summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/heimdal/HEIMDAL-LICENCE.txt49
-rw-r--r--source4/heimdal/kdc/default_config.c6
-rw-r--r--source4/heimdal/kdc/kerberos5.c2
-rw-r--r--source4/heimdal/kdc/krb5tgs.c28
-rw-r--r--source4/heimdal/kdc/pkinit.c16
-rw-r--r--source4/heimdal/kdc/windc.c19
-rw-r--r--source4/heimdal/lib/asn1/asn1-common.h16
-rw-r--r--source4/heimdal/lib/asn1/asn1_gen.c5
-rw-r--r--source4/heimdal/lib/asn1/asn1parse.c8
-rw-r--r--source4/heimdal/lib/asn1/asn1parse.y8
-rw-r--r--source4/heimdal/lib/asn1/cms.opt1
-rw-r--r--source4/heimdal/lib/asn1/der_cmp.c14
-rw-r--r--source4/heimdal/lib/asn1/der_copy.c14
-rw-r--r--source4/heimdal/lib/asn1/der_free.c6
-rw-r--r--source4/heimdal/lib/asn1/der_get.c19
-rw-r--r--source4/heimdal/lib/asn1/der_length.c4
-rw-r--r--source4/heimdal/lib/asn1/der_put.c4
-rw-r--r--source4/heimdal/lib/asn1/gen.c122
-rw-r--r--source4/heimdal/lib/asn1/gen_copy.c25
-rw-r--r--source4/heimdal/lib/asn1/gen_decode.c40
-rw-r--r--source4/heimdal/lib/asn1/gen_encode.c38
-rw-r--r--source4/heimdal/lib/asn1/gen_free.c12
-rw-r--r--source4/heimdal/lib/asn1/gen_glue.c2
-rw-r--r--source4/heimdal/lib/asn1/gen_length.c28
-rw-r--r--source4/heimdal/lib/asn1/gen_seq.c12
-rw-r--r--source4/heimdal/lib/asn1/gen_template.c88
-rw-r--r--source4/heimdal/lib/asn1/rfc2459.asn110
-rw-r--r--source4/heimdal/lib/com_err/com_err.c20
-rw-r--r--source4/heimdal/lib/com_err/com_err.h48
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi.h154
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h145
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h3
-rw-r--r--source4/heimdal/lib/gssapi/gssapi_mech.h80
-rw-r--r--source4/heimdal/lib/gssapi/krb5/8003.c5
-rw-r--r--source4/heimdal/lib/gssapi/krb5/accept_sec_context.c15
-rw-r--r--source4/heimdal/lib/gssapi/krb5/acquire_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/add_cred.c8
-rw-r--r--source4/heimdal/lib/gssapi/krb5/aeap.c6
-rw-r--r--source4/heimdal/lib/gssapi/krb5/canonicalize_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/compare_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/context_time.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/creds.c4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/delete_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/display_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/display_status.c26
-rw-r--r--source4/heimdal/lib/gssapi/krb5/duplicate_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/export_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/export_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/external.c181
-rw-r--r--source4/heimdal/lib/gssapi/krb5/get_mic.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/import_name.c4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/import_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/indicate_mechs.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c14
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/prf.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/process_context_token.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/release_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/release_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_cred_option.c11
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/store_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/unwrap.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/verify_mic.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/wrap.c5
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c3
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_add_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_aeap.c15
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_buffer_set.c6
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_compare_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_context_time.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_cred.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_display_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_display_status.c20
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c3
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c3
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_export_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_get_mic.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_import_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c8
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_krb5.c44
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_oid_equal.c18
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_process_context_token.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_buffer.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_oid.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_seal.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_sign.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_unseal.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_unwrap.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_verify.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_verify_mic.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_wrap.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c2
-rw-r--r--source4/heimdal/lib/gssapi/spnego/accept_sec_context.c12
-rw-r--r--source4/heimdal/lib/gssapi/spnego/compat.c11
-rw-r--r--source4/heimdal/lib/gssapi/spnego/context_stubs.c54
-rw-r--r--source4/heimdal/lib/gssapi/spnego/cred_stubs.c16
-rw-r--r--source4/heimdal/lib/gssapi/spnego/external.c4
-rw-r--r--source4/heimdal/lib/gssapi/spnego/init_sec_context.c3
-rw-r--r--source4/heimdal/lib/hcrypto/aes.c23
-rw-r--r--source4/heimdal/lib/hcrypto/aes.h4
-rw-r--r--source4/heimdal/lib/hcrypto/camellia.h2
-rw-r--r--source4/heimdal/lib/hcrypto/common.c69
-rw-r--r--source4/heimdal/lib/hcrypto/common.h45
-rw-r--r--source4/heimdal/lib/hcrypto/dh-imath.c9
-rw-r--r--source4/heimdal/lib/hcrypto/dh-ltm.c249
-rw-r--r--source4/heimdal/lib/hcrypto/dh.c63
-rw-r--r--source4/heimdal/lib/hcrypto/dh.h7
-rw-r--r--source4/heimdal/lib/hcrypto/engine.c104
-rw-r--r--source4/heimdal/lib/hcrypto/engine.h15
-rw-r--r--source4/heimdal/lib/hcrypto/evp-cc.c856
-rw-r--r--source4/heimdal/lib/hcrypto/evp-cc.h7
-rw-r--r--source4/heimdal/lib/hcrypto/evp-hcrypto.c93
-rw-r--r--source4/heimdal/lib/hcrypto/evp-hcrypto.h7
-rw-r--r--source4/heimdal/lib/hcrypto/evp.c74
-rw-r--r--source4/heimdal/lib/hcrypto/evp.h11
-rw-r--r--source4/heimdal/lib/hcrypto/hash.h3
-rw-r--r--source4/heimdal/lib/hcrypto/imath/imath.c2
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/LICENSE4
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn.ilg6
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn.ind82
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_error.c47
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_fast_mp_invmod.c148
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_fast_mp_montgomery_reduce.c172
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_mul_digs.c107
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_mul_high_digs.c98
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_sqr.c114
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_2expt.c48
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_abs.c43
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_add.c53
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_add_d.c112
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_addmod.c41
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_and.c57
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_clamp.c44
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_clear.c44
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_clear_multi.c34
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp.c43
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp_d.c44
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp_mag.c55
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_cnt_lsb.c53
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_copy.c68
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_count_bits.c45
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_div.c292
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_2.c68
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_2d.c97
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_3.c79
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_d.c115
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_is_modulus.c43
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_reduce.c94
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_setup.c32
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_exch.c34
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_expt_d.c57
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_exptmod.c112
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_exptmod_fast.c321
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_exteuclid.c82
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_find_prime.c26
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_fread.c67
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_fwrite.c52
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_gcd.c105
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_get_int.c45
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_grow.c57
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_init.c46
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_copy.c32
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_multi.c59
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_set.c32
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_set_int.c31
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_size.c48
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_invmod.c43
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_invmod_slow.c175
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_is_square.c109
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_isprime.c75
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_jacobi.c105
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_karatsuba_mul.c167
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_karatsuba_sqr.c121
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_lcm.c60
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_lshd.c67
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod.c48
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod_2d.c55
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod_d.c27
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_calc_normalization.c59
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_reduce.c118
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_setup.c59
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul.c66
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_2.c82
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_2d.c85
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_d.c79
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_mulmod.c40
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_n_root.c132
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_neg.c40
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_or.c50
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_fermat.c62
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_is_divisible.c50
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_is_prime.c83
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_miller_rabin.c103
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_next_prime.c170
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_rabin_miller_trials.c52
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_random_ex.c125
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_radix_size.c78
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_radix_smap.c24
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_rand.c55
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_radix.c85
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_signed_bin.c41
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_unsigned_bin.c55
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce.c100
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k.c61
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_l.c62
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_setup.c47
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_setup_l.c44
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_is_2k.c52
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_is_2k_l.c44
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_setup.c34
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_rshd.c72
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_set.c29
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_set_int.c48
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_shrink.c35
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_signed_bin_size.c27
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqr.c58
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqrmod.c41
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqrt.c81
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_sub.c59
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_sub_d.c93
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_submod.c42
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_signed_bin.c33
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_signed_bin_n.c31
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_unsigned_bin.c48
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_unsigned_bin_n.c31
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_toom_mul.c284
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_toom_sqr.c226
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_toradix.c75
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_toradix_n.c88
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_unsigned_bin_size.c28
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_xor.c51
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_zero.c36
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_mp_zero_multi.c35
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_prime_tab.c61
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_reverse.c39
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_add.c109
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_exptmod.c252
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_digs.c90
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_high_digs.c81
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_sqr.c84
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_sub.c89
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/bncore.c36
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/booker.pl265
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/callgraph.txt11913
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/libtommath.dsp572
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/mtest/logtab.h24
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/mtest/mpi-config.h90
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/mtest/mpi-types.h20
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/mtest/mpi.c3985
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/mtest/mpi.h231
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/mtest/mtest.c308
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pics/design_process.sxdbin0 -> 6950 bytes
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pics/design_process.tifbin0 -> 79042 bytes
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.sxdbin0 -> 6869 bytes
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.tifbin0 -> 87542 bytes
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pics/makefile35
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pics/primality.tifbin0 -> 85514 bytes
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pics/radix.sxdbin0 -> 6181 bytes
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.sxdbin0 -> 6787 bytes
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.tifbin0 -> 53880 bytes
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/pretty.build66
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/tombc/grammar.txt35
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/tommath.h592
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/tommath_class.h1000
-rw-r--r--source4/heimdal/lib/hcrypto/libtommath/tommath_superclass.h76
-rw-r--r--source4/heimdal/lib/hcrypto/md4.c6
-rw-r--r--source4/heimdal/lib/hcrypto/md5.c6
-rw-r--r--source4/heimdal/lib/hcrypto/rand-fortuna.c44
-rw-r--r--source4/heimdal/lib/hcrypto/rand-unix.c2
-rw-r--r--source4/heimdal/lib/hcrypto/rand.c24
-rw-r--r--source4/heimdal/lib/hcrypto/rand.h2
-rw-r--r--source4/heimdal/lib/hcrypto/randi.h2
-rw-r--r--source4/heimdal/lib/hcrypto/rijndael-alg-fst.c51
-rw-r--r--source4/heimdal/lib/hcrypto/rsa-imath.c9
-rw-r--r--source4/heimdal/lib/hcrypto/rsa-ltm.c630
-rw-r--r--source4/heimdal/lib/hcrypto/rsa.c221
-rw-r--r--source4/heimdal/lib/hcrypto/rsa.h6
-rw-r--r--source4/heimdal/lib/hcrypto/sha.c10
-rw-r--r--source4/heimdal/lib/hcrypto/sha256.c6
-rw-r--r--source4/heimdal/lib/hcrypto/ui.c2
-rw-r--r--source4/heimdal/lib/hcrypto/validate.c308
-rw-r--r--source4/heimdal/lib/hdb/ext.c5
-rw-r--r--source4/heimdal/lib/hdb/hdb_err.et1
-rw-r--r--source4/heimdal/lib/hdb/keytab.c14
-rw-r--r--source4/heimdal/lib/hdb/mkey.c23
-rw-r--r--source4/heimdal/lib/hdb/ndbm.c6
-rw-r--r--source4/heimdal/lib/hx509/ca.c103
-rw-r--r--source4/heimdal/lib/hx509/cert.c111
-rw-r--r--source4/heimdal/lib/hx509/char_map.h45
-rw-r--r--source4/heimdal/lib/hx509/cms.c53
-rw-r--r--source4/heimdal/lib/hx509/crypto.c219
-rw-r--r--source4/heimdal/lib/hx509/hx509.h7
-rw-r--r--source4/heimdal/lib/hx509/ks_p11.c3
-rw-r--r--source4/heimdal/lib/hx509/name.c79
-rw-r--r--source4/heimdal/lib/hx509/req.c6
-rw-r--r--source4/heimdal/lib/hx509/sel.c1
-rw-r--r--source4/heimdal/lib/krb5/acache.c79
-rw-r--r--source4/heimdal/lib/krb5/cache.c129
-rw-r--r--source4/heimdal/lib/krb5/ccache_plugin.h39
-rw-r--r--source4/heimdal/lib/krb5/config_file.c19
-rw-r--r--source4/heimdal/lib/krb5/context.c18
-rw-r--r--source4/heimdal/lib/krb5/crypto.c12
-rw-r--r--source4/heimdal/lib/krb5/data.c2
-rw-r--r--source4/heimdal/lib/krb5/error_string.c21
-rw-r--r--source4/heimdal/lib/krb5/expand_path.c500
-rw-r--r--source4/heimdal/lib/krb5/fcache.c119
-rw-r--r--source4/heimdal/lib/krb5/generate_seq_number.c2
-rw-r--r--source4/heimdal/lib/krb5/get_cred.c21
-rw-r--r--source4/heimdal/lib/krb5/get_default_principal.c2
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c32
-rw-r--r--source4/heimdal/lib/krb5/kcm.c88
-rw-r--r--source4/heimdal/lib/krb5/keytab.c7
-rw-r--r--source4/heimdal/lib/krb5/keytab_any.c16
-rw-r--r--source4/heimdal/lib/krb5/keytab_file.c22
-rw-r--r--source4/heimdal/lib/krb5/keytab_keyfile.c14
-rw-r--r--source4/heimdal/lib/krb5/keytab_memory.c16
-rw-r--r--source4/heimdal/lib/krb5/krb5.h157
-rw-r--r--source4/heimdal/lib/krb5/krb5_locl.h1
-rw-r--r--source4/heimdal/lib/krb5/krbhst.c10
-rw-r--r--source4/heimdal/lib/krb5/log.c12
-rw-r--r--source4/heimdal/lib/krb5/mcache.c49
-rw-r--r--source4/heimdal/lib/krb5/mit_glue.c40
-rw-r--r--source4/heimdal/lib/krb5/pcache.c66
-rw-r--r--source4/heimdal/lib/krb5/pkinit.c15
-rw-r--r--source4/heimdal/lib/krb5/plugin.c20
-rw-r--r--source4/heimdal/lib/krb5/prompter_posix.c2
-rw-r--r--source4/heimdal/lib/krb5/rd_req.c2
-rw-r--r--source4/heimdal/lib/krb5/replay.c6
-rw-r--r--source4/heimdal/lib/krb5/send_to_kdc.c14
-rw-r--r--source4/heimdal/lib/krb5/ticket.c2
-rw-r--r--source4/heimdal/lib/krb5/v4_glue.c2
-rw-r--r--source4/heimdal/lib/krb5/warn.c5
-rw-r--r--source4/heimdal/lib/ntlm/ntlm.c6
-rw-r--r--source4/heimdal/lib/roken/base64.c2
-rw-r--r--source4/heimdal/lib/roken/getarg.c5
-rw-r--r--source4/heimdal/lib/roken/getarg.h2
-rw-r--r--source4/heimdal/lib/roken/inet_ntop.c21
-rw-r--r--source4/heimdal/lib/roken/inet_pton.c13
-rw-r--r--source4/heimdal/lib/roken/net_read.c20
-rw-r--r--source4/heimdal/lib/roken/net_write.c19
-rw-r--r--source4/heimdal/lib/roken/resolve.c218
-rw-r--r--source4/heimdal/lib/roken/resolve.h4
-rw-r--r--source4/heimdal/lib/roken/roken.h.in89
-rw-r--r--source4/heimdal/lib/roken/roken_gethostby.c9
-rw-r--r--source4/heimdal/lib/roken/socket.c13
-rw-r--r--source4/heimdal/lib/roken/strerror_r.c2
-rw-r--r--source4/heimdal/lib/wind/errorlist.c2
-rw-r--r--source4/heimdal/lib/wind/normalize.c31
-rw-r--r--source4/heimdal/lib/wind/stringprep.py4
-rw-r--r--source4/heimdal/lib/wind/wind.h1
382 files changed, 34153 insertions, 1687 deletions
diff --git a/source4/heimdal/HEIMDAL-LICENCE.txt b/source4/heimdal/HEIMDAL-LICENCE.txt
index 90ff52309f..8ff9419512 100644
--- a/source4/heimdal/HEIMDAL-LICENCE.txt
+++ b/source4/heimdal/HEIMDAL-LICENCE.txt
@@ -12,34 +12,33 @@ cooperation in the use of the heimdal code in Samba.
/*
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan and others.
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * 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.
+ * 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.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
-
diff --git a/source4/heimdal/kdc/default_config.c b/source4/heimdal/kdc/default_config.c
index f5df4e0298..118bdf97aa 100644
--- a/source4/heimdal/kdc/default_config.c
+++ b/source4/heimdal/kdc/default_config.c
@@ -264,7 +264,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
if (c->pkinit_kdc_identity == NULL) {
if (c->pkinit_kdc_friendly_name == NULL)
- c->pkinit_kdc_friendly_name =
+ c->pkinit_kdc_friendly_name =
strdup("O=System Identity,CN=com.apple.kerberos.kdc");
c->pkinit_kdc_identity = strdup("KEYCHAIN:");
}
@@ -276,7 +276,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
if (c->enable_pkinit) {
if (c->pkinit_kdc_identity == NULL)
krb5_errx(context, 1, "pkinit enabled but no identity");
-
+
if (c->pkinit_kdc_anchors == NULL)
krb5_errx(context, 1, "pkinit enabled but no X509 anchors");
@@ -287,7 +287,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
c->pkinit_kdc_revoke);
}
-
+
*config = c;
return 0;
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index 05df86e143..9fb0998a2a 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -910,7 +910,7 @@ _kdc_as_rep(krb5_context context,
const char *e_text = NULL;
krb5_crypto crypto;
Key *ckey, *skey;
- EncryptionKey *reply_key, session_key;
+ EncryptionKey *reply_key = NULL, session_key;
int flags = 0;
#ifdef PKINIT
pk_client_params *pkp = NULL;
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index 06a535d4d4..23f9674bef 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -314,6 +314,7 @@ check_PAC(krb5_context context,
for (j = 0; j < child.len; j++) {
if (child.val[j].ad_type == KRB5_AUTHDATA_WIN2K_PAC) {
+ int signed_pac = 0;
krb5_pac pac;
/* Found PAC */
@@ -334,19 +335,26 @@ check_PAC(krb5_context context,
}
ret = _kdc_pac_verify(context, client_principal,
- client, server, krbtgt, &pac);
+ client, server, krbtgt, &pac, &signed_pac);
if (ret) {
krb5_pac_free(context, pac);
return ret;
}
- *signedpath = 1;
-
- ret = _krb5_pac_sign(context, pac, tkt->authtime,
- client_principal,
- server_key, krbtgt_sign_key, rspac);
+ /*
+ * Only re-sign PAC if we could verify it with the PAC
+ * function. The no-verify case happens when we get in
+ * a PAC from cross realm from a Windows domain and
+ * that there is no PAC verification function.
+ */
+ if (signed_pac) {
+ *signedpath = 1;
+ ret = _krb5_pac_sign(context, pac, tkt->authtime,
+ client_principal,
+ server_key, krbtgt_key, rspac);
+ }
krb5_pac_free(context, pac);
-
+
return ret;
}
}
@@ -449,7 +457,7 @@ check_tgs_flags(krb5_context context,
}
if(f.renewable){
- if(!tgt->flags.renewable){
+ if(!tgt->flags.renewable || tgt->renew_till == NULL){
kdc_log(context, config, 0,
"Bad request for renewable ticket");
return KRB5KDC_ERR_BADOPTION;
@@ -802,7 +810,9 @@ tgs_make_reply(krb5_context context,
et.endtime = *et.starttime + life;
}
if(f.renewable_ok && tgt->flags.renewable &&
- et.renew_till == NULL && et.endtime < *b->till){
+ et.renew_till == NULL && et.endtime < *b->till &&
+ tgt->renew_till != NULL)
+ {
et.flags.renewable = 1;
ALLOC(et.renew_till);
*et.renew_till = *b->till;
diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c
index 4405bf4f19..9c0be23b14 100644
--- a/source4/heimdal/kdc/pkinit.c
+++ b/source4/heimdal/kdc/pkinit.c
@@ -227,10 +227,7 @@ generate_dh_keyblock(krb5_context context,
goto out;
}
- dh_gen_keylen = DH_size(client_params->u.dh.key);
- size = BN_num_bytes(client_params->u.dh.key->p);
- if (size < dh_gen_keylen)
- size = dh_gen_keylen;
+ size = DH_size(client_params->u.dh.key);
dh_gen_key = malloc(size);
if (dh_gen_key == NULL) {
@@ -238,17 +235,20 @@ generate_dh_keyblock(krb5_context context,
krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
- memset(dh_gen_key, 0, size - dh_gen_keylen);
- dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
- client_params->u.dh.public_key,
- client_params->u.dh.key);
+ dh_gen_keylen = DH_compute_key(dh_gen_key,client_params->u.dh.public_key, client_params->u.dh.key);
if (dh_gen_keylen == -1) {
ret = KRB5KRB_ERR_GENERIC;
krb5_set_error_message(context, ret,
"Can't compute Diffie-Hellman key");
goto out;
}
+ if (dh_gen_keylen < size) {
+ size -= dh_gen_keylen;
+ memmove(dh_gen_key + size, dh_gen_key, dh_gen_keylen);
+ memset(dh_gen_key, 0, size);
+ }
+
ret = 0;
#ifdef HAVE_OPENSSL
} else if (client_params->keyex == USE_ECDH) {
diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c
index a8f1eb15d1..6efbeee9dd 100644
--- a/source4/heimdal/kdc/windc.c
+++ b/source4/heimdal/kdc/windc.c
@@ -87,14 +87,19 @@ _kdc_pac_verify(krb5_context context,
hdb_entry_ex *client,
hdb_entry_ex *server,
hdb_entry_ex *krbtgt,
- krb5_pac *pac)
+ krb5_pac *pac,
+ int *verified)
{
- if (windcft == NULL) {
- krb5_set_error_message(context, EINVAL, "Can't verify PAC, no function");
- return EINVAL;
- }
- return (windcft->pac_verify)(windcctx, context,
- client_principal, client, server, krbtgt, pac);
+ krb5_error_code ret;
+
+ if (windcft == NULL)
+ return 0;
+
+ ret = windcft->pac_verify(windcctx, context,
+ client_principal, client, server, krbtgt, pac);
+ if (ret == 0)
+ *verified = 1;
+ return ret;
}
krb5_error_code
diff --git a/source4/heimdal/lib/asn1/asn1-common.h b/source4/heimdal/lib/asn1/asn1-common.h
index 8ab97761db..9c8793e0cc 100644
--- a/source4/heimdal/lib/asn1/asn1-common.h
+++ b/source4/heimdal/lib/asn1/asn1-common.h
@@ -20,8 +20,8 @@ typedef struct heim_octet_string {
typedef char *heim_general_string;
typedef char *heim_utf8_string;
-typedef char *heim_printable_string;
-typedef char *heim_ia5_string;
+typedef struct heim_octet_string heim_printable_string;
+typedef struct heim_octet_string heim_ia5_string;
typedef struct heim_bmp_string {
size_t length;
@@ -64,4 +64,16 @@ typedef struct heim_octet_string heim_any_set;
} \
} while (0)
+#ifdef _WIN32
+#ifndef ASN1_LIB
+#define ASN1EXP __declspec(dllimport)
+#else
+#define ASN1EXP
+#endif
+#define ASN1CALL __stdcall
+#else
+#define ASN1EXP
+#define ASN1CALL
+#endif
+
#endif
diff --git a/source4/heimdal/lib/asn1/asn1_gen.c b/source4/heimdal/lib/asn1/asn1_gen.c
index 925cc72cb4..01dc680516 100644
--- a/source4/heimdal/lib/asn1/asn1_gen.c
+++ b/source4/heimdal/lib/asn1/asn1_gen.c
@@ -46,7 +46,7 @@ static int
doit(const char *fn)
{
char buf[2048];
- char *fnout;
+ char *fnout = NULL;
const char *bname;
unsigned long line = 0;
FILE *f, *fout;
@@ -62,8 +62,7 @@ doit(const char *fn)
else
bname = fn;
- asprintf(&fnout, "%s.out", bname);
- if (fnout == NULL)
+ if (asprintf(&fnout, "%s.out", bname) < 0 || fnout == NULL)
errx(1, "malloc");
fout = fopen(fnout, "w");
diff --git a/source4/heimdal/lib/asn1/asn1parse.c b/source4/heimdal/lib/asn1/asn1parse.c
index 545e0f6922..7fa937a49d 100644
--- a/source4/heimdal/lib/asn1/asn1parse.c
+++ b/source4/heimdal/lib/asn1/asn1parse.c
@@ -3015,7 +3015,8 @@ static void fix_labels1(struct memhead *members, const char *prefix)
if(members == NULL)
return;
ASN1_TAILQ_FOREACH(m, members, members) {
- asprintf(&m->label, "%s_%s", prefix, m->gen_name);
+ if (asprintf(&m->label, "%s_%s", prefix, m->gen_name) < 0)
+ errx(1, "malloc");
if (m->label == NULL)
errx(1, "malloc");
if(m->type != NULL)
@@ -3032,9 +3033,8 @@ static void fix_labels2(Type *t, const char *prefix)
static void
fix_labels(Symbol *s)
{
- char *p;
- asprintf(&p, "choice_%s", s->gen_name);
- if (p == NULL)
+ char *p = NULL;
+ if (asprintf(&p, "choice_%s", s->gen_name) < 0 || p == NULL)
errx(1, "malloc");
fix_labels2(s->type, p);
free(p);
diff --git a/source4/heimdal/lib/asn1/asn1parse.y b/source4/heimdal/lib/asn1/asn1parse.y
index 13b86b17c1..611c5b521a 100644
--- a/source4/heimdal/lib/asn1/asn1parse.y
+++ b/source4/heimdal/lib/asn1/asn1parse.y
@@ -1007,7 +1007,8 @@ static void fix_labels1(struct memhead *members, const char *prefix)
if(members == NULL)
return;
ASN1_TAILQ_FOREACH(m, members, members) {
- asprintf(&m->label, "%s_%s", prefix, m->gen_name);
+ if (asprintf(&m->label, "%s_%s", prefix, m->gen_name) < 0)
+ errx(1, "malloc");
if (m->label == NULL)
errx(1, "malloc");
if(m->type != NULL)
@@ -1024,9 +1025,8 @@ static void fix_labels2(Type *t, const char *prefix)
static void
fix_labels(Symbol *s)
{
- char *p;
- asprintf(&p, "choice_%s", s->gen_name);
- if (p == NULL)
+ char *p = NULL;
+ if (asprintf(&p, "choice_%s", s->gen_name) < 0 || p == NULL)
errx(1, "malloc");
fix_labels2(s->type, p);
free(p);
diff --git a/source4/heimdal/lib/asn1/cms.opt b/source4/heimdal/lib/asn1/cms.opt
index bf7d396529..49333e53a7 100644
--- a/source4/heimdal/lib/asn1/cms.opt
+++ b/source4/heimdal/lib/asn1/cms.opt
@@ -1 +1,2 @@
--decode-dce-ber
+--sequence=DigestAlgorithmIdentifiers
diff --git a/source4/heimdal/lib/asn1/der_cmp.c b/source4/heimdal/lib/asn1/der_cmp.c
index 7329c5867f..84aee4cce0 100644
--- a/source4/heimdal/lib/asn1/der_cmp.c
+++ b/source4/heimdal/lib/asn1/der_cmp.c
@@ -53,6 +53,20 @@ der_heim_octet_string_cmp(const heim_octet_string *p,
}
int
+der_printable_string_cmp(const heim_printable_string *p,
+ const heim_printable_string *q)
+{
+ return der_heim_octet_string_cmp(p, q);
+}
+
+int
+der_ia5_string_cmp(const heim_ia5_string *p,
+ const heim_ia5_string *q)
+{
+ return der_heim_octet_string_cmp(p, q);
+}
+
+int
der_heim_bit_string_cmp(const heim_bit_string *p,
const heim_bit_string *q)
{
diff --git a/source4/heimdal/lib/asn1/der_copy.c b/source4/heimdal/lib/asn1/der_copy.c
index a80c851f96..3a0a8c5ffa 100644
--- a/source4/heimdal/lib/asn1/der_copy.c
+++ b/source4/heimdal/lib/asn1/der_copy.c
@@ -85,14 +85,20 @@ int
der_copy_printable_string (const heim_printable_string *from,
heim_printable_string *to)
{
- return der_copy_general_string(from, to);
+ to->length = from->length;
+ to->data = malloc(to->length + 1);
+ if(to->data == NULL)
+ return ENOMEM;
+ memcpy(to->data, from->data, to->length);
+ ((char *)to->data)[to->length] = '\0';
+ return 0;
}
int
-der_copy_ia5_string (const heim_printable_string *from,
- heim_printable_string *to)
+der_copy_ia5_string (const heim_ia5_string *from,
+ heim_ia5_string *to)
{
- return der_copy_general_string(from, to);
+ return der_copy_printable_string(from, to);
}
int
diff --git a/source4/heimdal/lib/asn1/der_free.c b/source4/heimdal/lib/asn1/der_free.c
index a16ddaed1c..4bae5fc233 100644
--- a/source4/heimdal/lib/asn1/der_free.c
+++ b/source4/heimdal/lib/asn1/der_free.c
@@ -79,15 +79,13 @@ der_free_utf8string (heim_utf8_string *str)
void
der_free_printable_string (heim_printable_string *str)
{
- free(*str);
- *str = NULL;
+ der_free_octet_string(str);
}
void
der_free_ia5_string (heim_ia5_string *str)
{
- free(*str);
- *str = NULL;
+ der_free_octet_string(str);
}
void
diff --git a/source4/heimdal/lib/asn1/der_get.c b/source4/heimdal/lib/asn1/der_get.c
index aee565040f..3ea0d5ea18 100644
--- a/source4/heimdal/lib/asn1/der_get.c
+++ b/source4/heimdal/lib/asn1/der_get.c
@@ -167,17 +167,24 @@ der_get_utf8string (const unsigned char *p, size_t len,
}
int
-der_get_printable_string (const unsigned char *p, size_t len,
- heim_printable_string *str, size_t *size)
+der_get_printable_string(const unsigned char *p, size_t len,
+ heim_printable_string *str, size_t *size)
{
- return der_get_general_string(p, len, str, size);
+ str->length = len;
+ str->data = malloc(len + 1);
+ if (str->data == NULL)
+ return ENOMEM;
+ memcpy(str->data, p, len);
+ ((char *)str->data)[len] = '\0';
+ if(size) *size = len;
+ return 0;
}
int
-der_get_ia5_string (const unsigned char *p, size_t len,
- heim_ia5_string *str, size_t *size)
+der_get_ia5_string(const unsigned char *p, size_t len,
+ heim_ia5_string *str, size_t *size)
{
- return der_get_general_string(p, len, str, size);
+ return der_get_printable_string(p, len, str, size);
}
int
diff --git a/source4/heimdal/lib/asn1/der_length.c b/source4/heimdal/lib/asn1/der_length.c
index 688e6ba817..7a41de9d22 100644
--- a/source4/heimdal/lib/asn1/der_length.c
+++ b/source4/heimdal/lib/asn1/der_length.c
@@ -161,13 +161,13 @@ der_length_utf8string (const heim_utf8_string *data)
size_t
der_length_printable_string (const heim_printable_string *data)
{
- return strlen(*data);
+ return data->length;
}
size_t
der_length_ia5_string (const heim_ia5_string *data)
{
- return strlen(*data);
+ return data->length;
}
size_t
diff --git a/source4/heimdal/lib/asn1/der_put.c b/source4/heimdal/lib/asn1/der_put.c
index 10fc002334..c8192f25fe 100644
--- a/source4/heimdal/lib/asn1/der_put.c
+++ b/source4/heimdal/lib/asn1/der_put.c
@@ -181,14 +181,14 @@ int
der_put_printable_string (unsigned char *p, size_t len,
const heim_printable_string *str, size_t *size)
{
- return der_put_general_string(p, len, str, size);
+ return der_put_octet_string(p, len, str, size);
}
int
der_put_ia5_string (unsigned char *p, size_t len,
const heim_ia5_string *str, size_t *size)
{
- return der_put_general_string(p, len, str, size);
+ return der_put_octet_string(p, len, str, size);
}
int
diff --git a/source4/heimdal/lib/asn1/gen.c b/source4/heimdal/lib/asn1/gen.c
index 8c13434203..d59f3bfa47 100644
--- a/source4/heimdal/lib/asn1/gen.c
+++ b/source4/heimdal/lib/asn1/gen.c
@@ -116,7 +116,7 @@ get_filename (void)
void
init_generate (const char *filename, const char *base)
{
- char *fn;
+ char *fn = NULL;
orig_filename = filename;
if (base != NULL) {
@@ -126,34 +126,30 @@ init_generate (const char *filename, const char *base)
}
/* public header file */
- asprintf(&header, "%s.h", headerbase);
- if (header == NULL)
+ if (asprintf(&header, "%s.h", headerbase) < 0 || header == NULL)
errx(1, "malloc");
- asprintf(&fn, "%s.hx", headerbase);
- if (fn == NULL)
+ if (asprintf(&fn, "%s.hx", headerbase) < 0 || fn == NULL)
errx(1, "malloc");
headerfile = fopen (fn, "w");
if (headerfile == NULL)
err (1, "open %s", fn);
free(fn);
+ fn = NULL;
/* private header file */
- asprintf(&privheader, "%s-priv.h", headerbase);
- if (privheader == NULL)
+ if (asprintf(&privheader, "%s-priv.h", headerbase) < 0 || privheader == NULL)
errx(1, "malloc");
- asprintf(&fn, "%s-priv.hx", headerbase);
- if (fn == NULL)
+ if (asprintf(&fn, "%s-priv.hx", headerbase) < 0 || fn == NULL)
errx(1, "malloc");
privheaderfile = fopen (fn, "w");
if (privheaderfile == NULL)
err (1, "open %s", fn);
free(fn);
+ fn = NULL;
/* template file */
- asprintf(&template, "%s-template.c", headerbase);
- if (template == NULL)
+ if (asprintf(&template, "%s-template.c", headerbase) < 0 || template == NULL)
errx(1, "malloc");
-
fprintf (headerfile,
"/* Generated from %s */\n"
"/* Do not edit */\n\n",
@@ -185,10 +181,10 @@ init_generate (const char *filename, const char *base)
"typedef char *heim_utf8_string;\n\n"
);
fprintf (headerfile,
- "typedef char *heim_printable_string;\n\n"
+ "typedef struct heim_octet_string heim_printable_string;\n\n"
);
fprintf (headerfile,
- "typedef char *heim_ia5_string;\n\n"
+ "typedef struct heim_octet_string heim_ia5_string;\n\n"
);
fprintf (headerfile,
"typedef struct heim_bmp_string {\n"
@@ -232,10 +228,21 @@ init_generate (const char *filename, const char *base)
" } \\\n"
" } while (0)\n\n",
headerfile);
+ fputs("#ifdef _WIN32\n"
+ "#ifndef ASN1_LIB\n"
+ "#define ASN1EXP __declspec(dllimport)\n"
+ "#else\n"
+ "#define ASN1EXP\n"
+ "#endif\n"
+ "#define ASN1CALL __stdcall\n"
+ "#else\n"
+ "#define ASN1EXP\n"
+ "#define ASN1CALL\n"
+ "#endif\n",
+ headerfile);
fprintf (headerfile, "struct units;\n\n");
fprintf (headerfile, "#endif\n\n");
- asprintf(&fn, "%s_files", base);
- if (fn == NULL)
+ if (asprintf(&fn, "%s_files", base) < 0 || fn == NULL)
errx(1, "malloc");
logfile = fopen(fn, "w");
if (logfile == NULL)
@@ -333,22 +340,23 @@ gen_compare_defval(const char *var, struct value *val)
void
generate_header_of_codefile(const char *name)
{
- char *filename;
+ char *filename = NULL;
if (codefile != NULL)
abort();
- asprintf (&filename, "%s_%s.x", STEM, name);
- if (filename == NULL)
+ if (asprintf (&filename, "%s_%s.x", STEM, name) < 0 || filename == NULL)
errx(1, "malloc");
codefile = fopen (filename, "w");
if (codefile == NULL)
err (1, "fopen %s", filename);
fprintf(logfile, "%s ", filename);
free(filename);
+ filename = NULL;
fprintf (codefile,
"/* Generated from %s */\n"
"/* Do not edit */\n\n"
+ "#define ASN1_LIB\n\n"
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"#include <time.h>\n"
@@ -399,6 +407,7 @@ generate_constant (const Symbol *s)
case objectidentifiervalue: {
struct objid *o, **list;
unsigned int i, len;
+ char *gen_upper;
if (!one_code_file)
generate_header_of_codefile(s->gen_name);
@@ -424,12 +433,6 @@ generate_constant (const Symbol *s)
o->label ? o->label : "label-less", o->value);
}
- fprintf (headerfile, "} */\n");
- fprintf (headerfile,
- "extern const heim_oid asn1_oid_%s;\n\n",
- s->gen_name);
-
-
fprintf (codefile, "static unsigned oid_%s_variable_num[%d] = {",
s->gen_name, len);
for (i = len ; i > 0; i--) {
@@ -443,6 +446,23 @@ generate_constant (const Symbol *s)
free(list);
+ /* header file */
+
+ gen_upper = strdup(s->gen_name);
+ len = strlen(gen_upper);
+ for (i = 0; i < len; i++)
+ gen_upper[i] = toupper((int)s->gen_name[i]);
+
+ fprintf (headerfile, "} */\n");
+ fprintf (headerfile,
+ "extern ASN1EXP const heim_oid asn1_oid_%s;\n"
+ "#define ASN1_OID_%s (&asn1_oid_%s)\n\n",
+ s->gen_name,
+ gen_upper,
+ s->gen_name);
+
+ free(gen_upper);
+
if (!one_code_file)
close_codefile();
@@ -673,7 +693,8 @@ getnewbasename(char **newbasename, int typedefp, const char *basename, const cha
else {
if (name[0] == '*')
name++;
- asprintf(newbasename, "%s_%s", basename, name);
+ if (asprintf(newbasename, "%s_%s", basename, name) < 0)
+ errx(1, "malloc");
}
if (*newbasename == NULL)
err(1, "malloc");
@@ -739,27 +760,30 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
fprintf (headerfile, "struct %s {\n", newbasename);
ASN1_TAILQ_FOREACH(m, t->members, members) {
- char *n;
+ char *n = NULL;
/* pad unused */
while (pos < m->val) {
- asprintf (&n, "_unused%d:1", pos);
+ if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
+ errx(1, "malloc");
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
free(n);
pos++;
}
- asprintf (&n, "%s:1", m->gen_name);
- if (n == NULL)
+ n = NULL;
+ if (asprintf (&n, "%s:1", m->gen_name) < 0 || n == NULL)
errx(1, "malloc");
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
free (n);
+ n = NULL;
pos++;
}
/* pad to 32 elements */
while (pos < 32) {
- char *n;
- asprintf (&n, "_unused%d:1", pos);
+ char *n = NULL;
+ if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
+ errx(1, "malloc");
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
free(n);
pos++;
@@ -803,10 +827,9 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
if (m->ellipsis) {
;
} else if (m->optional) {
- char *n;
+ char *n = NULL;
- asprintf (&n, "*%s", m->gen_name);
- if (n == NULL)
+ if (asprintf (&n, "*%s", m->gen_name) < 0 || n == NULL)
errx(1, "malloc");
define_type (level + 1, n, newbasename, m->type, FALSE, FALSE);
free (n);
@@ -891,10 +914,9 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ
space(level + 2);
fprintf(headerfile, "heim_octet_string asn1_ellipsis;\n");
} else if (m->optional) {
- char *n;
+ char *n = NULL;
- asprintf (&n, "*%s", m->gen_name);
- if (n == NULL)
+ if (asprintf (&n, "*%s", m->gen_name) < 0 || n == NULL)
errx(1, "malloc");
define_type (level + 2, n, newbasename, m->type, FALSE, FALSE);
free (n);
@@ -970,6 +992,7 @@ void
generate_type (const Symbol *s)
{
FILE *h;
+ const char * exp;
if (!one_code_file)
generate_header_of_codefile(s->gen_name);
@@ -991,30 +1014,37 @@ generate_type (const Symbol *s)
/* generate prototypes */
- if (is_export(s->name))
+ if (is_export(s->name)) {
h = headerfile;
- else
+ exp = "ASN1EXP ";
+ } else {
h = privheaderfile;
+ exp = "";
+ }
fprintf (h,
- "int "
+ "%sint ASN1CALL "
"decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
+ exp,
s->gen_name, s->gen_name);
fprintf (h,
- "int "
+ "%sint ASN1CALL "
"encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
+ exp,
s->gen_name, s->gen_name);
fprintf (h,
- "size_t length_%s(const %s *);\n",
+ "%ssize_t ASN1CALL length_%s(const %s *);\n",
+ exp,
s->gen_name, s->gen_name);
fprintf (h,
- "int copy_%s (const %s *, %s *);\n",
+ "%sint ASN1CALL copy_%s (const %s *, %s *);\n",
+ exp,
s->gen_name, s->gen_name, s->gen_name);
fprintf (h,
- "void free_%s (%s *);\n",
+ "%svoid ASN1CALL free_%s (%s *);\n",
+ exp,
s->gen_name, s->gen_name);
-
fprintf(h, "\n\n");
if (!one_code_file) {
diff --git a/source4/heimdal/lib/asn1/gen_copy.c b/source4/heimdal/lib/asn1/gen_copy.c
index 5e228d0e64..36f68ee5d9 100644
--- a/source4/heimdal/lib/asn1/gen_copy.c
+++ b/source4/heimdal/lib/asn1/gen_copy.c
@@ -110,14 +110,16 @@ copy_type (const char *from, const char *to, const Type *t, int preserve)
if(t->type == TChoice)
fprintf(codefile, "case %s:\n", m->label);
- asprintf (&fs, "%s(%s)->%s%s",
- m->optional ? "" : "&", from,
- t->type == TChoice ? "u." : "", m->gen_name);
+ if (asprintf (&fs, "%s(%s)->%s%s",
+ m->optional ? "" : "&", from,
+ t->type == TChoice ? "u." : "", m->gen_name) < 0)
+ errx(1, "malloc");
if (fs == NULL)
errx(1, "malloc");
- asprintf (&ts, "%s(%s)->%s%s",
- m->optional ? "" : "&", to,
- t->type == TChoice ? "u." : "", m->gen_name);
+ if (asprintf (&ts, "%s(%s)->%s%s",
+ m->optional ? "" : "&", to,
+ t->type == TChoice ? "u." : "", m->gen_name) < 0)
+ errx(1, "malloc");
if (ts == NULL)
errx(1, "malloc");
if(m->optional){
@@ -155,8 +157,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve)
}
case TSetOf:
case TSequenceOf: {
- char *f;
- char *T;
+ char *f = NULL, *T = NULL;
fprintf (codefile, "if(((%s)->val = "
"malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",
@@ -166,10 +167,12 @@ copy_type (const char *from, const char *to, const Type *t, int preserve)
fprintf(codefile,
"for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
to, to, from, to);
- asprintf(&f, "&(%s)->val[(%s)->len]", from, to);
+ if (asprintf(&f, "&(%s)->val[(%s)->len]", from, to) < 0)
+ errx(1, "malloc");
if (f == NULL)
errx(1, "malloc");
- asprintf(&T, "&(%s)->val[(%s)->len]", to, to);
+ if (asprintf(&T, "&(%s)->val[(%s)->len]", to, to) < 0)
+ errx(1, "malloc");
if (T == NULL)
errx(1, "malloc");
copy_type(f, T, t->subtype, FALSE);
@@ -228,7 +231,7 @@ generate_type_copy (const Symbol *s)
used_fail = 0;
- fprintf (codefile, "int\n"
+ fprintf (codefile, "int ASN1CALL\n"
"copy_%s(const %s *from, %s *to)\n"
"{\n"
"memset(to, 0, sizeof(*to));\n",
diff --git a/source4/heimdal/lib/asn1/gen_decode.c b/source4/heimdal/lib/asn1/gen_decode.c
index 043cfac2db..ad76c07251 100644
--- a/source4/heimdal/lib/asn1/gen_decode.c
+++ b/source4/heimdal/lib/asn1/gen_decode.c
@@ -320,14 +320,13 @@ decode_type (const char *name, const Type *t, int optional,
break;
ASN1_TAILQ_FOREACH(m, t->members, members) {
- char *s;
+ char *s = NULL;
if (m->ellipsis)
continue;
- asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&",
- name, m->gen_name);
- if (s == NULL)
+ if (asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&",
+ name, m->gen_name) < 0 || s == NULL)
errx(1, "malloc");
decode_type (s, m->type, m->optional, forwstr, m->gen_name, NULL);
free (s);
@@ -363,8 +362,7 @@ decode_type (const char *name, const Type *t, int optional,
is_primitive_type(m->type->subtype->type) ? "PRIM" : "CONS",
valuename(m->type->tag.tagclass, m->type->tag.tagvalue));
- asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
- if (s == NULL)
+ if (asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name) < 0 || s == NULL)
errx(1, "malloc");
if(m->optional)
fprintf(codefile,
@@ -388,8 +386,7 @@ decode_type (const char *name, const Type *t, int optional,
ASN1_TAILQ_FOREACH(m, t->members, members) {
char *s;
- asprintf (&s, "%s->%s", name, m->gen_name);
- if (s == NULL)
+ if (asprintf (&s, "%s->%s", name, m->gen_name) < 0 || s == NULL)
errx(1, "malloc");
fprintf(codefile, "if((members & (1 << %d)) == 0)\n", memno);
if(m->optional)
@@ -406,8 +403,8 @@ decode_type (const char *name, const Type *t, int optional,
}
case TSetOf:
case TSequenceOf: {
- char *n;
- char *sname;
+ char *n = NULL;
+ char *sname = NULL;
fprintf (codefile,
"{\n"
@@ -441,11 +438,9 @@ decode_type (const char *name, const Type *t, int optional,
tmpstr, forwstr,
name, tmpstr);
- asprintf (&n, "&(%s)->val[(%s)->len]", name, name);
- if (n == NULL)
+ if (asprintf (&n, "&(%s)->val[(%s)->len]", name, name) < 0 || n == NULL)
errx(1, "malloc");
- asprintf (&sname, "%s_s_of", tmpstr);
- if (sname == NULL)
+ if (asprintf (&sname, "%s_s_of", tmpstr) < 0 || sname == NULL)
errx(1, "malloc");
decode_type (n, t->subtype, 0, forwstr, sname, NULL);
fprintf (codefile,
@@ -472,10 +467,11 @@ decode_type (const char *name, const Type *t, int optional,
decode_primitive ("general_string", name, forwstr);
break;
case TTag:{
- char *tname, *typestring;
+ char *tname = NULL, *typestring = NULL;
char *ide = NULL;
- asprintf(&typestring, "%s_type", tmpstr);
+ if (asprintf(&typestring, "%s_type", tmpstr) < 0 || typestring == NULL)
+ errx(1, "malloc");
fprintf(codefile,
"{\n"
@@ -528,8 +524,7 @@ decode_type (const char *name, const Type *t, int optional,
fprintf(codefile,
"if (%s_datalen > len) { e = ASN1_OVERRUN; %s; }\n"
"len = %s_datalen;\n", tmpstr, forwstr, tmpstr);
- asprintf (&tname, "%s_Tag", tmpstr);
- if (tname == NULL)
+ if (asprintf (&tname, "%s_Tag", tmpstr) < 0 || tname == NULL)
errx(1, "malloc");
decode_type (name, t->subtype, 0, forwstr, tname, ide);
if(support_ber)
@@ -568,7 +563,7 @@ decode_type (const char *name, const Type *t, int optional,
ASN1_TAILQ_FOREACH(m, t->members, members) {
const Type *tt = m->type;
- char *s;
+ char *s = NULL;
Der_class cl;
Der_type ty;
unsigned tag;
@@ -586,9 +581,8 @@ decode_type (const char *name, const Type *t, int optional,
classname(cl),
ty ? "CONS" : "PRIM",
valuename(cl, tag));
- asprintf (&s, "%s(%s)->u.%s", m->optional ? "" : "&",
- name, m->gen_name);
- if (s == NULL)
+ if (asprintf (&s, "%s(%s)->u.%s", m->optional ? "" : "&",
+ name, m->gen_name) < 0 || s == NULL)
errx(1, "malloc");
decode_type (s, m->type, m->optional, forwstr, m->gen_name, NULL);
fprintf(codefile,
@@ -667,7 +661,7 @@ generate_type_decode (const Symbol *s)
{
int preserve = preserve_type(s->name) ? TRUE : FALSE;
- fprintf (codefile, "int\n"
+ fprintf (codefile, "int ASN1CALL\n"
"decode_%s(const unsigned char *p,"
" size_t len, %s *data, size_t *size)\n"
"{\n",
diff --git a/source4/heimdal/lib/asn1/gen_encode.c b/source4/heimdal/lib/asn1/gen_encode.c
index e9b4e7cd12..43f29c1fe1 100644
--- a/source4/heimdal/lib/asn1/gen_encode.c
+++ b/source4/heimdal/lib/asn1/gen_encode.c
@@ -259,13 +259,12 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
break;
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
- char *s;
+ char *s = NULL;
if (m->ellipsis)
continue;
- asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
- if (s == NULL)
+ if (asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name) < 0 || s == NULL)
errx(1, "malloc");
fprintf(codefile, "/* %s */\n", m->name);
if (m->optional)
@@ -289,8 +288,8 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
fprintf(codefile,
"{\n"
"struct heim_octet_string *val;\n"
- "size_t elen, totallen = 0;\n"
- "int eret;\n");
+ "size_t elen = 0, totallen = 0;\n"
+ "int eret = 0;\n");
fprintf(codefile,
"if ((%s)->len > UINT_MAX/sizeof(val[0]))\n"
@@ -352,19 +351,17 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
break;
}
case TSequenceOf: {
- char *n;
- char *sname;
+ char *sname = NULL;
+ char *n = NULL;
fprintf (codefile,
"for(i = (%s)->len - 1; i >= 0; --i) {\n"
"size_t %s_for_oldret = ret;\n"
"ret = 0;\n",
name, tmpstr);
- asprintf (&n, "&(%s)->val[i]", name);
- if (n == NULL)
+ if (asprintf (&n, "&(%s)->val[i]", name) < 0 || n == NULL)
errx(1, "malloc");
- asprintf (&sname, "%s_S_Of", tmpstr);
- if (sname == NULL)
+ if (asprintf (&sname, "%s_S_Of", tmpstr) < 0 || sname == NULL)
errx(1, "malloc");
encode_type (n, t->subtype, sname);
fprintf (codefile,
@@ -388,10 +385,9 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
constructed = 0;
break;
case TTag: {
- char *tname;
+ char *tname = NULL;
int c;
- asprintf (&tname, "%s_tag", tmpstr);
- if (tname == NULL)
+ if (asprintf (&tname, "%s_tag", tmpstr) < 0 || tname == NULL)
errx(1, "malloc");
c = encode_type (name, t->subtype, tname);
fprintf (codefile,
@@ -405,20 +401,19 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
}
case TChoice:{
Member *m, *have_ellipsis = NULL;
- char *s;
+ char *s = NULL;
if (t->members == NULL)
break;
fprintf(codefile, "\n");
- asprintf (&s, "(%s)", name);
- if (s == NULL)
+ if (asprintf (&s, "(%s)", name) < 0 || s == NULL)
errx(1, "malloc");
fprintf(codefile, "switch(%s->element) {\n", s);
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
- char *s2;
+ char *s2 = NULL;
if (m->ellipsis) {
have_ellipsis = m;
@@ -426,9 +421,8 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
}
fprintf (codefile, "case %s: {", m->label);
- asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&",
- s, m->gen_name);
- if (s2 == NULL)
+ if (asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&",
+ s, m->gen_name) < 0 || s2 == NULL)
errx(1, "malloc");
if (m->optional)
fprintf (codefile, "if(%s) {\n", s2);
@@ -508,7 +502,7 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
void
generate_type_encode (const Symbol *s)
{
- fprintf (codefile, "int\n"
+ fprintf (codefile, "int ASN1CALL\n"
"encode_%s(unsigned char *p, size_t len,"
" const %s *data, size_t *size)\n"
"{\n",
diff --git a/source4/heimdal/lib/asn1/gen_free.c b/source4/heimdal/lib/asn1/gen_free.c
index dc612074a3..7c88751c32 100644
--- a/source4/heimdal/lib/asn1/gen_free.c
+++ b/source4/heimdal/lib/asn1/gen_free.c
@@ -93,10 +93,9 @@ free_type (const char *name, const Type *t, int preserve)
if(t->type == TChoice)
fprintf(codefile, "case %s:\n", m->label);
- asprintf (&s, "%s(%s)->%s%s",
- m->optional ? "" : "&", name,
- t->type == TChoice ? "u." : "", m->gen_name);
- if (s == NULL)
+ if (asprintf (&s, "%s(%s)->%s%s",
+ m->optional ? "" : "&", name,
+ t->type == TChoice ? "u." : "", m->gen_name) < 0 || s == NULL)
errx(1, "malloc");
if(m->optional)
fprintf(codefile, "if(%s) {\n", s);
@@ -128,8 +127,7 @@ free_type (const char *name, const Type *t, int preserve)
char *n;
fprintf (codefile, "while((%s)->len){\n", name);
- asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
- if (n == NULL)
+ if (asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name) < 0 || n == NULL)
errx(1, "malloc");
free_type(n, t->subtype, FALSE);
fprintf(codefile,
@@ -182,7 +180,7 @@ generate_type_free (const Symbol *s)
{
int preserve = preserve_type(s->name) ? TRUE : FALSE;
- fprintf (codefile, "void\n"
+ fprintf (codefile, "void ASN1CALL\n"
"free_%s(%s *data)\n"
"{\n",
s->gen_name, s->gen_name);
diff --git a/source4/heimdal/lib/asn1/gen_glue.c b/source4/heimdal/lib/asn1/gen_glue.c
index 32680cef41..5ab93305a2 100644
--- a/source4/heimdal/lib/asn1/gen_glue.c
+++ b/source4/heimdal/lib/asn1/gen_glue.c
@@ -103,7 +103,7 @@ generate_units (const Type *t, const char *gen_name)
gen_name, gen_name);
} else {
fprintf (headerfile,
- "const struct units * asn1_%s_units(void);",
+ "const struct units * asn1_%s_units(void);\n",
gen_name);
}
diff --git a/source4/heimdal/lib/asn1/gen_length.c b/source4/heimdal/lib/asn1/gen_length.c
index da6d26e373..20b5adfe5d 100644
--- a/source4/heimdal/lib/asn1/gen_length.c
+++ b/source4/heimdal/lib/asn1/gen_length.c
@@ -149,10 +149,9 @@ length_type (const char *name, const Type *t,
if(t->type == TChoice)
fprintf(codefile, "case %s:\n", m->label);
- asprintf (&s, "%s(%s)->%s%s",
- m->optional ? "" : "&", name,
- t->type == TChoice ? "u." : "", m->gen_name);
- if (s == NULL)
+ if (asprintf (&s, "%s(%s)->%s%s",
+ m->optional ? "" : "&", name,
+ t->type == TChoice ? "u." : "", m->gen_name) < 0 || s == NULL)
errx(1, "malloc");
if (m->optional)
fprintf (codefile, "if(%s)", s);
@@ -183,24 +182,22 @@ length_type (const char *name, const Type *t,
}
case TSetOf:
case TSequenceOf: {
- char *n;
- char *sname;
+ char *n = NULL;
+ char *sname = NULL;
fprintf (codefile,
"{\n"
- "int %s_oldret = %s;\n"
+ "size_t %s_oldret = %s;\n"
"int i;\n"
"%s = 0;\n",
tmpstr, variable, variable);
fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
- fprintf (codefile, "int %s_for_oldret = %s;\n"
+ fprintf (codefile, "size_t %s_for_oldret = %s;\n"
"%s = 0;\n", tmpstr, variable, variable);
- asprintf (&n, "&(%s)->val[i]", name);
- if (n == NULL)
+ if (asprintf (&n, "&(%s)->val[i]", name) < 0 || n == NULL)
errx(1, "malloc");
- asprintf (&sname, "%s_S_Of", tmpstr);
- if (sname == NULL)
+ if (asprintf (&sname, "%s_S_Of", tmpstr) < 0 || sname == NULL)
errx(1, "malloc");
length_type(n, t->subtype, variable, sname);
fprintf (codefile, "%s += %s_for_oldret;\n",
@@ -248,9 +245,8 @@ length_type (const char *name, const Type *t,
fprintf (codefile, "/* NULL */\n");
break;
case TTag:{
- char *tname;
- asprintf(&tname, "%s_tag", tmpstr);
- if (tname == NULL)
+ char *tname = NULL;
+ if (asprintf(&tname, "%s_tag", tmpstr) < 0 || tname == NULL)
errx(1, "malloc");
length_type (name, t->subtype, variable, tname);
fprintf (codefile, "ret += %lu + der_length_len (ret);\n",
@@ -271,7 +267,7 @@ void
generate_type_length (const Symbol *s)
{
fprintf (codefile,
- "size_t\n"
+ "size_t ASN1CALL\n"
"length_%s(const %s *data)\n"
"{\n"
"size_t ret = 0;\n",
diff --git a/source4/heimdal/lib/asn1/gen_seq.c b/source4/heimdal/lib/asn1/gen_seq.c
index ec3ccc265e..ac7b9ed0ba 100644
--- a/source4/heimdal/lib/asn1/gen_seq.c
+++ b/source4/heimdal/lib/asn1/gen_seq.c
@@ -47,8 +47,8 @@ generate_type_seq (const Symbol *s)
while(type->type == TTag)
type = type->subtype;
- if (type->type != TSequenceOf) {
- printf("%s not seq of %d\n", s->name, (int)type->type);
+ if (type->type != TSequenceOf && type->type != TSetOf) {
+ fprintf(stderr, "%s not seq of %d\n", s->name, (int)type->type);
return;
}
@@ -67,12 +67,12 @@ generate_type_seq (const Symbol *s)
subname = type->subtype->symbol->gen_name;
fprintf (headerfile,
- "int add_%s (%s *, const %s *);\n"
- "int remove_%s (%s *, unsigned int);\n",
+ "ASN1EXP int ASN1CALL add_%s (%s *, const %s *);\n"
+ "ASN1EXP int ASN1CALL remove_%s (%s *, unsigned int);\n",
s->gen_name, s->gen_name, subname,
s->gen_name, s->gen_name);
- fprintf (codefile, "int\n"
+ fprintf (codefile, "int ASN1CALL\n"
"add_%s(%s *data, const %s *element)\n"
"{\n",
s->gen_name, s->gen_name, subname);
@@ -93,7 +93,7 @@ generate_type_seq (const Symbol *s)
fprintf (codefile, "}\n\n");
- fprintf (codefile, "int\n"
+ fprintf (codefile, "int ASN1CALL\n"
"remove_%s(%s *data, unsigned int element)\n"
"{\n",
s->gen_name, s->gen_name);
diff --git a/source4/heimdal/lib/asn1/gen_template.c b/source4/heimdal/lib/asn1/gen_template.c
index 8d4d9b49c2..9e09eb2d8d 100644
--- a/source4/heimdal/lib/asn1/gen_template.c
+++ b/source4/heimdal/lib/asn1/gen_template.c
@@ -224,7 +224,8 @@ partial_offset(const char *basetype, const char *name, int need_offset)
char *str;
if (name == NULL || need_offset == 0)
return strdup("0");
- asprintf(&str, "offsetof(struct %s, %s)", basetype, name);
+ if (asprintf(&str, "offsetof(struct %s, %s)", basetype, name) < 0 || str == NULL)
+ errx(1, "malloc");
return str;
}
@@ -273,7 +274,8 @@ tlist_header(struct tlist *t, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- vasprintf(&t->header, fmt, ap);
+ if (vasprintf(&t->header, fmt, ap) < 0 || t->header == NULL)
+ errx(1, "malloc");
va_end(ap);
}
@@ -389,7 +391,8 @@ add_line(struct templatehead *t, const char *fmt, ...)
struct template *q = calloc(1, sizeof(*q));
va_list ap;
va_start(ap, fmt);
- vasprintf(&q->line, fmt, ap);
+ if (vasprintf(&q->line, fmt, ap) < 0 || q->line == NULL)
+ errx(1, "malloc");
va_end(ap);
ASN1_TAILQ_INSERT_TAIL(t, q, members);
return q;
@@ -404,10 +407,11 @@ add_line_pointer(struct templatehead *t,
{
struct template *q;
va_list ap;
- char *tt;
+ char *tt = NULL;
va_start(ap, ttfmt);
- vasprintf(&tt, ttfmt, ap);
+ if (vasprintf(&tt, ttfmt, ap) < 0 || tt == NULL)
+ errx(1, "malloc");
va_end(ap);
q = add_line(t, "{ %s, %s, asn1_%s }", tt, offset, ptr);
@@ -543,7 +547,7 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
struct template *q;
Member *m;
size_t count = 0, i;
- char *bname;
+ char *bname = NULL;
FILE *f = get_code_file();
if (ASN1_TAILQ_EMPTY(t->members)) {
@@ -551,7 +555,8 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
break;
}
- asprintf(&bname, "bmember_%s_%lu", name ? name : "", (unsigned long)t);
+ if (asprintf(&bname, "bmember_%s_%lu", name ? name : "", (unsigned long)t) < 0 || bname == NULL)
+ errx(1, "malloc");
output_name(bname);
ASN1_TAILQ_FOREACH(m, t->members, members) {
@@ -583,15 +588,18 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
Member *m;
ASN1_TAILQ_FOREACH(m, t->members, members) {
- char *newbasename;
-
+ char *newbasename = NULL;
+
if (m->ellipsis)
continue;
- if (name)
- asprintf(&newbasename, "%s_%s", basetype, name);
- else
+ if (name) {
+ if (asprintf(&newbasename, "%s_%s", basetype, name) < 0)
+ errx(1, "malloc");
+ } else
newbasename = strdup(basetype);
+ if (newbasename == NULL)
+ errx(1, "malloc");
template_members(temp, newbasename, m->gen_name, m->type, m->optional, isstruct, 1);
@@ -601,7 +609,7 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
break;
}
case TTag: {
- char *tname, *elname;
+ char *tname = NULL, *elname = NULL;
const char *sename, *dupname;
int subtype_is_struct = is_struct(t->subtype, isstruct);
@@ -610,10 +618,12 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
else
sename = symbol_name(basetype, t->subtype);
- asprintf(&tname, "tag_%s_%lu", name ? name : "", (unsigned long)t);
+ if (asprintf(&tname, "tag_%s_%lu", name ? name : "", (unsigned long)t) < 0 || tname == NULL)
+ errx(1, "malloc");
output_name(tname);
- asprintf(&elname, "%s_%s", basetype, tname);
+ if (asprintf(&elname, "%s_%s", basetype, tname) < 0 || elname == NULL)
+ errx(1, "malloc");
generate_template_type(elname, &dupname, NULL, sename, name,
t->subtype, 0, subtype_is_struct, 0);
@@ -633,16 +643,17 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
case TSetOf:
case TSequenceOf: {
const char *type, *tname, *dupname;
- char *sename, *elname;
+ char *sename = NULL, *elname = NULL;
int subtype_is_struct = is_struct(t->subtype, 0);
if (name && subtype_is_struct) {
tname = "seofTstruct";
- asprintf(&sename, "%s_%s_val",
- basetype, name);
+ if (asprintf(&sename, "%s_%s_val", basetype, name) < 0)
+ errx(1, "malloc");
} else if (subtype_is_struct) {
tname = "seofTstruct";
- asprintf(&sename, "%s_val", symbol_name(basetype, t->subtype));
+ if (asprintf(&sename, "%s_val", symbol_name(basetype, t->subtype)) < 0)
+ errx(1, "malloc");
} else {
if (name)
tname = name;
@@ -650,12 +661,15 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
tname = "seofTstruct";
sename = strdup(symbol_name(basetype, t->subtype));
}
+ if (sename == NULL)
+ errx(1, "malloc");
if (t->type == TSetOf) type = "A1_OP_SETOF";
else if (t->type == TSequenceOf) type = "A1_OP_SEQOF";
else abort();
- asprintf(&elname, "%s_%s_%lu", basetype, tname, (unsigned long)t);
+ if (asprintf(&elname, "%s_%s_%lu", basetype, tname, (unsigned long)t) < 0 || elname == NULL)
+ errx(1, "malloc");
generate_template_type(elname, &dupname, NULL, sename, NULL, t->subtype,
0, subtype_is_struct, need_offset);
@@ -668,21 +682,22 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
struct templatehead template = ASN1_TAILQ_HEAD_INITIALIZER(template);
struct template *q;
size_t count = 0, i;
- char *tname;
+ char *tname = NULL;
FILE *f = get_code_file();
Member *m;
int ellipsis = 0;
char *e;
- asprintf(&tname, "asn1_choice_%s_%s%x",
- basetype, name ? name : "", (unsigned int)(uintptr_t)t);
+ if (asprintf(&tname, "asn1_choice_%s_%s%x",
+ basetype, name ? name : "", (unsigned int)(uintptr_t)t) < 0 || tname == NULL)
+ errx(1, "malloc");
ASN1_TAILQ_FOREACH(m, t->members, members) {
const char *dupname;
- char *elname;
- char *newbasename;
+ char *elname = NULL;
+ char *newbasename = NULL;
int subtype_is_struct;
-
+
if (m->ellipsis) {
ellipsis = 1;
continue;
@@ -690,13 +705,19 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
subtype_is_struct = is_struct(m->type, 0);
- asprintf(&elname, "%s_choice_%s", basetype, m->gen_name);
+ if (asprintf(&elname, "%s_choice_%s", basetype, m->gen_name) < 0 || elname == NULL)
+ errx(1, "malloc");
- if (subtype_is_struct)
- asprintf(&newbasename, "%s_%s", basetype, m->gen_name);
- else
+ if (subtype_is_struct) {
+ if (asprintf(&newbasename, "%s_%s", basetype, m->gen_name) < 0)
+ errx(1, "malloc");
+ } else
newbasename = strdup(basetype);
+ if (newbasename == NULL)
+ errx(1, "malloc");
+
+
generate_template_type(elname, &dupname, NULL,
symbol_name(newbasename, m->type),
NULL, m->type, 0, subtype_is_struct, 1);
@@ -710,10 +731,11 @@ template_members(struct templatehead *temp, const char *basetype, const char *na
free(newbasename);
}
+ e = NULL;
if (ellipsis) {
- asprintf(&e, "offsetof(%s%s, u.asn1_ellipsis)", isstruct ? "struct " : "", basetype);
- } else
- e = NULL;
+ if (asprintf(&e, "offsetof(%s%s, u.asn1_ellipsis)", isstruct ? "struct " : "", basetype) < 0 || e == NULL)
+ errx(1, "malloc");
+ }
ASN1_TAILQ_FOREACH(q, &template, members) {
count++;
diff --git a/source4/heimdal/lib/asn1/rfc2459.asn1 b/source4/heimdal/lib/asn1/rfc2459.asn1
index 9794ca1514..5df9e41fff 100644
--- a/source4/heimdal/lib/asn1/rfc2459.asn1
+++ b/source4/heimdal/lib/asn1/rfc2459.asn1
@@ -52,6 +52,9 @@ id-rsadsi-des-ede3-cbc OBJECT IDENTIFIER ::= { id-rsadsi-encalg 7 }
id-secsig-sha-1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
oiw(14) secsig(3) algorithm(2) 26 }
+id-secsig-sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+ oiw(14) secsig(3) algorithm(2) 29 }
+
id-nistAlgorithm OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) 4 }
@@ -241,6 +244,13 @@ DomainParameters ::= SEQUENCE {
validationParms ValidationParms OPTIONAL -- ValidationParms
}
+-- As defined by PKCS3
+DHParameter ::= SEQUENCE {
+ prime INTEGER, -- odd prime, p=jq +1
+ base INTEGER, -- generator, g
+ privateValueLength INTEGER OPTIONAL
+}
+
DHPublicKey ::= INTEGER
OtherName ::= SEQUENCE {
diff --git a/source4/heimdal/lib/com_err/com_err.c b/source4/heimdal/lib/com_err/com_err.c
index a43d1e3e6c..fe4cc2983c 100644
--- a/source4/heimdal/lib/com_err/com_err.c
+++ b/source4/heimdal/lib/com_err/com_err.c
@@ -43,7 +43,7 @@
struct et_list *_et_list = NULL;
-const char *
+KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
error_message (long code)
{
static char msg[128];
@@ -61,18 +61,18 @@ error_message (long code)
return msg;
}
-int
+KRB5_LIB_FUNCTION int KRB5_LIB_CALL
init_error_table(const char **msgs, long base, int count)
{
initialize_error_table_r(&_et_list, msgs, count, base);
return 0;
}
-static void
+static void KRB5_CALLCONV
default_proc (const char *whoami, long code, const char *fmt, va_list args)
__attribute__((__format__(__printf__, 3, 0)));
-static void
+static void KRB5_CALLCONV
default_proc (const char *whoami, long code, const char *fmt, va_list args)
{
if (whoami)
@@ -86,7 +86,7 @@ default_proc (const char *whoami, long code, const char *fmt, va_list args)
static errf com_err_hook = default_proc;
-void
+KRB5_LIB_FUNCTION void KRB5_LIB_CALL
com_err_va (const char *whoami,
long code,
const char *fmt,
@@ -95,7 +95,7 @@ com_err_va (const char *whoami,
(*com_err_hook) (whoami, code, fmt, args);
}
-void
+KRB5_LIB_FUNCTION void KRB5_LIB_CALL
com_err (const char *whoami,
long code,
const char *fmt,
@@ -107,7 +107,7 @@ com_err (const char *whoami,
va_end(ap);
}
-errf
+KRB5_LIB_FUNCTION errf KRB5_LIB_CALL
set_com_err_hook (errf new)
{
errf old = com_err_hook;
@@ -120,7 +120,7 @@ set_com_err_hook (errf new)
return old;
}
-errf
+KRB5_LIB_FUNCTION errf KRB5_LIB_CALL
reset_com_err_hook (void)
{
return set_com_err_hook(NULL);
@@ -134,7 +134,7 @@ static const char char_set[] =
static char buf[6];
-const char *
+KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
error_table_name(int num)
{
int ch;
@@ -156,7 +156,7 @@ error_table_name(int num)
return(buf);
}
-void
+KRB5_LIB_FUNCTION void KRB5_LIB_CALL
add_to_error_table(struct et_list *new_table)
{
struct et_list *et;
diff --git a/source4/heimdal/lib/com_err/com_err.h b/source4/heimdal/lib/com_err/com_err.h
index a8ceb969cb..1fcfe7f7aa 100644
--- a/source4/heimdal/lib/com_err/com_err.h
+++ b/source4/heimdal/lib/com_err/com_err.h
@@ -45,22 +45,52 @@
#define __attribute__(X)
#endif
-typedef void (*errf) (const char *, long, const char *, va_list);
+#ifndef KRB5_LIB
+#ifndef KRB5_LIB_FUNCTION
+#if defined(_WIN32)
+#define KRB5_LIB_FUNCTION __declspec(dllimport)
+#define KRB5_LIB_CALL __stdcall
+#define KRB5_LIB_VARIABLE __declspec(dllimport)
+#else
+#define KRB5_LIB_FUNCTION
+#define KRB5_LIB_CALL
+#define KRB5_LIB_VARIABLE
+#endif
+#endif
+#endif
+
+#ifdef _WIN32
+#define KRB5_CALLCONV __stdcall
+#else
+#define KRB5_CALLCONV
+#endif
+
+typedef void (KRB5_CALLCONV *errf) (const char *, long, const char *, va_list);
-const char * error_message (long);
-int init_error_table (const char**, long, int);
+KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
+error_message (long);
-void com_err_va (const char *, long, const char *, va_list)
+KRB5_LIB_FUNCTION int KRB5_LIB_CALL
+init_error_table (const char**, long, int);
+
+KRB5_LIB_FUNCTION void KRB5_LIB_CALL
+com_err_va (const char *, long, const char *, va_list)
__attribute__((format(printf, 3, 0)));
-void com_err (const char *, long, const char *, ...)
+KRB5_LIB_FUNCTION void KRB5_LIB_CALL
+com_err (const char *, long, const char *, ...)
__attribute__((format(printf, 3, 4)));
-errf set_com_err_hook (errf);
-errf reset_com_err_hook (void);
+KRB5_LIB_FUNCTION errf KRB5_LIB_CALL
+set_com_err_hook (errf);
+
+KRB5_LIB_FUNCTION errf KRB5_LIB_CALL
+reset_com_err_hook (void);
-const char *error_table_name (int num);
+KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL
+error_table_name (int num);
-void add_to_error_table (struct et_list *new_table);
+KRB5_LIB_FUNCTION void KRB5_LIB_CALL
+add_to_error_table (struct et_list *new_table);
#endif /* __COM_ERR_H__ */
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
index 3f217d38cb..fa53a8a74c 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
@@ -73,6 +73,12 @@
#define GSSAPI_CPP_END
#endif
+#ifdef _WIN32
+#define GSSAPI_CALLCONV __stdcall
+#else
+#define GSSAPI_CALLCONV
+#endif
+
/*
* Now define the three implementation-dependent types.
*/
@@ -266,7 +272,8 @@ GSSAPI_CPP_START
* GSS_C_NT_USER_NAME should be initialized to point
* to that gss_OID_desc.
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_USER_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_user_name_oid_desc;
+#define GSS_C_NT_USER_NAME (&__gss_c_nt_user_name_oid_desc)
/*
* The implementation must reserve static storage for a
@@ -279,7 +286,8 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_USER_NAME;
* The constant GSS_C_NT_MACHINE_UID_NAME should be
* initialized to point to that gss_OID_desc.
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_MACHINE_UID_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_machine_uid_name_oid_desc;
+#define GSS_C_NT_MACHINE_UID_NAME (&__gss_c_nt_machine_uid_name_oid_desc)
/*
* The implementation must reserve static storage for a
@@ -292,7 +300,8 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_MACHINE_UID_NAME;
* The constant GSS_C_NT_STRING_UID_NAME should be
* initialized to point to that gss_OID_desc.
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_STRING_UID_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_string_uid_name_oid_desc;
+#define GSS_C_NT_STRING_UID_NAME (&__gss_c_nt_string_uid_name_oid_desc)
/*
* The implementation must reserve static storage for a
@@ -311,7 +320,8 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_STRING_UID_NAME;
* parameter, but should not be emitted by GSS-API
* implementations
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_hostbased_service_x_oid_desc;
+#define GSS_C_NT_HOSTBASED_SERVICE_X (&__gss_c_nt_hostbased_service_x_oid_desc)
/*
* The implementation must reserve static storage for a
@@ -324,7 +334,8 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
* GSS_C_NT_HOSTBASED_SERVICE should be initialized
* to point to that gss_OID_desc.
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_hostbased_service_oid_desc;
+#define GSS_C_NT_HOSTBASED_SERVICE (&__gss_c_nt_hostbased_service_oid_desc)
/*
* The implementation must reserve static storage for a
@@ -336,7 +347,8 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_HOSTBASED_SERVICE;
* and GSS_C_NT_ANONYMOUS should be initialized to point
* to that gss_OID_desc.
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_ANONYMOUS;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_anonymous_oid_desc;
+#define GSS_C_NT_ANONYMOUS (&__gss_c_nt_anonymous_oid_desc)
/*
* The implementation must reserve static storage for a
@@ -348,13 +360,16 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_ANONYMOUS;
* GSS_C_NT_EXPORT_NAME should be initialized to point
* to that gss_OID_desc.
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_EXPORT_NAME;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_nt_export_name_oid_desc;
+#define GSS_C_NT_EXPORT_NAME (&__gss_c_nt_export_name_oid_desc)
/*
* Digest mechanism
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_SASL_DIGEST_MD5_MECHANISM;
+extern gss_OID_desc GSSAPI_LIB_VARIABLE __gss_sasl_digest_md5_mechanism_oid_desc;
+#define GSS_SASL_DIGEST_MD5_MECHANISM (&__gss_sasl_digest_md5_mechanism_oid_desc)
+
/* Major status codes */
@@ -437,7 +452,7 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_SASL_DIGEST_MD5_MECHANISM;
* Finally, function prototypes for the GSS-API routines.
*/
-OM_uint32 GSSAPI_LIB_FUNCTION gss_acquire_cred
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_acquire_cred
(OM_uint32 * /*minor_status*/,
const gss_name_t /*desired_name*/,
OM_uint32 /*time_req*/,
@@ -448,12 +463,12 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_acquire_cred
OM_uint32 * /*time_rec*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_release_cred
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_release_cred
(OM_uint32 * /*minor_status*/,
gss_cred_id_t * /*cred_handle*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_init_sec_context
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_init_sec_context
(OM_uint32 * /*minor_status*/,
const gss_cred_id_t /*initiator_cred_handle*/,
gss_ctx_id_t * /*context_handle*/,
@@ -469,7 +484,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_init_sec_context
OM_uint32 * /*time_rec*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_accept_sec_context
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_accept_sec_context
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t * /*context_handle*/,
const gss_cred_id_t /*acceptor_cred_handle*/,
@@ -483,25 +498,25 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_accept_sec_context
gss_cred_id_t * /*delegated_cred_handle*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_process_context_token
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_process_context_token
(OM_uint32 * /*minor_status*/,
const gss_ctx_id_t /*context_handle*/,
const gss_buffer_t /*token_buffer*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_delete_sec_context
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_delete_sec_context
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t * /*context_handle*/,
gss_buffer_t /*output_token*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_context_time
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_context_time
(OM_uint32 * /*minor_status*/,
const gss_ctx_id_t /*context_handle*/,
OM_uint32 * /*time_rec*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_get_mic
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_get_mic
(OM_uint32 * /*minor_status*/,
const gss_ctx_id_t /*context_handle*/,
gss_qop_t /*qop_req*/,
@@ -509,7 +524,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_get_mic
gss_buffer_t /*message_token*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_verify_mic
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_verify_mic
(OM_uint32 * /*minor_status*/,
const gss_ctx_id_t /*context_handle*/,
const gss_buffer_t /*message_buffer*/,
@@ -517,7 +532,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_verify_mic
gss_qop_t * /*qop_state*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_wrap
(OM_uint32 * /*minor_status*/,
const gss_ctx_id_t /*context_handle*/,
int /*conf_req_flag*/,
@@ -527,7 +542,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap
gss_buffer_t /*output_message_buffer*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_unwrap
(OM_uint32 * /*minor_status*/,
const gss_ctx_id_t /*context_handle*/,
const gss_buffer_t /*input_message_buffer*/,
@@ -536,7 +551,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_unwrap
gss_qop_t * /*qop_state*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_display_status
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_display_status
(OM_uint32 * /*minor_status*/,
OM_uint32 /*status_value*/,
int /*status_type*/,
@@ -545,54 +560,54 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_display_status
gss_buffer_t /*status_string*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_indicate_mechs
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_indicate_mechs
(OM_uint32 * /*minor_status*/,
gss_OID_set * /*mech_set*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_compare_name
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_compare_name
(OM_uint32 * /*minor_status*/,
const gss_name_t /*name1*/,
const gss_name_t /*name2*/,
int * /*name_equal*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_display_name
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_display_name
(OM_uint32 * /*minor_status*/,
const gss_name_t /*input_name*/,
gss_buffer_t /*output_name_buffer*/,
gss_OID * /*output_name_type*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_import_name
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_import_name
(OM_uint32 * /*minor_status*/,
const gss_buffer_t /*input_name_buffer*/,
const gss_OID /*input_name_type*/,
gss_name_t * /*output_name*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_export_name
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_export_name
(OM_uint32 * /*minor_status*/,
const gss_name_t /*input_name*/,
gss_buffer_t /*exported_name*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_release_name
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_release_name
(OM_uint32 * /*minor_status*/,
gss_name_t * /*input_name*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_release_buffer
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_release_buffer
(OM_uint32 * /*minor_status*/,
gss_buffer_t /*buffer*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_release_oid_set
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_release_oid_set
(OM_uint32 * /*minor_status*/,
gss_OID_set * /*set*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_cred
(OM_uint32 * /*minor_status*/,
const gss_cred_id_t /*cred_handle*/,
gss_name_t * /*name*/,
@@ -601,7 +616,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred
gss_OID_set * /*mechanisms*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_context (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_context (
OM_uint32 * /*minor_status*/,
const gss_ctx_id_t /*context_handle*/,
gss_name_t * /*src_name*/,
@@ -613,7 +628,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_context (
int * /*open_context*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_size_limit (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_wrap_size_limit (
OM_uint32 * /*minor_status*/,
const gss_ctx_id_t /*context_handle*/,
int /*conf_req_flag*/,
@@ -622,7 +637,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_wrap_size_limit (
OM_uint32 * /*max_input_size*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_add_cred (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_add_cred (
OM_uint32 * /*minor_status*/,
const gss_cred_id_t /*input_cred_handle*/,
const gss_name_t /*desired_name*/,
@@ -636,7 +651,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_add_cred (
OM_uint32 * /*acceptor_time_rec*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred_by_mech (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_cred_by_mech (
OM_uint32 * /*minor_status*/,
const gss_cred_id_t /*cred_handle*/,
const gss_OID /*mech_type*/,
@@ -646,81 +661,81 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_cred_by_mech (
gss_cred_usage_t * /*cred_usage*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_export_sec_context (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_export_sec_context (
OM_uint32 * /*minor_status*/,
gss_ctx_id_t * /*context_handle*/,
gss_buffer_t /*interprocess_token*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_import_sec_context (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_import_sec_context (
OM_uint32 * /*minor_status*/,
const gss_buffer_t /*interprocess_token*/,
gss_ctx_id_t * /*context_handle*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_create_empty_oid_set (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_create_empty_oid_set (
OM_uint32 * /*minor_status*/,
gss_OID_set * /*oid_set*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_add_oid_set_member (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_add_oid_set_member (
OM_uint32 * /*minor_status*/,
const gss_OID /*member_oid*/,
gss_OID_set * /*oid_set*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_test_oid_set_member (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_test_oid_set_member (
OM_uint32 * /*minor_status*/,
const gss_OID /*member*/,
const gss_OID_set /*set*/,
int * /*present*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_names_for_mech (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_names_for_mech (
OM_uint32 * /*minor_status*/,
const gss_OID /*mechanism*/,
gss_OID_set * /*name_types*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_inquire_mechs_for_name (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_inquire_mechs_for_name (
OM_uint32 * /*minor_status*/,
const gss_name_t /*input_name*/,
gss_OID_set * /*mech_types*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_canonicalize_name (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_canonicalize_name (
OM_uint32 * /*minor_status*/,
const gss_name_t /*input_name*/,
const gss_OID /*mech_type*/,
gss_name_t * /*output_name*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_duplicate_name (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_duplicate_name (
OM_uint32 * /*minor_status*/,
const gss_name_t /*src_name*/,
gss_name_t * /*dest_name*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_duplicate_oid (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_duplicate_oid (
OM_uint32 * /* minor_status */,
gss_OID /* src_oid */,
gss_OID * /* dest_oid */
);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_oid
(OM_uint32 * /*minor_status*/,
gss_OID * /* oid */
);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_oid_to_str(
OM_uint32 * /*minor_status*/,
gss_OID /* oid */,
gss_buffer_t /* str */
);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_sec_context_by_oid(
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
@@ -728,38 +743,38 @@ gss_inquire_sec_context_by_oid(
gss_buffer_set_t *data_set
);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_set_sec_context_option (OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
const gss_OID desired_object,
const gss_buffer_t value);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_set_cred_option (OM_uint32 *minor_status,
gss_cred_id_t *cred_handle,
const gss_OID object,
const gss_buffer_t value);
-int GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
gss_oid_equal(const gss_OID a, const gss_OID b);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_create_empty_buffer_set
(OM_uint32 * minor_status,
gss_buffer_set_t *buffer_set);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_add_buffer_set_member
(OM_uint32 * minor_status,
const gss_buffer_t member_buffer,
gss_buffer_set_t *buffer_set);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_buffer_set
(OM_uint32 * minor_status,
gss_buffer_set_t *buffer_set);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_cred_by_oid(OM_uint32 *minor_status,
const gss_cred_id_t cred_handle,
const gss_OID desired_object,
@@ -772,7 +787,7 @@ gss_inquire_cred_by_oid(OM_uint32 *minor_status,
#define GSS_C_PRF_KEY_FULL 0
#define GSS_C_PRF_KEY_PARTIAL 1
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_pseudo_random
(OM_uint32 *minor_status,
gss_ctx_id_t context,
@@ -782,7 +797,7 @@ gss_pseudo_random
gss_buffer_t prf_out
);
-OM_uint32
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_store_cred(OM_uint32 * /* minor_status */,
gss_cred_id_t /* input_cred_handle */,
gss_cred_usage_t /* cred_usage */,
@@ -807,10 +822,11 @@ typedef struct {
(GSS_IOV_BUFFER_TYPE_PADDING) */
} gss_context_stream_sizes;
-extern gss_OID GSSAPI_LIB_VARIABLE GSS_C_ATTR_STREAM_SIZES;
+extern gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_attr_stream_sizes_oid_desc;
+#define GSS_C_ATTR_STREAM_SIZES (&__gss_c_attr_stream_sizes_oid_desc)
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_context_query_attributes(OM_uint32 * /* minor_status */,
const gss_ctx_id_t /* context_handle */,
const gss_OID /* attribute */,
@@ -827,7 +843,7 @@ gss_context_query_attributes(OM_uint32 * /* minor_status */,
* obsolete versions of these routines and their current forms.
*/
-OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_sign
+GSSAPI_DEPRECATED GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_sign
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t /*context_handle*/,
int /*qop_req*/,
@@ -835,7 +851,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_sign
gss_buffer_t /*message_token*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_verify
+GSSAPI_DEPRECATED GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_verify
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t /*context_handle*/,
gss_buffer_t /*message_buffer*/,
@@ -843,7 +859,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_verify
int * /*qop_state*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_seal
+GSSAPI_DEPRECATED GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_seal
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t /*context_handle*/,
int /*conf_req_flag*/,
@@ -853,7 +869,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_seal
gss_buffer_t /*output_message_buffer*/
);
-OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_unseal
+GSSAPI_DEPRECATED GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_unseal
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t /*context_handle*/,
gss_buffer_t /*input_message_buffer*/,
@@ -866,12 +882,12 @@ OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_unseal
*
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_encapsulate_token(const gss_buffer_t /* input_token */,
const gss_OID /* oid */,
gss_buffer_t /* output_token */);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_decapsulate_token(const gss_buffer_t /* input_token */,
const gss_OID /* oid */,
gss_buffer_t /* output_token */);
@@ -886,29 +902,29 @@ gss_decapsulate_token(const gss_buffer_t /* input_token */,
* GSS_IOV
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_wrap_iov(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
gss_iov_buffer_desc *, int);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_unwrap_iov(OM_uint32 *, gss_ctx_id_t, int *, gss_qop_t *,
gss_iov_buffer_desc *, int);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_wrap_iov_length(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
gss_iov_buffer_desc *, int);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_export_cred(OM_uint32 * /* minor_status */,
gss_cred_id_t /* cred_handle */,
gss_buffer_t /* cred_token */);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_import_cred(OM_uint32 * /* minor_status */,
gss_buffer_t /* cred_token */,
gss_cred_id_t * /* cred_handle */);
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
index 1b91bbbb84..28f9c3777b 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
@@ -53,12 +53,15 @@ GSSAPI_CPP_START
* This is for kerberos5 names.
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_PRINCIPAL_NAME;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_USER_NAME;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_MACHINE_UID_NAME;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_NT_STRING_UID_NAME;
+extern gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_nt_principal_name_oid_desc;
+#define GSS_KRB5_NT_PRINCIPAL_NAME (&__gss_krb5_nt_principal_name_oid_desc)
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_MECHANISM;
+#define GSS_KRB5_NT_USER_NAME (&__gss_c_nt_user_name_oid_desc)
+#define GSS_KRB5_NT_MACHINE_UID_NAME (&__gss_c_nt_machine_uid_name_oid_desc)
+#define GSS_KRB5_NT_STRING_UID_NAME (&__gss_c_nt_string_uid_name_oid_desc)
+
+extern gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_mechanism_oid_desc;
+#define GSS_KRB5_MECHANISM (&__gss_krb5_mechanism_oid_desc)
/* for compatibility with MIT api */
@@ -66,31 +69,77 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_MECHANISM;
#define gss_krb5_nt_general_name GSS_KRB5_NT_PRINCIPAL_NAME
/* Extensions set contexts options */
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_COPY_CCACHE_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_COMPAT_DES3_MIC_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_DNS_CANONICALIZE_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SEND_TO_KDC_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_DEFAULT_REALM_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_CCACHE_NAME_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_TIME_OFFSET_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_TIME_OFFSET_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_PLUGIN_REGISTER_X;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_copy_ccache_x_oid_desc;
+#define GSS_KRB5_COPY_CCACHE_X (&__gss_krb5_copy_ccache_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_compat_des3_mic_x_oid_desc;
+#define GSS_KRB5_COMPAT_DES3_MIC_X (&__gss_krb5_compat_des3_mic_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_register_acceptor_identity_x_oid_desc;
+#define GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X (&__gss_krb5_register_acceptor_identity_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_set_dns_canonicalize_x_oid_desc;
+#define GSS_KRB5_SET_DNS_CANONICALIZE_X (&__gss_krb5_set_dns_canonicalize_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_send_to_kdc_x_oid_desc;
+#define GSS_KRB5_SEND_TO_KDC_X (&__gss_krb5_send_to_kdc_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_set_default_realm_x_oid_desc;
+#define GSS_KRB5_SET_DEFAULT_REALM_X (&__gss_krb5_set_default_realm_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_ccache_name_x_oid_desc;
+#define GSS_KRB5_CCACHE_NAME_X (&__gss_krb5_ccache_name_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_set_time_offset_x_oid_desc;
+#define GSS_KRB5_SET_TIME_OFFSET_X (&__gss_krb5_set_time_offset_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_time_offset_x_oid_desc;
+#define GSS_KRB5_GET_TIME_OFFSET_X (&__gss_krb5_get_time_offset_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_plugin_register_x_oid_desc;
+#define GSS_KRB5_PLUGIN_REGISTER_X (&__gss_krb5_plugin_register_x_oid_desc)
+
/* Extensions inquire context */
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_TKT_FLAGS_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_PEER_HAS_UPDATED_SPNEGO;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_SUBKEY_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_INITIATOR_SUBKEY_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_ACCEPTOR_SUBKEY_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_AUTHTIME_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_tkt_flags_x_oid_desc;
+#define GSS_KRB5_GET_TKT_FLAGS_X (&__gss_krb5_get_tkt_flags_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_extract_authz_data_from_sec_context_x_oid_desc;
+#define GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X (&__gss_krb5_extract_authz_data_from_sec_context_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_peer_has_updated_spnego_oid_desc;
+#define GSS_C_PEER_HAS_UPDATED_SPNEGO (&__gss_c_peer_has_updated_spnego_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_export_lucid_context_x_oid_desc;
+#define GSS_KRB5_EXPORT_LUCID_CONTEXT_X (&__gss_krb5_export_lucid_context_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_export_lucid_context_v1_x_oid_desc;
+#define GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X (&__gss_krb5_export_lucid_context_v1_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_subkey_x_oid_desc;
+#define GSS_KRB5_GET_SUBKEY_X (&__gss_krb5_get_subkey_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_initiator_subkey_x_oid_desc;
+#define GSS_KRB5_GET_INITIATOR_SUBKEY_X (&__gss_krb5_get_initiator_subkey_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_acceptor_subkey_x_oid_desc;
+#define GSS_KRB5_GET_ACCEPTOR_SUBKEY_X (&__gss_krb5_get_acceptor_subkey_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_authtime_x_oid_desc;
+#define GSS_KRB5_GET_AUTHTIME_X (&__gss_krb5_get_authtime_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_get_service_keyblock_x_oid_desc;
+#define GSS_KRB5_GET_SERVICE_KEYBLOCK_X (&__gss_krb5_get_service_keyblock_x_oid_desc)
+
/* Extensions creds */
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_IMPORT_CRED_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X;
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X;
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_import_cred_x_oid_desc;
+#define GSS_KRB5_IMPORT_CRED_X (&__gss_krb5_import_cred_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_set_allowable_enctypes_x_oid_desc;
+#define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X (&__gss_krb5_set_allowable_enctypes_x_oid_desc)
+
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_ci_flags_x_oid_desc;
+#define GSS_KRB5_CRED_NO_CI_FLAGS_X (&__gss_krb5_cred_no_ci_flags_x_oid_desc)
/*
* kerberos mechanism specific functions
@@ -100,42 +149,42 @@ struct krb5_keytab_data;
struct krb5_ccache_data;
struct Principal;
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_ccache_name(OM_uint32 * /*minor_status*/,
const char * /*name */,
const char ** /*out_name */);
-OM_uint32 GSSAPI_LIB_FUNCTION gsskrb5_register_acceptor_identity
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gsskrb5_register_acceptor_identity
(const char * /*identity*/);
-OM_uint32 GSSAPI_LIB_FUNCTION krb5_gss_register_acceptor_identity
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL krb5_gss_register_acceptor_identity
(const char * /*identity*/);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_copy_ccache
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_krb5_copy_ccache
(OM_uint32 * /*minor*/,
gss_cred_id_t /*cred*/,
struct krb5_ccache_data * /*out*/);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_import_cred(OM_uint32 * /*minor*/,
struct krb5_ccache_data * /*in*/,
struct Principal * /*keytab_principal*/,
struct krb5_keytab_data * /*keytab*/,
gss_cred_id_t * /*out*/);
-OM_uint32 GSSAPI_LIB_FUNCTION gss_krb5_get_tkt_flags
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_krb5_get_tkt_flags
(OM_uint32 * /*minor*/,
gss_ctx_id_t /*context_handle*/,
OM_uint32 * /*tkt_flags*/);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_extract_authz_data_from_sec_context
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t /*context_handle*/,
int /*ad_type*/,
gss_buffer_t /*ad_data*/);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_set_dns_canonicalize(int);
struct gsskrb5_send_to_kdc {
@@ -143,35 +192,35 @@ struct gsskrb5_send_to_kdc {
void *ptr;
};
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *)
GSSKRB5_FUNCTION_DEPRECATED;
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_set_default_realm(const char *);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_extract_authtime_from_sec_context(OM_uint32 *, gss_ctx_id_t, time_t *);
struct EncryptionKey;
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
struct EncryptionKey **out);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
struct EncryptionKey **out);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_get_subkey(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
struct EncryptionKey **out);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_set_time_offset(int);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_get_time_offset(int *);
struct gsskrb5_krb5_plugin {
@@ -180,7 +229,7 @@ struct gsskrb5_krb5_plugin {
void *symbol;
};
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_plugin_register(struct gsskrb5_krb5_plugin *);
@@ -226,19 +275,19 @@ typedef struct gss_krb5_lucid_context_version {
* Function declarations
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
OM_uint32 version,
void **kctx);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status,
void *kctx);
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status,
gss_cred_id_t cred,
OM_uint32 num_enctypes,
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
index c5d372d6dc..dd3b2a5c3f 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h
@@ -46,7 +46,8 @@ GSSAPI_CPP_START
* negotiation token is identified by the Object Identifier
* iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
*/
-extern GSSAPI_LIB_VARIABLE gss_OID GSS_SPNEGO_MECHANISM;
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_spnego_mechanism_oid_desc;
+#define GSS_SPNEGO_MECHANISM (&__gss_spnego_mechanism_oid_desc)
#define gss_mech_spnego GSS_SPNEGO_MECHANISM
GSSAPI_CPP_END
diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h
index 65cabf54d1..93b7bf72d7 100644
--- a/source4/heimdal/lib/gssapi/gssapi_mech.h
+++ b/source4/heimdal/lib/gssapi/gssapi_mech.h
@@ -31,7 +31,7 @@
#include <gssapi.h>
-typedef OM_uint32 _gss_acquire_cred_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_acquire_cred_t
(OM_uint32 *, /* minor_status */
const gss_name_t, /* desired_name */
OM_uint32, /* time_req */
@@ -42,12 +42,12 @@ typedef OM_uint32 _gss_acquire_cred_t
OM_uint32 * /* time_rec */
);
-typedef OM_uint32 _gss_release_cred_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_release_cred_t
(OM_uint32 *, /* minor_status */
gss_cred_id_t * /* cred_handle */
);
-typedef OM_uint32 _gss_init_sec_context_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_init_sec_context_t
(OM_uint32 *, /* minor_status */
const gss_cred_id_t, /* initiator_cred_handle */
gss_ctx_id_t *, /* context_handle */
@@ -64,7 +64,7 @@ typedef OM_uint32 _gss_init_sec_context_t
OM_uint32 * /* time_rec */
);
-typedef OM_uint32 _gss_accept_sec_context_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_accept_sec_context_t
(OM_uint32 *, /* minor_status */
gss_ctx_id_t *, /* context_handle */
const gss_cred_id_t, /* acceptor_cred_handle */
@@ -79,25 +79,25 @@ typedef OM_uint32 _gss_accept_sec_context_t
gss_cred_id_t * /* delegated_cred_handle */
);
-typedef OM_uint32 _gss_process_context_token_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_process_context_token_t
(OM_uint32 *, /* minor_status */
const gss_ctx_id_t, /* context_handle */
const gss_buffer_t /* token_buffer */
);
-typedef OM_uint32 _gss_delete_sec_context_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_delete_sec_context_t
(OM_uint32 *, /* minor_status */
gss_ctx_id_t *, /* context_handle */
gss_buffer_t /* output_token */
);
-typedef OM_uint32 _gss_context_time_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_context_time_t
(OM_uint32 *, /* minor_status */
const gss_ctx_id_t, /* context_handle */
OM_uint32 * /* time_rec */
);
-typedef OM_uint32 _gss_get_mic_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_get_mic_t
(OM_uint32 *, /* minor_status */
const gss_ctx_id_t, /* context_handle */
gss_qop_t, /* qop_req */
@@ -105,7 +105,7 @@ typedef OM_uint32 _gss_get_mic_t
gss_buffer_t /* message_token */
);
-typedef OM_uint32 _gss_verify_mic_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_verify_mic_t
(OM_uint32 *, /* minor_status */
const gss_ctx_id_t, /* context_handle */
const gss_buffer_t, /* message_buffer */
@@ -113,7 +113,7 @@ typedef OM_uint32 _gss_verify_mic_t
gss_qop_t * /* qop_state */
);
-typedef OM_uint32 _gss_wrap_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_wrap_t
(OM_uint32 *, /* minor_status */
const gss_ctx_id_t, /* context_handle */
int, /* conf_req_flag */
@@ -123,7 +123,7 @@ typedef OM_uint32 _gss_wrap_t
gss_buffer_t /* output_message_buffer */
);
-typedef OM_uint32 _gss_unwrap_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_unwrap_t
(OM_uint32 *, /* minor_status */
const gss_ctx_id_t, /* context_handle */
const gss_buffer_t, /* input_message_buffer */
@@ -132,7 +132,7 @@ typedef OM_uint32 _gss_unwrap_t
gss_qop_t * /* qop_state */
);
-typedef OM_uint32 _gss_display_status_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_display_status_t
(OM_uint32 *, /* minor_status */
OM_uint32, /* status_value */
int, /* status_type */
@@ -141,44 +141,44 @@ typedef OM_uint32 _gss_display_status_t
gss_buffer_t /* status_string */
);
-typedef OM_uint32 _gss_indicate_mechs_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_indicate_mechs_t
(OM_uint32 *, /* minor_status */
gss_OID_set * /* mech_set */
);
-typedef OM_uint32 _gss_compare_name_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_compare_name_t
(OM_uint32 *, /* minor_status */
const gss_name_t, /* name1 */
const gss_name_t, /* name2 */
int * /* name_equal */
);
-typedef OM_uint32 _gss_display_name_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_display_name_t
(OM_uint32 *, /* minor_status */
const gss_name_t, /* input_name */
gss_buffer_t, /* output_name_buffer */
gss_OID * /* output_name_type */
);
-typedef OM_uint32 _gss_import_name_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_import_name_t
(OM_uint32 *, /* minor_status */
const gss_buffer_t, /* input_name_buffer */
const gss_OID, /* input_name_type */
gss_name_t * /* output_name */
);
-typedef OM_uint32 _gss_export_name_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_export_name_t
(OM_uint32 *, /* minor_status */
const gss_name_t, /* input_name */
gss_buffer_t /* exported_name */
);
-typedef OM_uint32 _gss_release_name_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_release_name_t
(OM_uint32 *, /* minor_status */
gss_name_t * /* input_name */
);
-typedef OM_uint32 _gss_inquire_cred_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_cred_t
(OM_uint32 *, /* minor_status */
const gss_cred_id_t, /* cred_handle */
gss_name_t *, /* name */
@@ -187,7 +187,7 @@ typedef OM_uint32 _gss_inquire_cred_t
gss_OID_set * /* mechanisms */
);
-typedef OM_uint32 _gss_inquire_context_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_context_t
(OM_uint32 *, /* minor_status */
const gss_ctx_id_t, /* context_handle */
gss_name_t *, /* src_name */
@@ -199,7 +199,7 @@ typedef OM_uint32 _gss_inquire_context_t
int * /* open */
);
-typedef OM_uint32 _gss_wrap_size_limit_t
+typedef OM_uint32 GSSAPI_CALLCONV _gss_wrap_size_limit_t
(OM_uint32 *, /* minor_status */
const gss_ctx_id_t, /* context_handle */
int, /* conf_req_flag */
@@ -208,7 +208,7 @@ typedef OM_uint32 _gss_wrap_size_limit_t
OM_uint32 * /* max_input_size */
);
-typedef OM_uint32 _gss_add_cred_t (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_add_cred_t (
OM_uint32 *, /* minor_status */
const gss_cred_id_t, /* input_cred_handle */
const gss_name_t, /* desired_name */
@@ -222,7 +222,7 @@ typedef OM_uint32 _gss_add_cred_t (
OM_uint32 * /* acceptor_time_rec */
);
-typedef OM_uint32 _gss_inquire_cred_by_mech_t (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_cred_by_mech_t (
OM_uint32 *, /* minor_status */
const gss_cred_id_t, /* cred_handle */
const gss_OID, /* mech_type */
@@ -232,65 +232,65 @@ typedef OM_uint32 _gss_inquire_cred_by_mech_t (
gss_cred_usage_t * /* cred_usage */
);
-typedef OM_uint32 _gss_export_sec_context_t (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_export_sec_context_t (
OM_uint32 *, /* minor_status */
gss_ctx_id_t *, /* context_handle */
gss_buffer_t /* interprocess_token */
);
-typedef OM_uint32 _gss_import_sec_context_t (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_import_sec_context_t (
OM_uint32 *, /* minor_status */
const gss_buffer_t, /* interprocess_token */
gss_ctx_id_t * /* context_handle */
);
-typedef OM_uint32 _gss_inquire_names_for_mech_t (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_names_for_mech_t (
OM_uint32 *, /* minor_status */
const gss_OID, /* mechanism */
gss_OID_set * /* name_types */
);
-typedef OM_uint32 _gss_inquire_mechs_for_name_t (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_mechs_for_name_t (
OM_uint32 *, /* minor_status */
const gss_name_t, /* input_name */
gss_OID_set * /* mech_types */
);
-typedef OM_uint32 _gss_canonicalize_name_t (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_canonicalize_name_t (
OM_uint32 *, /* minor_status */
const gss_name_t, /* input_name */
const gss_OID, /* mech_type */
gss_name_t * /* output_name */
);
-typedef OM_uint32 _gss_duplicate_name_t (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_duplicate_name_t (
OM_uint32 *, /* minor_status */
const gss_name_t, /* src_name */
gss_name_t * /* dest_name */
);
-typedef OM_uint32 _gss_inquire_sec_context_by_oid (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_sec_context_by_oid (
OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_OID desired_object,
gss_buffer_set_t *data_set
);
-typedef OM_uint32 _gss_inquire_cred_by_oid (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_cred_by_oid (
OM_uint32 *minor_status,
const gss_cred_id_t cred,
const gss_OID desired_object,
gss_buffer_set_t *data_set
);
-typedef OM_uint32 _gss_set_sec_context_option (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_set_sec_context_option (
OM_uint32 *minor_status,
gss_ctx_id_t *cred_handle,
const gss_OID desired_object,
const gss_buffer_t value
);
-typedef OM_uint32 _gss_set_cred_option (
+typedef OM_uint32 GSSAPI_CALLCONV _gss_set_cred_option (
OM_uint32 *minor_status,
gss_cred_id_t *cred_handle,
const gss_OID desired_object,
@@ -298,7 +298,7 @@ typedef OM_uint32 _gss_set_cred_option (
);
-typedef OM_uint32 _gss_pseudo_random(
+typedef OM_uint32 GSSAPI_CALLCONV _gss_pseudo_random(
OM_uint32 *minor_status,
gss_ctx_id_t context,
int prf_key,
@@ -307,7 +307,7 @@ typedef OM_uint32 _gss_pseudo_random(
gss_buffer_t prf_out
);
-typedef OM_uint32
+typedef OM_uint32 GSSAPI_CALLCONV
_gss_wrap_iov_t(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -316,7 +316,7 @@ _gss_wrap_iov_t(OM_uint32 *minor_status,
gss_iov_buffer_desc *iov,
int iov_count);
-typedef OM_uint32
+typedef OM_uint32 GSSAPI_CALLCONV
_gss_unwrap_iov_t(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int *conf_state,
@@ -324,7 +324,7 @@ _gss_unwrap_iov_t(OM_uint32 *minor_status,
gss_iov_buffer_desc *iov,
int iov_count);
-typedef OM_uint32
+typedef OM_uint32 GSSAPI_CALLCONV
_gss_wrap_iov_length_t(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -333,7 +333,7 @@ _gss_wrap_iov_length_t(OM_uint32 * minor_status,
gss_iov_buffer_desc *iov,
int iov_count);
-typedef OM_uint32
+typedef OM_uint32 GSSAPI_CALLCONV
_gss_store_cred_t(OM_uint32 *minor_status,
gss_cred_id_t input_cred_handle,
gss_cred_usage_t cred_usage,
@@ -343,12 +343,12 @@ _gss_store_cred_t(OM_uint32 *minor_status,
gss_OID_set *elements_stored,
gss_cred_usage_t *cred_usage_stored);
-typedef OM_uint32
+typedef OM_uint32 GSSAPI_CALLCONV
_gss_export_cred_t(OM_uint32 *minor_status,
gss_cred_id_t cred_handle,
gss_buffer_t cred_token);
-typedef OM_uint32
+typedef OM_uint32 GSSAPI_CALLCONV
_gss_import_cred_t(OM_uint32 * minor_status,
gss_buffer_t cred_token,
gss_cred_id_t * cred_handle);
diff --git a/source4/heimdal/lib/gssapi/krb5/8003.c b/source4/heimdal/lib/gssapi/krb5/8003.c
index 2c53d67003..65db343cad 100644
--- a/source4/heimdal/lib/gssapi/krb5/8003.c
+++ b/source4/heimdal/lib/gssapi/krb5/8003.c
@@ -182,11 +182,6 @@ _gsskrb5_verify_8003_checksum(
int DlgOpt;
static unsigned char zeros[16];
- if (cksum == NULL) {
- *minor_status = 0;
- return GSS_S_BAD_BINDINGS;
- }
-
/* XXX should handle checksums > 24 bytes */
if(cksum->cksumtype != CKSUMTYPE_GSSAPI || cksum->checksum.length < 24) {
*minor_status = 0;
diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
index e3ba189b36..8ec3a65a31 100644
--- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
@@ -55,10 +55,10 @@ _gsskrb5_register_acceptor_identity (const char *identity)
if (identity == NULL) {
ret = krb5_kt_default(context, &_gsskrb5_keytab);
} else {
- char *p;
+ char *p = NULL;
- asprintf(&p, "FILE:%s", identity);
- if(p == NULL) {
+ ret = asprintf(&p, "FILE:%s", identity);
+ if(ret < 0 || p == NULL) {
HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
return GSS_S_FAILURE;
}
@@ -462,6 +462,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
/*
* We need to get the flags out of the 8003 checksum.
*/
+
{
krb5_authenticator authenticator;
@@ -474,6 +475,12 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
return ret;
}
+ if (authenticator->cksum == NULL) {
+ krb5_free_authenticator(context, &authenticator);
+ *minor_status = 0;
+ return GSS_S_BAD_BINDINGS;
+ }
+
if (authenticator->cksum->cksumtype == CKSUMTYPE_GSSAPI) {
ret = _gsskrb5_verify_8003_checksum(minor_status,
input_chan_bindings,
@@ -793,7 +800,7 @@ acceptor_wait_for_dcestyle(OM_uint32 * minor_status,
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_accept_sec_context(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
const gss_cred_id_t acceptor_cred_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
index 7e448dcfb2..584ce7711a 100644
--- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
@@ -288,7 +288,7 @@ end:
return (ret);
}
-OM_uint32 _gsskrb5_acquire_cred
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred
(OM_uint32 * minor_status,
const gss_name_t desired_name,
OM_uint32 time_req,
diff --git a/source4/heimdal/lib/gssapi/krb5/add_cred.c b/source4/heimdal/lib/gssapi/krb5/add_cred.c
index adc8a09fa4..a326613edd 100644
--- a/source4/heimdal/lib/gssapi/krb5/add_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/add_cred.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_add_cred (
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (
OM_uint32 *minor_status,
const gss_cred_id_t input_cred_handle,
const gss_name_t desired_name,
@@ -155,7 +155,7 @@ OM_uint32 _gsskrb5_add_cred (
if (cred->ccache) {
const char *type, *name;
- char *type_name;
+ char *type_name = NULL;
ret = GSS_S_FAILURE;
@@ -187,8 +187,8 @@ OM_uint32 _gsskrb5_add_cred (
goto failure;
}
- asprintf(&type_name, "%s:%s", type, name);
- if (type_name == NULL) {
+ kret = asprintf(&type_name, "%s:%s", type, name);
+ if (kret < 0 || type_name == NULL) {
*minor_status = ENOMEM;
goto failure;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c
index f1aee4bbbf..040cd3ee76 100644
--- a/source4/heimdal/lib/gssapi/krb5/aeap.c
+++ b/source4/heimdal/lib/gssapi/krb5/aeap.c
@@ -35,7 +35,7 @@
#include <roken.h>
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gk_wrap_iov(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -57,7 +57,7 @@ _gk_wrap_iov(OM_uint32 * minor_status,
return GSS_S_FAILURE;
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gk_unwrap_iov(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int *conf_state,
@@ -77,7 +77,7 @@ _gk_unwrap_iov(OM_uint32 *minor_status,
return GSS_S_FAILURE;
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gk_wrap_iov_length(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
diff --git a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
index 3de55d6e32..7fc921bac0 100644
--- a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_canonicalize_name (
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_canonicalize_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
const gss_OID mech_type,
diff --git a/source4/heimdal/lib/gssapi/krb5/compare_name.c b/source4/heimdal/lib/gssapi/krb5/compare_name.c
index f45e4df3e2..7409d45fcb 100644
--- a/source4/heimdal/lib/gssapi/krb5/compare_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/compare_name.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_compare_name
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_compare_name
(OM_uint32 * minor_status,
const gss_name_t name1,
const gss_name_t name2,
diff --git a/source4/heimdal/lib/gssapi/krb5/context_time.c b/source4/heimdal/lib/gssapi/krb5/context_time.c
index 987ceea4aa..7b27906b5b 100644
--- a/source4/heimdal/lib/gssapi/krb5/context_time.c
+++ b/source4/heimdal/lib/gssapi/krb5/context_time.c
@@ -62,7 +62,7 @@ _gsskrb5_lifetime_left(OM_uint32 *minor_status,
}
-OM_uint32 _gsskrb5_context_time
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_context_time
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
OM_uint32 * time_rec
diff --git a/source4/heimdal/lib/gssapi/krb5/creds.c b/source4/heimdal/lib/gssapi/krb5/creds.c
index fd40617040..d2c253e84b 100644
--- a/source4/heimdal/lib/gssapi/krb5/creds.c
+++ b/source4/heimdal/lib/gssapi/krb5/creds.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_export_cred(OM_uint32 *minor_status,
gss_cred_id_t cred_handle,
gss_buffer_t cred_token)
@@ -154,7 +154,7 @@ _gsskrb5_export_cred(OM_uint32 *minor_status,
return GSS_S_COMPLETE;
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_import_cred(OM_uint32 * minor_status,
gss_buffer_t cred_token,
gss_cred_id_t * cred_handle)
diff --git a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
index e02a4c6a9f..83a66cc0ca 100644
--- a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_delete_sec_context(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
gss_buffer_t output_token)
diff --git a/source4/heimdal/lib/gssapi/krb5/display_name.c b/source4/heimdal/lib/gssapi/krb5/display_name.c
index 6487d84880..a296399cec 100644
--- a/source4/heimdal/lib/gssapi/krb5/display_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/display_name.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_display_name
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_display_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
gss_buffer_t output_name_buffer,
diff --git a/source4/heimdal/lib/gssapi/krb5/display_status.c b/source4/heimdal/lib/gssapi/krb5/display_status.c
index f9d84fc762..c50200672a 100644
--- a/source4/heimdal/lib/gssapi/krb5/display_status.c
+++ b/source4/heimdal/lib/gssapi/krb5/display_status.c
@@ -125,20 +125,21 @@ _gsskrb5_set_status (int ret, const char *fmt, ...)
krb5_context context;
va_list args;
char *str;
+ int e;
if (_gsskrb5_init (&context) != 0)
return;
va_start(args, fmt);
- vasprintf(&str, fmt, args);
+ e = vasprintf(&str, fmt, args);
va_end(args);
- if (str) {
+ if (e >= 0 && str) {
krb5_set_error_message(context, ret, "%s", str);
free(str);
}
}
-OM_uint32 _gsskrb5_display_status
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_display_status
(OM_uint32 *minor_status,
OM_uint32 status_value,
int status_type,
@@ -147,7 +148,8 @@ OM_uint32 _gsskrb5_display_status
gss_buffer_t status_string)
{
krb5_context context;
- char *buf;
+ char *buf = NULL;
+ int e = 0;
GSSAPI_KRB5_INIT (&context);
@@ -162,27 +164,27 @@ OM_uint32 _gsskrb5_display_status
if (status_type == GSS_C_GSS_CODE) {
if (GSS_SUPPLEMENTARY_INFO(status_value))
- asprintf(&buf, "%s",
- supplementary_error(GSS_SUPPLEMENTARY_INFO(status_value)));
+ e = asprintf(&buf, "%s",
+ supplementary_error(GSS_SUPPLEMENTARY_INFO(status_value)));
else
- asprintf (&buf, "%s %s",
- calling_error(GSS_CALLING_ERROR(status_value)),
- routine_error(GSS_ROUTINE_ERROR(status_value)));
+ e = asprintf (&buf, "%s %s",
+ calling_error(GSS_CALLING_ERROR(status_value)),
+ routine_error(GSS_ROUTINE_ERROR(status_value)));
} else if (status_type == GSS_C_MECH_CODE) {
const char *buf2 = krb5_get_error_message(context, status_value);
if (buf2) {
buf = strdup(buf2);
krb5_free_error_message(context, buf2);
} else {
- asprintf(&buf, "unknown mech error-code %u",
- (unsigned)status_value);
+ e = asprintf(&buf, "unknown mech error-code %u",
+ (unsigned)status_value);
}
} else {
*minor_status = EINVAL;
return GSS_S_BAD_STATUS;
}
- if (buf == NULL) {
+ if (e < 0 || buf == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c
index b0188acd51..0bc57e8a03 100644
--- a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_duplicate_name (
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_duplicate_name (
OM_uint32 * minor_status,
const gss_name_t src_name,
gss_name_t * dest_name
diff --git a/source4/heimdal/lib/gssapi/krb5/export_name.c b/source4/heimdal/lib/gssapi/krb5/export_name.c
index 705bb70d91..32368d3cce 100644
--- a/source4/heimdal/lib/gssapi/krb5/export_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/export_name.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_export_name
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_export_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
gss_buffer_t exported_name
diff --git a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c
index 3d3870a6b4..eeb2743b43 100644
--- a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_export_sec_context (
OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c
index fd81f3ebeb..ef33c5575a 100644
--- a/source4/heimdal/lib/gssapi/krb5/external.c
+++ b/source4/heimdal/lib/gssapi/krb5/external.c
@@ -46,12 +46,9 @@
* to that gss_OID_desc.
*/
-static gss_OID_desc gss_c_nt_user_name_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_user_name_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x01")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_USER_NAME =
- &gss_c_nt_user_name_oid_desc;
-
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
@@ -64,12 +61,9 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_USER_NAME =
* initialized to point to that gss_OID_desc.
*/
-static gss_OID_desc gss_c_nt_machine_uid_name_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_machine_uid_name_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x02")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_MACHINE_UID_NAME =
- &gss_c_nt_machine_uid_name_oid_desc;
-
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
@@ -82,12 +76,9 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_MACHINE_UID_NAME =
* initialized to point to that gss_OID_desc.
*/
-static gss_OID_desc gss_c_nt_string_uid_name_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_string_uid_name_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x03")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_STRING_UID_NAME =
- &gss_c_nt_string_uid_name_oid_desc;
-
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
@@ -106,12 +97,9 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_STRING_UID_NAME =
* implementations
*/
-static gss_OID_desc gss_c_nt_hostbased_service_x_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_hostbased_service_x_oid_desc =
{6, rk_UNCONST("\x2b\x06\x01\x05\x06\x02")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_HOSTBASED_SERVICE_X =
- &gss_c_nt_hostbased_service_x_oid_desc;
-
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
@@ -123,12 +111,9 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_HOSTBASED_SERVICE_X =
* GSS_C_NT_HOSTBASED_SERVICE should be initialized
* to point to that gss_OID_desc.
*/
-static gss_OID_desc gss_c_nt_hostbased_service_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_hostbased_service_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12" "\x01\x02\x01\x04")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_HOSTBASED_SERVICE =
- &gss_c_nt_hostbased_service_oid_desc;
-
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
@@ -140,12 +125,9 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_HOSTBASED_SERVICE =
* to that gss_OID_desc.
*/
-static gss_OID_desc gss_c_nt_anonymous_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_anonymous_oid_desc =
{6, rk_UNCONST("\x2b\x06\01\x05\x06\x03")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_ANONYMOUS =
- &gss_c_nt_anonymous_oid_desc;
-
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
@@ -157,12 +139,9 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_ANONYMOUS =
* to that gss_OID_desc.
*/
-static gss_OID_desc gss_c_nt_export_name_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_nt_export_name_oid_desc =
{6, rk_UNCONST("\x2b\x06\x01\x05\x06\x04") };
-gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_EXPORT_NAME =
- &gss_c_nt_export_name_oid_desc;
-
/*
* This name form shall be represented by the Object Identifier {iso(1)
* member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
@@ -170,12 +149,9 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_C_NT_EXPORT_NAME =
* is "GSS_KRB5_NT_PRINCIPAL_NAME".
*/
-static gss_OID_desc gss_krb5_nt_principal_name_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_nt_principal_name_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01") };
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_PRINCIPAL_NAME =
- &gss_krb5_nt_principal_name_oid_desc;
-
/*
* This name form shall be represented by the Object Identifier {iso(1)
* member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
@@ -183,9 +159,6 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_PRINCIPAL_NAME =
* type is "GSS_KRB5_NT_USER_NAME".
*/
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_USER_NAME =
- &gss_c_nt_user_name_oid_desc;
-
/*
* This name form shall be represented by the Object Identifier {iso(1)
* member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
@@ -193,9 +166,6 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_USER_NAME =
* this type is "GSS_KRB5_NT_MACHINE_UID_NAME".
*/
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_MACHINE_UID_NAME =
- &gss_c_nt_machine_uid_name_oid_desc;
-
/*
* This name form shall be represented by the Object Identifier {iso(1)
* member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
@@ -203,9 +173,6 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_MACHINE_UID_NAME =
* this type is "GSS_KRB5_NT_STRING_UID_NAME".
*/
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_STRING_UID_NAME =
- &gss_c_nt_string_uid_name_oid_desc;
-
/*
* To support ongoing experimentation, testing, and evolution of the
* specification, the Kerberos V5 GSS-API mechanism as defined in this
@@ -223,19 +190,9 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_NT_STRING_UID_NAME =
* gssapi(2) krb5(2)}
*/
-#if 0 /* This is the old OID */
-
-static gss_OID_desc gss_krb5_mechanism_oid_desc =
- {5, rk_UNCONST("\x2b\x05\x01\x05\x02")};
-
-#endif
-
-static gss_OID_desc gss_krb5_mechanism_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_mechanism_oid_desc =
{9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") };
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_MECHANISM =
- &gss_krb5_mechanism_oid_desc;
-
/*
* draft-ietf-cat-iakerb-09, IAKERB:
* The mechanism ID for IAKERB proxy GSS-API Kerberos, in accordance
@@ -249,179 +206,107 @@ gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_MECHANISM =
* iakerbMinimumMessagesProtocol(2)}.
*/
-static gss_OID_desc gss_iakerb_proxy_mechanism_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_iakerb_proxy_mechanism_oid_desc =
{7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x01")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_IAKERB_PROXY_MECHANISM =
- &gss_iakerb_proxy_mechanism_oid_desc;
-
-static gss_OID_desc gss_iakerb_min_msg_mechanism_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_iakerb_min_msg_mechanism_oid_desc =
{7, rk_UNCONST("\x2b\x06\x01\x05\x05\x0a\x02") };
-gss_OID GSSAPI_LIB_VARIABLE GSS_IAKERB_MIN_MSG_MECHANISM =
- &gss_iakerb_min_msg_mechanism_oid_desc;
-
/*
*
*/
-static gss_OID_desc gss_c_peer_has_updated_spnego_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_peer_has_updated_spnego_oid_desc =
{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05"};
-gss_OID GSSAPI_LIB_VARIABLE GSS_C_PEER_HAS_UPDATED_SPNEGO =
- &gss_c_peer_has_updated_spnego_oid_desc;
-
/*
* 1.2.752.43.13 Heimdal GSS-API Extentions
*/
/* 1.2.752.43.13.1 */
-static gss_OID_desc gss_krb5_copy_ccache_x_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_copy_ccache_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x01")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_COPY_CCACHE_X =
- &gss_krb5_copy_ccache_x_oid_desc;
-
/* 1.2.752.43.13.2 */
-static gss_OID_desc gss_krb5_get_tkt_flags_x_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_tkt_flags_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x02")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_TKT_FLAGS_X =
- &gss_krb5_get_tkt_flags_x_oid_desc;
-
/* 1.2.752.43.13.3 */
-static gss_OID_desc gss_krb5_extract_authz_data_from_sec_context_x_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_extract_authz_data_from_sec_context_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x03")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X =
- &gss_krb5_extract_authz_data_from_sec_context_x_oid_desc;
-
/* 1.2.752.43.13.4 */
-static gss_OID_desc gss_krb5_compat_des3_mic_x_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_compat_des3_mic_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x04")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_COMPAT_DES3_MIC_X =
- &gss_krb5_compat_des3_mic_x_oid_desc;
-
/* 1.2.752.43.13.5 */
-static gss_OID_desc gss_krb5_register_acceptor_identity_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_register_acceptor_identity_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x05")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X =
- &gss_krb5_register_acceptor_identity_x_desc;
-
/* 1.2.752.43.13.6 */
-static gss_OID_desc gss_krb5_export_lucid_context_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_export_lucid_context_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_EXPORT_LUCID_CONTEXT_X =
- &gss_krb5_export_lucid_context_x_desc;
-
/* 1.2.752.43.13.6.1 */
-static gss_OID_desc gss_krb5_export_lucid_context_v1_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_export_lucid_context_v1_x_oid_desc =
{7, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x06\x01")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X =
- &gss_krb5_export_lucid_context_v1_x_desc;
-
/* 1.2.752.43.13.7 */
-static gss_OID_desc gss_krb5_set_dns_canonicalize_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_dns_canonicalize_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x07")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_DNS_CANONICALIZE_X =
- &gss_krb5_set_dns_canonicalize_x_desc;
-
/* 1.2.752.43.13.8 */
-static gss_OID_desc gss_krb5_get_subkey_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_subkey_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x08")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_SUBKEY_X =
- &gss_krb5_get_subkey_x_desc;
-
/* 1.2.752.43.13.9 */
-static gss_OID_desc gss_krb5_get_initiator_subkey_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_initiator_subkey_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x09")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_INITIATOR_SUBKEY_X =
- &gss_krb5_get_initiator_subkey_x_desc;
-
/* 1.2.752.43.13.10 */
-static gss_OID_desc gss_krb5_get_acceptor_subkey_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_acceptor_subkey_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0a")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_ACCEPTOR_SUBKEY_X =
- &gss_krb5_get_acceptor_subkey_x_desc;
-
/* 1.2.752.43.13.11 */
-static gss_OID_desc gss_krb5_send_to_kdc_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_send_to_kdc_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0b")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SEND_TO_KDC_X =
- &gss_krb5_send_to_kdc_x_desc;
-
/* 1.2.752.43.13.12 */
-static gss_OID_desc gss_krb5_get_authtime_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_authtime_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0c")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_AUTHTIME_X =
- &gss_krb5_get_authtime_x_desc;
-
/* 1.2.752.43.13.13 */
-static gss_OID_desc gss_krb5_get_service_keyblock_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_service_keyblock_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0d")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_SERVICE_KEYBLOCK_X =
- &gss_krb5_get_service_keyblock_x_desc;
-
/* 1.2.752.43.13.14 */
-static gss_OID_desc gss_krb5_set_allowable_enctypes_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_allowable_enctypes_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0e")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X =
- &gss_krb5_set_allowable_enctypes_x_desc;
-
/* 1.2.752.43.13.15 */
-static gss_OID_desc gss_krb5_set_default_realm_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_default_realm_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x0f")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_DEFAULT_REALM_X =
- &gss_krb5_set_default_realm_x_desc;
-
/* 1.2.752.43.13.16 */
-static gss_OID_desc gss_krb5_ccache_name_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_ccache_name_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x10")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_CCACHE_NAME_X =
- &gss_krb5_ccache_name_x_desc;
-
/* 1.2.752.43.13.17 */
-static gss_OID_desc gss_krb5_set_time_offset_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_set_time_offset_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_SET_TIME_OFFSET_X =
- &gss_krb5_set_time_offset_x_desc;
-
/* 1.2.752.43.13.18 */
-static gss_OID_desc gss_krb5_get_time_offset_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_get_time_offset_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_GET_TIME_OFFSET_X =
- &gss_krb5_get_time_offset_x_desc;
-
/* 1.2.752.43.13.19 */
-static gss_OID_desc gss_krb5_plugin_register_x_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_plugin_register_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x13")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_KRB5_PLUGIN_REGISTER_X =
- &gss_krb5_plugin_register_x_desc;
-
/* 1.2.752.43.14.1 */
-static gss_OID_desc gss_sasl_digest_md5_mechanism_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_sasl_digest_md5_mechanism_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x01") };
-gss_OID GSSAPI_LIB_VARIABLE GSS_SASL_DIGEST_MD5_MECHANISM =
- &gss_sasl_digest_md5_mechanism_desc;
-
/*
* Context for krb5 calls.
*/
diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c
index f3f7fff8ae..0109ca7c6e 100644
--- a/source4/heimdal/lib/gssapi/krb5/get_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c
@@ -273,7 +273,7 @@ mic_des3
return GSS_S_COMPLETE;
}
-OM_uint32 _gsskrb5_get_mic
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
diff --git a/source4/heimdal/lib/gssapi/krb5/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c
index f1aca93ffd..2a071a305e 100644
--- a/source4/heimdal/lib/gssapi/krb5/import_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/import_name.c
@@ -215,7 +215,7 @@ import_export_name (OM_uint32 *minor_status,
return ret;
}
-OM_uint32 _gsskrb5_import_name
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_import_name
(OM_uint32 * minor_status,
const gss_buffer_t input_name_buffer,
const gss_OID input_name_type,
@@ -235,7 +235,7 @@ OM_uint32 _gsskrb5_import_name
context,
input_name_buffer,
output_name);
- else if (gss_oid_equal(input_name_type, GSS_C_NO_OID)
+ else if (input_name_type == GSS_C_NO_OID
|| gss_oid_equal(input_name_type, GSS_C_NT_USER_NAME)
|| gss_oid_equal(input_name_type, GSS_KRB5_NT_PRINCIPAL_NAME))
/* default printable syntax */
diff --git a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c
index 2af942338f..c873da9ba9 100644
--- a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_import_sec_context (
OM_uint32 * minor_status,
const gss_buffer_t interprocess_token,
diff --git a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
index b1d18bd244..620137884a 100644
--- a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
+++ b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_indicate_mechs
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_indicate_mechs
(OM_uint32 * minor_status,
gss_OID_set * mech_set
)
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
index b513bd2d65..f4e103a7a5 100644
--- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -838,7 +838,7 @@ repl_mutual
* gss_init_sec_context
*/
-OM_uint32 _gsskrb5_init_sec_context
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_init_sec_context
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
gss_ctx_id_t * context_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_context.c b/source4/heimdal/lib/gssapi/krb5/inquire_context.c
index 381ffc9e6f..ade8ec4b9c 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_context.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_inquire_context (
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_context (
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_name_t * src_name,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c
index 518736d78e..d3798623ff 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_inquire_cred
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
gss_name_t * output_name,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
index 9da1ac43f1..7bd9c11c60 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_inquire_cred_by_mech (
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_mech (
OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
const gss_OID mech_type,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
index f32342f1d8..d560ed4ba1 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
@@ -32,7 +32,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_inquire_cred_by_oid
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_oid
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
const gss_OID desired_object,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
index 5fa3c302a2..6197a81b40 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_inquire_mechs_for_name (
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_mechs_for_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
gss_OID_set * mech_types
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
index 591343307e..dc02b99851 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
@@ -33,15 +33,15 @@
#include "gsskrb5_locl.h"
-static gss_OID *name_list[] = {
- &GSS_C_NT_HOSTBASED_SERVICE,
- &GSS_C_NT_USER_NAME,
- &GSS_KRB5_NT_PRINCIPAL_NAME,
- &GSS_C_NT_EXPORT_NAME,
+static gss_OID name_list[] = {
+ GSS_C_NT_HOSTBASED_SERVICE,
+ GSS_C_NT_USER_NAME,
+ GSS_KRB5_NT_PRINCIPAL_NAME,
+ GSS_C_NT_EXPORT_NAME,
NULL
};
-OM_uint32 _gsskrb5_inquire_names_for_mech (
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_names_for_mech (
OM_uint32 * minor_status,
const gss_OID mechanism,
gss_OID_set * name_types
@@ -64,7 +64,7 @@ OM_uint32 _gsskrb5_inquire_names_for_mech (
for (i = 0; name_list[i] != NULL; i++) {
ret = gss_add_oid_set_member(minor_status,
- *(name_list[i]),
+ name_list[i],
name_types);
if (ret != GSS_S_COMPLETE)
break;
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
index e0b5553928..14816e7a05 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
@@ -487,7 +487,7 @@ out:
*
*/
-OM_uint32 _gsskrb5_inquire_sec_context_by_oid
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_sec_context_by_oid
(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_OID desired_object,
diff --git a/source4/heimdal/lib/gssapi/krb5/prf.c b/source4/heimdal/lib/gssapi/krb5/prf.c
index 737ccb6834..323b4cc722 100644
--- a/source4/heimdal/lib/gssapi/krb5/prf.c
+++ b/source4/heimdal/lib/gssapi/krb5/prf.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_pseudo_random(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int prf_key,
diff --git a/source4/heimdal/lib/gssapi/krb5/process_context_token.c b/source4/heimdal/lib/gssapi/krb5/process_context_token.c
index 1c9d44588f..4feda0de04 100644
--- a/source4/heimdal/lib/gssapi/krb5/process_context_token.c
+++ b/source4/heimdal/lib/gssapi/krb5/process_context_token.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_process_context_token (
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_process_context_token (
OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t token_buffer
diff --git a/source4/heimdal/lib/gssapi/krb5/release_cred.c b/source4/heimdal/lib/gssapi/krb5/release_cred.c
index 5eec3c48cb..105a7a6eb2 100644
--- a/source4/heimdal/lib/gssapi/krb5/release_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/release_cred.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_release_cred
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_release_cred
(OM_uint32 * minor_status,
gss_cred_id_t * cred_handle
)
diff --git a/source4/heimdal/lib/gssapi/krb5/release_name.c b/source4/heimdal/lib/gssapi/krb5/release_name.c
index 0fafc275d0..57fc8a4e45 100644
--- a/source4/heimdal/lib/gssapi/krb5/release_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/release_name.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32 _gsskrb5_release_name
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_release_name
(OM_uint32 * minor_status,
gss_name_t * input_name
)
diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
index ee29bf8c66..d6255bacb5 100644
--- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
+++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
@@ -33,18 +33,13 @@
#include "gsskrb5_locl.h"
/* 1.2.752.43.13.17 */
-static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_no_ci_flags_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
-gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X = &gss_krb5_cred_no_ci_flags_x_oid_desc;
-
/* 1.2.752.43.13.18 */
-static gss_OID_desc gss_krb5_import_cred_x_oid_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_cred_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12")};
-gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc;
-
-
static OM_uint32
import_cred(OM_uint32 *minor_status,
@@ -230,7 +225,7 @@ no_ci_flags(OM_uint32 *minor_status,
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_set_cred_option
(OM_uint32 *minor_status,
gss_cred_id_t *cred_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
index 096e835045..237af1a52c 100644
--- a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
+++ b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
@@ -98,7 +98,7 @@ set_int32(OM_uint32 *minor_status,
return GSS_S_COMPLETE;
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_set_sec_context_option
(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/store_cred.c b/source4/heimdal/lib/gssapi/krb5/store_cred.c
index 675a1d8e95..21f9f6e8ab 100644
--- a/source4/heimdal/lib/gssapi/krb5/store_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/store_cred.c
@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_store_cred(OM_uint32 *minor_status,
gss_cred_id_t input_cred_handle,
gss_cred_usage_t cred_usage,
diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c
index 5e0042e28b..7620d691bd 100644
--- a/source4/heimdal/lib/gssapi/krb5/unwrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c
@@ -379,7 +379,7 @@ unwrap_des3
return GSS_S_COMPLETE;
}
-OM_uint32 _gsskrb5_unwrap
+OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
index 0b5b6e1ccd..9a5445698b 100644
--- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
@@ -327,7 +327,7 @@ _gsskrb5_verify_mic_internal
return ret;
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_verify_mic
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c
index 9078fb3dd7..54f92df609 100644
--- a/source4/heimdal/lib/gssapi/krb5/wrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/wrap.c
@@ -134,7 +134,7 @@ sub_wrap_size (
return GSS_S_COMPLETE;
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gsskrb5_wrap_size_limit (
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
@@ -524,7 +524,8 @@ wrap_des3
return GSS_S_COMPLETE;
}
-OM_uint32 _gsskrb5_wrap
+OM_uint32 GSSAPI_CALLCONV
+_gsskrb5_wrap
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
index 5775db837b..19f3bc4bf8 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
@@ -141,7 +141,8 @@ choose_mech(const gss_buffer_t input, gss_OID mech_oid)
}
-OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_accept_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
const gss_cred_id_t acceptor_cred_handle,
const gss_buffer_t input_token,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
index 75a7978d89..416407a7bf 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_acquire_cred(OM_uint32 *minor_status,
const gss_name_t desired_name,
OM_uint32 time_req,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c
index 08c7882784..56fb8ec6a9 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_add_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_add_cred.c
@@ -70,7 +70,7 @@ _gss_copy_cred(struct _gss_mechanism_cred *mc)
return (new_mc);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_add_cred(OM_uint32 *minor_status,
const gss_cred_id_t input_cred_handle,
const gss_name_t desired_name,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
index b866125291..191a4a305c 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_add_oid_set_member.c
@@ -51,7 +51,7 @@
* @ingroup gssapi
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_add_oid_set_member (OM_uint32 * minor_status,
const gss_OID member_oid,
gss_OID_set * oid_set)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_aeap.c b/source4/heimdal/lib/gssapi/mech/gss_aeap.c
index ee0113d6d3..e98ba970d1 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_aeap.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_aeap.c
@@ -43,7 +43,7 @@
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_wrap_iov(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -81,7 +81,7 @@ gss_wrap_iov(OM_uint32 * minor_status,
* @ingroup gssapi
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_unwrap_iov(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int *conf_state,
@@ -124,7 +124,7 @@ gss_unwrap_iov(OM_uint32 *minor_status,
* @ingroup gssapi
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_wrap_iov_length(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -162,7 +162,7 @@ gss_wrap_iov_length(OM_uint32 * minor_status,
* @ingroup gssapi
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_iov_buffer(OM_uint32 *minor_status,
gss_iov_buffer_desc *iov,
int iov_count)
@@ -194,13 +194,10 @@ gss_release_iov_buffer(OM_uint32 *minor_status,
* @ingroup gssapi
*/
-static gss_OID_desc gss_c_attr_stream_sizes_desc =
+gss_OID_desc GSSAPI_LIB_FUNCTION __gss_c_attr_stream_sizes_oid_desc =
{10, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")};
-gss_OID GSSAPI_LIB_VARIABLE GSS_C_ATTR_STREAM_SIZES =
- &gss_c_attr_stream_sizes_desc;
-
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_context_query_attributes(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_OID attribute,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c
index 58863c3112..3099b163b5 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_buffer_set.c
@@ -32,7 +32,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_create_empty_buffer_set
(OM_uint32 * minor_status,
gss_buffer_set_t *buffer_set)
@@ -54,7 +54,7 @@ gss_create_empty_buffer_set
return GSS_S_COMPLETE;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_add_buffer_set_member
(OM_uint32 * minor_status,
const gss_buffer_t member_buffer,
@@ -96,7 +96,7 @@ gss_add_buffer_set_member
return GSS_S_COMPLETE;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_buffer_set(OM_uint32 * minor_status,
gss_buffer_set_t *buffer_set)
{
diff --git a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
index 1bb94b3468..fba35c5379 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_canonicalize_name.c
@@ -52,7 +52,7 @@
* @ingroup gssapi
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_canonicalize_name(OM_uint32 *minor_status,
const gss_name_t input_name,
const gss_OID mech_type,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c
index 9481218de2..14593f6def 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_compare_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_compare_name.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_compare_name(OM_uint32 *minor_status,
const gss_name_t name1_arg,
const gss_name_t name2_arg,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_context_time.c b/source4/heimdal/lib/gssapi/mech/gss_context_time.c
index d99f71f77a..69434ee898 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_context_time.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_context_time.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_context_time(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
OM_uint32 *time_rec)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
index 36337a5435..8d880f5511 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_create_empty_oid_set.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_create_empty_oid_set(OM_uint32 *minor_status,
gss_OID_set *oid_set)
{
diff --git a/source4/heimdal/lib/gssapi/mech/gss_cred.c b/source4/heimdal/lib/gssapi/mech/gss_cred.c
index 66df50b55e..b52015b6de 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_cred.c
@@ -42,7 +42,7 @@
* cred-data char * (not alligned)
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_export_cred(OM_uint32 * minor_status,
gss_cred_id_t cred_handle,
gss_buffer_t token)
@@ -107,7 +107,7 @@ gss_export_cred(OM_uint32 * minor_status,
return GSS_S_COMPLETE;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_import_cred(OM_uint32 * minor_status,
gss_buffer_t token,
gss_cred_id_t * cred_handle)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
index 95a6c68445..0fe3b4f5a5 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c
@@ -33,7 +33,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_decapsulate_token(const gss_buffer_t input_token,
const gss_OID oid,
gss_buffer_t output_token)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
index c2575927c3..ce57a76682 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_delete_sec_context.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_delete_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
gss_buffer_t output_token)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_name.c b/source4/heimdal/lib/gssapi/mech/gss_display_name.c
index 0b75592246..599e79861a 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_display_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_display_name.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_display_name(OM_uint32 *minor_status,
const gss_name_t input_name,
gss_buffer_t output_name_buffer,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_display_status.c b/source4/heimdal/lib/gssapi/mech/gss_display_status.c
index 60c5b8f523..d6aaf98827 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_display_status.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_display_status.c
@@ -135,7 +135,7 @@ supplementary_error(OM_uint32 v)
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_display_status(OM_uint32 *minor_status,
OM_uint32 status_value,
int status_type,
@@ -160,17 +160,18 @@ gss_display_status(OM_uint32 *minor_status,
*minor_status = 0;
switch (status_type) {
case GSS_C_GSS_CODE: {
- char *buf;
+ char *buf = NULL;
+ int e;
if (GSS_SUPPLEMENTARY_INFO(status_value))
- asprintf(&buf, "%s", supplementary_error(
+ e = asprintf(&buf, "%s", supplementary_error(
GSS_SUPPLEMENTARY_INFO(status_value)));
else
- asprintf (&buf, "%s %s",
+ e = asprintf (&buf, "%s %s",
calling_error(GSS_CALLING_ERROR(status_value)),
routine_error(GSS_ROUTINE_ERROR(status_value)));
- if (buf == NULL)
+ if (e < 0 || buf == NULL)
break;
status_string->length = strlen(buf);
@@ -181,21 +182,22 @@ gss_display_status(OM_uint32 *minor_status,
case GSS_C_MECH_CODE: {
OM_uint32 maj_junk, min_junk;
gss_buffer_desc oid;
- char *buf;
+ char *buf = NULL;
+ int e;
maj_junk = gss_oid_to_str(&min_junk, mech_type, &oid);
if (maj_junk != GSS_S_COMPLETE) {
oid.value = rk_UNCONST("unknown");
oid.length = 7;
}
-
- asprintf (&buf, "unknown mech-code %lu for mech %.*s",
+
+ e = asprintf (&buf, "unknown mech-code %lu for mech %.*s",
(unsigned long)status_value,
(int)oid.length, (char *)oid.value);
if (maj_junk == GSS_S_COMPLETE)
gss_release_buffer(&min_junk, &oid);
- if (buf == NULL)
+ if (e < 0 || buf == NULL)
break;
status_string->length = strlen(buf);
diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c
index 87775878ef..3d3a56802f 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_name.c
@@ -28,7 +28,8 @@
#include "mech_locl.h"
-OM_uint32 gss_duplicate_name(OM_uint32 *minor_status,
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_duplicate_name(OM_uint32 *minor_status,
const gss_name_t src_name,
gss_name_t *dest_name)
{
diff --git a/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
index 165b07e5ae..10a2000486 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_duplicate_oid.c
@@ -33,7 +33,8 @@
#include "mech_locl.h"
-OM_uint32 gss_duplicate_oid (
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_duplicate_oid (
OM_uint32 *minor_status,
gss_OID src_oid,
gss_OID *dest_oid
diff --git a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
index 7a3e165364..fc0ec736bb 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c
@@ -33,7 +33,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_encapsulate_token(const gss_buffer_t input_token,
const gss_OID oid,
gss_buffer_t output_token)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_name.c b/source4/heimdal/lib/gssapi/mech/gss_export_name.c
index 7f7c1afe68..6bc5ee8d1c 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_export_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_export_name.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_export_name(OM_uint32 *minor_status,
const gss_name_t input_name,
gss_buffer_t exported_name)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c
index 0fc19e2af7..babc8ebdf4 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_export_sec_context.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_export_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
gss_buffer_t interprocess_token)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c
index f4921b60db..6eebfe0bbb 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_get_mic.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_get_mic.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_get_mic(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_name.c b/source4/heimdal/lib/gssapi/mech/gss_import_name.c
index 6ae2302abd..90dc0c1e94 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_import_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_import_name.c
@@ -163,7 +163,7 @@ _gss_import_export_name(OM_uint32 *minor_status,
* @ingroup gssapi
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_import_name(OM_uint32 *minor_status,
const gss_buffer_t input_name_buffer,
const gss_OID input_name_type,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c
index e08d3b7af4..2a376fefea 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_import_sec_context.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_import_sec_context(OM_uint32 *minor_status,
const gss_buffer_t interprocess_token,
gss_ctx_id_t *context_handle)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
index ab95a18ee6..8560bc7c41 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_indicate_mechs.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_indicate_mechs(OM_uint32 *minor_status,
gss_OID_set *mech_set)
{
diff --git a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
index 1bcc639345..5da035d15a 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c
@@ -55,6 +55,10 @@ _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
*
* @param minor_status minor status code.
*
+ * @param initiator_cred_handle the credential to use when building
+ * the context, if GSS_C_NO_CREDENTIAL is passed, the default
+ * credential for the mechanism will be used.
+ *
* @param context_handle a pointer to a context handle, will be
* returned as long as there is not an error.
*
@@ -69,7 +73,7 @@ _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
* section.
*
* @param req_flags flags using when building the context, see @ref
- * gssapi_context_ flags
+ * gssapi_context_flags
*
* @param time_req time requested this context should be valid in
* seconds, common used value is GSS_C_INDEFINITE
@@ -101,7 +105,7 @@ _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_init_sec_context(OM_uint32 * minor_status,
const gss_cred_id_t initiator_cred_handle,
gss_ctx_id_t * context_handle,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c
index e000af00ef..0658267b2f 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_context.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_context(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
gss_name_t *src_name,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c
index e5faf58764..50d9c0b8da 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred.c
@@ -42,7 +42,7 @@ updateusage(gss_cred_usage_t usage, int *usagemask)
*usagemask |= IUSAGE;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_cred(OM_uint32 *minor_status,
const gss_cred_id_t cred_handle,
gss_name_t *name_ret,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
index 39c5e711b7..f71bd6993f 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_mech.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_cred_by_mech(OM_uint32 *minor_status,
const gss_cred_id_t cred_handle,
const gss_OID mech_type,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
index 3b821ce823..72d3048039 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_cred_by_oid.c
@@ -32,7 +32,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_cred_by_oid (OM_uint32 *minor_status,
const gss_cred_id_t cred_handle,
const gss_OID desired_object,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
index f0e23e664a..1ad7b58dbb 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_mechs_for_name.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_mechs_for_name(OM_uint32 *minor_status,
const gss_name_t input_name,
gss_OID_set *mech_types)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
index c796f05227..595ab737f9 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_names_for_mech.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_names_for_mech(OM_uint32 *minor_status,
const gss_OID mechanism,
gss_OID_set *name_types)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
index ffa0c44fa3..cc6e5c9cb6 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_inquire_sec_context_by_oid.c
@@ -32,7 +32,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_OID desired_object,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_krb5.c b/source4/heimdal/lib/gssapi/mech/gss_krb5.c
index 1611d91d02..f4290a2a5a 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_krb5.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_krb5.c
@@ -32,7 +32,7 @@
#include <roken.h>
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_copy_ccache(OM_uint32 *minor_status,
gss_cred_id_t cred,
krb5_ccache out)
@@ -42,7 +42,7 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status,
krb5_error_code kret;
krb5_ccache id;
OM_uint32 ret;
- char *str;
+ char *str = NULL;
ret = gss_inquire_cred_by_oid(minor_status,
cred,
@@ -67,7 +67,7 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status,
kret = asprintf(&str, "%.*s", (int)data_set->elements[0].length,
(char *)data_set->elements[0].value);
gss_release_buffer_set(minor_status, &data_set);
- if (kret == -1) {
+ if (kret < 0 || str == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
@@ -90,7 +90,7 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status,
return ret;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_import_cred(OM_uint32 *minor_status,
krb5_ccache id,
krb5_principal keytab_principal,
@@ -185,7 +185,7 @@ out:
return major_status;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_register_acceptor_identity(const char *identity)
{
struct _gss_mech_switch *m;
@@ -207,14 +207,14 @@ gsskrb5_register_acceptor_identity(const char *identity)
return (GSS_S_COMPLETE);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
krb5_gss_register_acceptor_identity(const char *identity)
{
return gsskrb5_register_acceptor_identity(identity);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_set_dns_canonicalize(int flag)
{
struct _gss_mech_switch *m;
@@ -259,7 +259,7 @@ free_key(gss_krb5_lucid_key_t *key)
memset(key, 0, sizeof(*key));
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
OM_uint32 version,
@@ -402,7 +402,7 @@ out:
return GSS_S_COMPLETE;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c)
{
gss_krb5_lucid_context_v1_t *ctx = c;
@@ -430,7 +430,7 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *c)
*
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status,
gss_cred_id_t cred,
OM_uint32 num_enctypes,
@@ -484,7 +484,7 @@ out:
*
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c)
{
struct _gss_mech_switch *m;
@@ -515,7 +515,7 @@ gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc *c)
*
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_ccache_name(OM_uint32 *minor_status,
const char *name,
const char **out_name)
@@ -547,7 +547,7 @@ gss_krb5_ccache_name(OM_uint32 *minor_status,
*
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
time_t *authtime)
@@ -602,7 +602,7 @@ gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,
*
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int ad_type,
@@ -775,7 +775,7 @@ out:
*
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
krb5_keyblock **keyblock)
@@ -786,7 +786,7 @@ gsskrb5_extract_service_keyblock(OM_uint32 *minor_status,
keyblock);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
krb5_keyblock **keyblock)
@@ -797,7 +797,7 @@ gsskrb5_get_initiator_subkey(OM_uint32 *minor_status,
keyblock);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_get_subkey(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
krb5_keyblock **keyblock)
@@ -808,7 +808,7 @@ gsskrb5_get_subkey(OM_uint32 *minor_status,
keyblock);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_set_default_realm(const char *realm)
{
struct _gss_mech_switch *m;
@@ -830,7 +830,7 @@ gsskrb5_set_default_realm(const char *realm)
return (GSS_S_COMPLETE);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
OM_uint32 *tkt_flags)
@@ -869,7 +869,7 @@ gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
return GSS_S_COMPLETE;
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_set_time_offset(int offset)
{
struct _gss_mech_switch *m;
@@ -892,7 +892,7 @@ gsskrb5_set_time_offset(int offset)
return (GSS_S_COMPLETE);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_get_time_offset(int *offset)
{
struct _gss_mech_switch *m;
@@ -920,7 +920,7 @@ gsskrb5_get_time_offset(int *offset)
return (GSS_S_UNAVAILABLE);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gsskrb5_plugin_register(struct gsskrb5_krb5_plugin *c)
{
struct _gss_mech_switch *m;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c
index 93ee6b2a2d..3e64135089 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_oid_equal.c
@@ -33,10 +33,24 @@
#include "mech_locl.h"
-int GSSAPI_LIB_FUNCTION
+/**
+ * Compare two GSS-API OIDs with each other.
+ *
+ * GSS_C_NO_OID matches nothing, not even it-self.
+ *
+ * @param a first oid to compare
+ * @param b second oid to compare
+ *
+ * @return non-zero when both oid are the same OID, zero when they are
+ * not the same.
+ *
+ * @ingroup gssapi
+ */
+
+GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL
gss_oid_equal(const gss_OID a, const gss_OID b)
{
- if (a == b)
+ if (a == b && a != GSS_C_NO_OID)
return 1;
if (a == GSS_C_NO_OID || b == GSS_C_NO_OID || a->length != b->length)
return 0;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c b/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c
index 114e7d63e4..d8e188da08 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_oid_to_str.c
@@ -33,7 +33,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str)
{
int ret;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c
index 738ff7d8e2..e8e9b56cdc 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_process_context_token.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_process_context_token(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t token_buffer)
diff --git a/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c b/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c
index 96b40a6af6..ce4f9a4136 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_pseudo_random.c
@@ -35,7 +35,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_pseudo_random(OM_uint32 *minor_status,
gss_ctx_id_t context,
int prf_key,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c
index 9aad034ab2..c3dd4575b6 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_buffer.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_buffer(OM_uint32 *minor_status,
gss_buffer_t buffer)
{
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c
index 463fddb2ba..591ef49ab2 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_cred.c
@@ -50,7 +50,7 @@
* @ingroup gssapi
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
{
struct _gss_cred *cred = (struct _gss_cred *) *cred_handle;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
index 47786725ac..28fb75d966 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_name.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c
@@ -43,7 +43,7 @@
*
* @ingroup gssapi
*/
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_name(OM_uint32 *minor_status,
gss_name_t *input_name)
{
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c
index 458e94d711..610daf229c 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_oid.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid.c
@@ -34,7 +34,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_oid(OM_uint32 *minor_status, gss_OID *oid)
{
gss_OID o = *oid;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
index f875d39d0c..183ddf8c75 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_release_oid_set.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_release_oid_set(OM_uint32 *minor_status,
gss_OID_set *set)
{
diff --git a/source4/heimdal/lib/gssapi/mech/gss_seal.c b/source4/heimdal/lib/gssapi/mech/gss_seal.c
index 8c1e9eba1c..26c65dafc9 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_seal.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_seal.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_seal(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c
index 86a136159e..adae7a622e 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_set_cred_option.c
@@ -32,7 +32,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_set_cred_option (OM_uint32 *minor_status,
gss_cred_id_t *cred_handle,
const gss_OID object,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
index ca0ec00ef7..6efe1a0b17 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_set_sec_context_option.c
@@ -32,7 +32,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_set_sec_context_option (OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
const gss_OID object,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_sign.c b/source4/heimdal/lib/gssapi/mech/gss_sign.c
index 8a1b1e363f..4ef99c1987 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_sign.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_sign.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_sign(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int qop_req,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
index 7995f4df00..4c4d349045 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_test_oid_set_member.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_test_oid_set_member(OM_uint32 *minor_status,
const gss_OID member,
const gss_OID_set set,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_unseal.c b/source4/heimdal/lib/gssapi/mech/gss_unseal.c
index 8815790575..0add03d4dd 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_unseal.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_unseal.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_unseal(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
gss_buffer_t input_message_buffer,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_unwrap.c b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c
index 7285e46598..d0d18aca25 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_unwrap.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_unwrap.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_unwrap(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify.c b/source4/heimdal/lib/gssapi/mech/gss_verify.c
index e60d6507be..dd53ddbae9 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_verify.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_verify.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_verify(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
gss_buffer_t message_buffer,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c
index c535e3ffce..a791dc7327 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_verify_mic.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_verify_mic(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap.c b/source4/heimdal/lib/gssapi/mech/gss_wrap.c
index fb8a17bbe6..dcbb4fcdfe 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_wrap.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_wrap.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_wrap(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
diff --git a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
index 49af364668..e79814aea7 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_wrap_size_limit.c
@@ -28,7 +28,7 @@
#include "mech_locl.h"
-OM_uint32 GSSAPI_LIB_FUNCTION
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_wrap_size_limit(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
index ab8a4d1aac..35bc56fbb7 100644
--- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
@@ -372,7 +372,11 @@ select_mech(OM_uint32 *minor_status, MechType *mechType, int verify_p,
*minor_status = errno;
return GSS_S_FAILURE;
}
- asprintf(&str, "host@%s", hostname);
+ i = asprintf(&str, "host@%s", hostname);
+ if (i < 0 || str == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
host = str;
}
@@ -468,7 +472,7 @@ acceptor_complete(OM_uint32 * minor_status,
}
-static OM_uint32
+static OM_uint32 GSSAPI_CALLCONV
acceptor_start
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
@@ -685,7 +689,7 @@ out:
}
-static OM_uint32
+static OM_uint32 GSSAPI_CALLCONV
acceptor_continue
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
@@ -872,7 +876,7 @@ acceptor_continue
return ret;
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_accept_sec_context
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
diff --git a/source4/heimdal/lib/gssapi/spnego/compat.c b/source4/heimdal/lib/gssapi/spnego/compat.c
index 673a5df66b..b23658cfd1 100644
--- a/source4/heimdal/lib/gssapi/spnego/compat.c
+++ b/source4/heimdal/lib/gssapi/spnego/compat.c
@@ -49,8 +49,9 @@ gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc =
/*
* Allocate a SPNEGO context handle
*/
-OM_uint32 _gss_spnego_alloc_sec_context (OM_uint32 * minor_status,
- gss_ctx_id_t *context_handle)
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_alloc_sec_context (OM_uint32 * minor_status,
+ gss_ctx_id_t *context_handle)
{
gssspnego_ctx ctx;
@@ -91,7 +92,7 @@ OM_uint32 _gss_spnego_alloc_sec_context (OM_uint32 * minor_status,
* Free a SPNEGO context handle. The caller must have acquired
* the lock before this is called.
*/
-OM_uint32 _gss_spnego_internal_delete_sec_context
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_internal_delete_sec_context
(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
gss_buffer_t output_token
@@ -150,7 +151,7 @@ OM_uint32 _gss_spnego_internal_delete_sec_context
* a non-preferred mechanism was negotiated
*/
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_require_mechlist_mic(OM_uint32 *minor_status,
gssspnego_ctx ctx,
int *require_mic)
@@ -228,7 +229,7 @@ add_mech_type(gss_OID mech_type,
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_indicate_mechtypelist (OM_uint32 *minor_status,
gss_name_t target_name,
OM_uint32 (*func)(gss_name_t, gss_OID),
diff --git a/source4/heimdal/lib/gssapi/spnego/context_stubs.c b/source4/heimdal/lib/gssapi/spnego/context_stubs.c
index 98ab919459..18c13fe299 100644
--- a/source4/heimdal/lib/gssapi/spnego/context_stubs.c
+++ b/source4/heimdal/lib/gssapi/spnego/context_stubs.c
@@ -66,7 +66,7 @@ spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
-OM_uint32 _gss_spnego_process_context_token
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_process_context_token
(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t token_buffer
@@ -99,7 +99,7 @@ OM_uint32 _gss_spnego_process_context_token
GSS_C_NO_BUFFER);
}
-OM_uint32 _gss_spnego_delete_sec_context
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_delete_sec_context
(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
gss_buffer_t output_token
@@ -119,7 +119,7 @@ OM_uint32 _gss_spnego_delete_sec_context
output_token);
}
-OM_uint32 _gss_spnego_context_time
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_context_time
(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
OM_uint32 *time_rec
@@ -143,7 +143,7 @@ OM_uint32 _gss_spnego_context_time
time_rec);
}
-OM_uint32 _gss_spnego_get_mic
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_get_mic
(OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t qop_req,
@@ -169,7 +169,7 @@ OM_uint32 _gss_spnego_get_mic
qop_req, message_buffer, message_token);
}
-OM_uint32 _gss_spnego_verify_mic
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_verify_mic
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t message_buffer,
@@ -198,7 +198,7 @@ OM_uint32 _gss_spnego_verify_mic
qop_state);
}
-OM_uint32 _gss_spnego_wrap
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -231,7 +231,7 @@ OM_uint32 _gss_spnego_wrap
output_message_buffer);
}
-OM_uint32 _gss_spnego_unwrap
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_unwrap
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_buffer_t input_message_buffer,
@@ -262,7 +262,7 @@ OM_uint32 _gss_spnego_unwrap
qop_state);
}
-OM_uint32 _gss_spnego_compare_name
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_compare_name
(OM_uint32 *minor_status,
const gss_name_t name1,
const gss_name_t name2,
@@ -286,7 +286,7 @@ OM_uint32 _gss_spnego_compare_name
return GSS_S_COMPLETE;
}
-OM_uint32 _gss_spnego_display_name
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_display_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
gss_buffer_t output_name_buffer,
@@ -304,7 +304,7 @@ OM_uint32 _gss_spnego_display_name
output_name_buffer, output_name_type);
}
-OM_uint32 _gss_spnego_import_name
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_name
(OM_uint32 * minor_status,
const gss_buffer_t name_buffer,
const gss_OID name_type,
@@ -340,7 +340,7 @@ OM_uint32 _gss_spnego_import_name
return GSS_S_COMPLETE;
}
-OM_uint32 _gss_spnego_export_name
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
gss_buffer_t exported_name
@@ -359,7 +359,7 @@ OM_uint32 _gss_spnego_export_name
return gss_export_name(minor_status, name->mech, exported_name);
}
-OM_uint32 _gss_spnego_release_name
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_release_name
(OM_uint32 * minor_status,
gss_name_t * input_name
)
@@ -380,7 +380,7 @@ OM_uint32 _gss_spnego_release_name
return GSS_S_COMPLETE;
}
-OM_uint32 _gss_spnego_inquire_context (
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_context (
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_name_t * src_name,
@@ -447,7 +447,7 @@ enomem:
return GSS_S_FAILURE;
}
-OM_uint32 _gss_spnego_wrap_size_limit (
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_wrap_size_limit (
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -478,7 +478,7 @@ OM_uint32 _gss_spnego_wrap_size_limit (
max_input_size);
}
-OM_uint32 _gss_spnego_export_sec_context (
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_export_sec_context (
OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
gss_buffer_t interprocess_token
@@ -521,7 +521,7 @@ OM_uint32 _gss_spnego_export_sec_context (
return ret;
}
-OM_uint32 _gss_spnego_import_sec_context (
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_sec_context (
OM_uint32 * minor_status,
const gss_buffer_t interprocess_token,
gss_ctx_id_t *context_handle
@@ -557,7 +557,7 @@ OM_uint32 _gss_spnego_import_sec_context (
return GSS_S_COMPLETE;
}
-OM_uint32 _gss_spnego_inquire_names_for_mech (
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_names_for_mech (
OM_uint32 * minor_status,
const gss_OID mechanism,
gss_OID_set * name_types
@@ -600,7 +600,7 @@ out:
return ret;
}
-OM_uint32 _gss_spnego_inquire_mechs_for_name (
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_mechs_for_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
gss_OID_set * mech_types
@@ -621,7 +621,7 @@ OM_uint32 _gss_spnego_inquire_mechs_for_name (
return ret;
}
-OM_uint32 _gss_spnego_canonicalize_name (
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_canonicalize_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
const gss_OID mech_type,
@@ -632,7 +632,7 @@ OM_uint32 _gss_spnego_canonicalize_name (
return gss_duplicate_name(minor_status, input_name, output_name);
}
-OM_uint32 _gss_spnego_duplicate_name (
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_duplicate_name (
OM_uint32 * minor_status,
const gss_name_t src_name,
gss_name_t * dest_name
@@ -641,7 +641,7 @@ OM_uint32 _gss_spnego_duplicate_name (
return gss_duplicate_name(minor_status, src_name, dest_name);
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_wrap_iov(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -662,7 +662,7 @@ _gss_spnego_wrap_iov(OM_uint32 * minor_status,
iov, iov_count);
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_unwrap_iov(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int *conf_state,
@@ -683,7 +683,7 @@ _gss_spnego_unwrap_iov(OM_uint32 *minor_status,
iov, iov_count);
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_wrap_iov_length(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -705,7 +705,7 @@ _gss_spnego_wrap_iov_length(OM_uint32 * minor_status,
}
#if 0
-OM_uint32 _gss_spnego_complete_auth_token
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_complete_auth_token
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
gss_buffer_t input_message_buffer)
@@ -730,7 +730,7 @@ OM_uint32 _gss_spnego_complete_auth_token
}
#endif
-OM_uint32 _gss_spnego_inquire_sec_context_by_oid
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_sec_context_by_oid
(OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
const gss_OID desired_object,
@@ -756,7 +756,7 @@ OM_uint32 _gss_spnego_inquire_sec_context_by_oid
data_set);
}
-OM_uint32 _gss_spnego_set_sec_context_option
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_set_sec_context_option
(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
const gss_OID desired_object,
@@ -783,7 +783,7 @@ OM_uint32 _gss_spnego_set_sec_context_option
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_pseudo_random(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int prf_key,
diff --git a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
index f15069362c..2920f3d9b5 100644
--- a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
+++ b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c
@@ -32,7 +32,7 @@
#include "spnego_locl.h"
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
{
OM_uint32 ret;
@@ -54,7 +54,7 @@ _gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
* we support gss_{get,set}_neg_mechs() we will need to expose
* more functionality.
*/
-OM_uint32 _gss_spnego_acquire_cred
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_acquire_cred
(OM_uint32 *minor_status,
const gss_name_t desired_name,
OM_uint32 time_req,
@@ -127,7 +127,7 @@ out:
return ret;
}
-OM_uint32 _gss_spnego_inquire_cred
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
gss_name_t * name,
@@ -169,7 +169,7 @@ OM_uint32 _gss_spnego_inquire_cred
return ret;
}
-OM_uint32 _gss_spnego_inquire_cred_by_mech (
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred_by_mech (
OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
const gss_OID mech_type,
@@ -214,7 +214,7 @@ OM_uint32 _gss_spnego_inquire_cred_by_mech (
return GSS_S_COMPLETE;
}
-OM_uint32 _gss_spnego_inquire_cred_by_oid
+OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_cred_by_oid
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
const gss_OID desired_object,
@@ -235,7 +235,7 @@ OM_uint32 _gss_spnego_inquire_cred_by_oid
return ret;
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_set_cred_option (OM_uint32 *minor_status,
gss_cred_id_t *cred_handle,
const gss_OID object,
@@ -253,7 +253,7 @@ _gss_spnego_set_cred_option (OM_uint32 *minor_status,
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_export_cred (OM_uint32 *minor_status,
gss_cred_id_t cred_handle,
gss_buffer_t value)
@@ -261,7 +261,7 @@ _gss_spnego_export_cred (OM_uint32 *minor_status,
return gss_export_cred(minor_status, cred_handle, value);
}
-OM_uint32
+OM_uint32 GSSAPI_CALLCONV
_gss_spnego_import_cred (OM_uint32 *minor_status,
gss_buffer_t value,
gss_cred_id_t *cred_handle)
diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c
index 2a6002b8ea..d21e4dc7fe 100644
--- a/source4/heimdal/lib/gssapi/spnego/external.c
+++ b/source4/heimdal/lib/gssapi/spnego/external.c
@@ -93,7 +93,5 @@ __gss_spnego_initialize(void)
return &spnego_mech;
}
-static gss_OID_desc _gss_spnego_mechanism_desc =
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_spnego_mechanism_oid_desc =
{6, (void *)"\x2b\x06\x01\x05\x05\x02"};
-
-gss_OID GSS_SPNEGO_MECHANISM = &_gss_spnego_mechanism_desc;
diff --git a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
index 75a925497e..c9e182129d 100644
--- a/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/spnego/init_sec_context.c
@@ -609,7 +609,8 @@ spnego_reply
return ret;
}
-OM_uint32 _gss_spnego_init_sec_context
+OM_uint32 GSSAPI_CALLCONV
+_gss_spnego_init_sec_context
(OM_uint32 * minor_status,
const gss_cred_id_t initiator_cred_handle,
gss_ctx_id_t * context_handle,
diff --git a/source4/heimdal/lib/hcrypto/aes.c b/source4/heimdal/lib/hcrypto/aes.c
index b3049c165a..77847e460e 100644
--- a/source4/heimdal/lib/hcrypto/aes.c
+++ b/source4/heimdal/lib/hcrypto/aes.c
@@ -119,3 +119,26 @@ AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
}
}
}
+
+void
+AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+ unsigned long size, const AES_KEY *key,
+ unsigned char *iv, int forward_encrypt)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ unsigned char tmp[AES_BLOCK_SIZE + 1];
+
+ memcpy(tmp, iv, AES_BLOCK_SIZE);
+ AES_encrypt(iv, iv, key);
+ if (!forward_encrypt) {
+ tmp[AES_BLOCK_SIZE] = in[i];
+ }
+ out[i] = in[i] ^ iv[0];
+ if (forward_encrypt) {
+ tmp[AES_BLOCK_SIZE] = out[i];
+ }
+ memcpy(iv, &tmp[1], AES_BLOCK_SIZE);
+ }
+}
diff --git a/source4/heimdal/lib/hcrypto/aes.h b/source4/heimdal/lib/hcrypto/aes.h
index 273f1dd569..4ba4516519 100644
--- a/source4/heimdal/lib/hcrypto/aes.h
+++ b/source4/heimdal/lib/hcrypto/aes.h
@@ -42,6 +42,7 @@
#define AES_encrypt hc_AES_encrypt
#define AES_decrypt hc_AES_decrypt
#define AES_cbc_encrypt hc_AES_cbc_encrypt
+#define AES_cfb8_encrypt hc_AES_cfb8_encrypt
/*
*
@@ -71,6 +72,9 @@ void AES_decrypt(const unsigned char *, unsigned char *, const AES_KEY *);
void AES_cbc_encrypt(const unsigned char *, unsigned char *,
unsigned long, const AES_KEY *,
unsigned char *, int);
+void AES_cfb8_encrypt(const unsigned char *, unsigned char *,
+ unsigned long, const AES_KEY *,
+ unsigned char *, int);
#ifdef __cplusplus
}
diff --git a/source4/heimdal/lib/hcrypto/camellia.h b/source4/heimdal/lib/hcrypto/camellia.h
index feabae1aa3..6661f3bf07 100644
--- a/source4/heimdal/lib/hcrypto/camellia.h
+++ b/source4/heimdal/lib/hcrypto/camellia.h
@@ -66,7 +66,7 @@ void CAMELLIA_decrypt(const unsigned char *, unsigned char *,
const CAMELLIA_KEY *);
void CAMELLIA_cbc_encrypt(const unsigned char *, unsigned char *,
- const unsigned long, const CAMELLIA_KEY *,
+ unsigned long, const CAMELLIA_KEY *,
unsigned char *, int);
#endif /* HEIM_CAMELLIA_H */
diff --git a/source4/heimdal/lib/hcrypto/common.c b/source4/heimdal/lib/hcrypto/common.c
new file mode 100644
index 0000000000..136bf1db10
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/common.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <errno.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <krb5-types.h>
+#include <rfc2459_asn1.h>
+#include <hcrypto/bn.h>
+
+
+#include "common.h"
+
+int
+_hc_BN_to_integer(BIGNUM *bn, heim_integer *integer)
+{
+ integer->length = BN_num_bytes(bn);
+ integer->data = malloc(integer->length);
+ if (integer->data == NULL)
+ return ENOMEM;
+ BN_bn2bin(bn, integer->data);
+ integer->negative = BN_is_negative(bn);
+ return 0;
+}
+
+BIGNUM *
+_hc_integer_to_BN(const heim_integer *i, BIGNUM *bn)
+{
+ bn = BN_bin2bn(i->data, i->length, bn);
+ if (bn)
+ BN_set_negative(bn, i->negative);
+ return bn;
+}
diff --git a/source4/heimdal/lib/hcrypto/common.h b/source4/heimdal/lib/hcrypto/common.h
new file mode 100644
index 0000000000..f78f544401
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/common.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HCRYPTO_COMMON_H
+#define HCRYPTO_COMMON_H 1
+
+int
+_hc_BN_to_integer(BIGNUM *, heim_integer *);
+
+BIGNUM *
+_hc_integer_to_BN(const heim_integer *i, BIGNUM *bn);
+
+#endif /* HCRYPTO_COMMON_H */
diff --git a/source4/heimdal/lib/hcrypto/dh-imath.c b/source4/heimdal/lib/hcrypto/dh-imath.c
index 822d5a328b..c2e86fa2fa 100644
--- a/source4/heimdal/lib/hcrypto/dh-imath.c
+++ b/source4/heimdal/lib/hcrypto/dh-imath.c
@@ -31,14 +31,14 @@
* SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
#include <stdio.h>
#include <stdlib.h>
#include <dh.h>
+#ifdef USE_HCRYPTO_IMATH
+
#include <roken.h>
#include "imath/imath.h"
@@ -233,6 +233,7 @@ const DH_METHOD _hc_dh_imath_method = {
NULL,
dh_generate_params
};
+#endif /* USE_HCRYPTO_DH_IMATH */
/**
* DH implementation using libimath.
@@ -245,5 +246,9 @@ const DH_METHOD _hc_dh_imath_method = {
const DH_METHOD *
DH_imath_method(void)
{
+#ifdef USE_HCRYPTO_DH_IMATH
return &_hc_dh_imath_method;
+#else
+ return NULL;
+#endif
}
diff --git a/source4/heimdal/lib/hcrypto/dh-ltm.c b/source4/heimdal/lib/hcrypto/dh-ltm.c
new file mode 100644
index 0000000000..6166100b08
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/dh-ltm.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dh.h>
+
+#include <roken.h>
+
+#include "tommath.h"
+
+static void
+BN2mpz(mp_int *s, const BIGNUM *bn)
+{
+ size_t len;
+ void *p;
+
+ len = BN_num_bytes(bn);
+ p = malloc(len);
+ BN_bn2bin(bn, p);
+ mp_read_unsigned_bin(s, p, len);
+ free(p);
+}
+
+
+static BIGNUM *
+mpz2BN(mp_int *s)
+{
+ size_t size;
+ BIGNUM *bn;
+ void *p;
+
+ size = mp_unsigned_bin_size(s);
+ p = malloc(size);
+ if (p == NULL && size != 0)
+ return NULL;
+ mp_to_unsigned_bin(s, p);
+
+ bn = BN_bin2bn(p, size, NULL);
+ free(p);
+ return bn;
+}
+
+/*
+ *
+ */
+
+#define DH_NUM_TRIES 10
+
+static int
+ltm_dh_generate_key(DH *dh)
+{
+ mp_int pub, priv_key, g, p;
+ int have_private_key = (dh->priv_key != NULL);
+ int codes, times = 0;
+ int res;
+
+ if (dh->p == NULL || dh->g == NULL)
+ return 0;
+
+ while (times++ < DH_NUM_TRIES) {
+ if (!have_private_key) {
+ size_t bits = BN_num_bits(dh->p);
+
+ if (dh->priv_key)
+ BN_free(dh->priv_key);
+
+ dh->priv_key = BN_new();
+ if (dh->priv_key == NULL)
+ return 0;
+ if (!BN_rand(dh->priv_key, bits - 1, 0, 0)) {
+ BN_clear_free(dh->priv_key);
+ dh->priv_key = NULL;
+ return 0;
+ }
+ }
+ if (dh->pub_key)
+ BN_free(dh->pub_key);
+
+ mp_init_multi(&pub, &priv_key, &g, &p, NULL);
+
+ BN2mpz(&priv_key, dh->priv_key);
+ BN2mpz(&g, dh->g);
+ BN2mpz(&p, dh->p);
+
+ res = mp_exptmod(&g, &priv_key, &p, &pub);
+
+ mp_zero(&priv_key);
+ mp_zero(&g);
+ mp_zero(&p);
+ if (res != 0)
+ continue;
+
+ dh->pub_key = mpz2BN(&pub);
+ mp_zero(&pub);
+ if (dh->pub_key == NULL)
+ return 0;
+
+ if (DH_check_pubkey(dh, dh->pub_key, &codes) && codes == 0)
+ break;
+ if (have_private_key)
+ return 0;
+ }
+
+ if (times >= DH_NUM_TRIES) {
+ if (!have_private_key && dh->priv_key) {
+ BN_free(dh->priv_key);
+ dh->priv_key = NULL;
+ }
+ if (dh->pub_key) {
+ BN_free(dh->pub_key);
+ dh->pub_key = NULL;
+ }
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+ltm_dh_compute_key(unsigned char *shared, const BIGNUM * pub, DH *dh)
+{
+ mp_int s, priv_key, p, peer_pub;
+ size_t size = 0;
+ int ret;
+
+ if (dh->pub_key == NULL || dh->g == NULL || dh->priv_key == NULL)
+ return -1;
+
+ mp_init(&p);
+ BN2mpz(&p, dh->p);
+
+ mp_init(&peer_pub);
+ BN2mpz(&peer_pub, pub);
+
+ /* check if peers pubkey is reasonable */
+ if (mp_isneg(&peer_pub)
+ || mp_cmp(&peer_pub, &p) >= 0
+ || mp_cmp_d(&peer_pub, 1) <= 0)
+ {
+ mp_zero(&p);
+ mp_zero(&peer_pub);
+ return -1;
+ }
+
+ mp_init(&priv_key);
+ BN2mpz(&priv_key, dh->priv_key);
+
+ mp_init(&s);
+
+ ret = mp_exptmod(&peer_pub, &priv_key, &p, &s);
+
+ mp_zero(&p);
+ mp_zero(&peer_pub);
+ mp_zero(&priv_key);
+
+ if (ret != 0)
+ return -1;
+
+ size = mp_unsigned_bin_size(&s);
+ mp_to_unsigned_bin(&s, shared);
+ mp_zero(&s);
+
+ return size;
+}
+
+static int
+ltm_dh_generate_params(DH *dh, int a, int b, BN_GENCB *callback)
+{
+ /* groups should already be known, we don't care about this */
+ return 0;
+}
+
+static int
+ltm_dh_init(DH *dh)
+{
+ return 1;
+}
+
+static int
+ltm_dh_finish(DH *dh)
+{
+ return 1;
+}
+
+
+/*
+ *
+ */
+
+const DH_METHOD _hc_dh_ltm_method = {
+ "hcrypto ltm DH",
+ ltm_dh_generate_key,
+ ltm_dh_compute_key,
+ NULL,
+ ltm_dh_init,
+ ltm_dh_finish,
+ 0,
+ NULL,
+ ltm_dh_generate_params
+};
+
+/**
+ * DH implementation using libimath.
+ *
+ * @return the DH_METHOD for the DH implementation using libimath.
+ *
+ * @ingroup hcrypto_dh
+ */
+
+const DH_METHOD *
+DH_ltm_method(void)
+{
+ return &_hc_dh_ltm_method;
+}
diff --git a/source4/heimdal/lib/hcrypto/dh.c b/source4/heimdal/lib/hcrypto/dh.c
index d42ac34fd2..3ad37f87a7 100644
--- a/source4/heimdal/lib/hcrypto/dh.c
+++ b/source4/heimdal/lib/hcrypto/dh.c
@@ -37,6 +37,9 @@
#include <stdio.h>
#include <stdlib.h>
+#include <krb5-types.h>
+#include <rfc2459_asn1.h>
+
#include <dh.h>
#include <roken.h>
@@ -487,3 +490,63 @@ DH_get_default_method(void)
return dh_default_method;
}
+/*
+ *
+ */
+
+static int
+bn2heim_int(BIGNUM *bn, heim_integer *integer)
+{
+ integer->length = BN_num_bytes(bn);
+ integer->data = malloc(integer->length);
+ if (integer->data == NULL) {
+ integer->length = 0;
+ return ENOMEM;
+ }
+ BN_bn2bin(bn, integer->data);
+ integer->negative = BN_is_negative(bn);
+ return 0;
+}
+
+/**
+ *
+ */
+
+int
+i2d_DHparams(DH *dh, unsigned char **pp)
+{
+ DHParameter data;
+ size_t size;
+ int ret;
+
+ memset(&data, 0, sizeof(data));
+
+ if (bn2heim_int(dh->p, &data.prime) ||
+ bn2heim_int(dh->g, &data.base))
+ {
+ free_DHParameter(&data);
+ return -1;
+ }
+
+ if (pp == NULL) {
+ size = length_DHParameter(&data);
+ free_DHParameter(&data);
+ } else {
+ void *p;
+ size_t len;
+
+ ASN1_MALLOC_ENCODE(DHParameter, p, len, &data, &size, ret);
+ free_DHParameter(&data);
+ if (ret)
+ return -1;
+ if (len != size)
+ abort();
+
+ memcpy(*pp, p, size);
+ free(p);
+
+ *pp += size;
+ }
+
+ return size;
+}
diff --git a/source4/heimdal/lib/hcrypto/dh.h b/source4/heimdal/lib/hcrypto/dh.h
index 2522bfe39f..3a24f9dfdf 100644
--- a/source4/heimdal/lib/hcrypto/dh.h
+++ b/source4/heimdal/lib/hcrypto/dh.h
@@ -41,6 +41,8 @@
/* symbol renaming */
#define DH_null_method hc_DH_null_method
#define DH_imath_method hc_DH_imath_method
+#define DH_tfm_method hc_DH_tfm_method
+#define DH_ltm_method hc_DH_ltm_method
#define DH_new hc_DH_new
#define DH_new_method hc_DH_new_method
#define DH_free hc_DH_free
@@ -56,6 +58,7 @@
#define DH_check_pubkey hc_DH_check_pubkey
#define DH_generate_key hc_DH_generate_key
#define DH_compute_key hc_DH_compute_key
+#define i2d_DHparams hc_i2d_DHparams
/*
*
@@ -114,6 +117,8 @@ struct DH {
*/
const DH_METHOD *DH_null_method(void);
+const DH_METHOD *DH_tfm_method(void);
+const DH_METHOD *DH_ltm_method(void);
const DH_METHOD *DH_imath_method(void);
DH * DH_new(void);
@@ -137,5 +142,7 @@ int DH_check_pubkey(const DH *, const BIGNUM *, int *);
int DH_generate_key(DH *);
int DH_compute_key(unsigned char *,const BIGNUM *,DH *);
+int i2d_DHparams(DH *, unsigned char **);
+
#endif /* _HEIM_DH_H */
diff --git a/source4/heimdal/lib/hcrypto/engine.c b/source4/heimdal/lib/hcrypto/engine.c
index 8066d59cf8..6e3e5e3939 100644
--- a/source4/heimdal/lib/hcrypto/engine.c
+++ b/source4/heimdal/lib/hcrypto/engine.c
@@ -56,6 +56,23 @@ struct hc_engine {
const RAND_METHOD *rand;
};
+ENGINE *
+ENGINE_new(void)
+{
+ ENGINE *engine;
+
+ engine = calloc(1, sizeof(*engine));
+ engine->references = 1;
+
+ return engine;
+}
+
+int
+ENGINE_free(ENGINE *engine)
+{
+ return ENGINE_finish(engine);
+}
+
int
ENGINE_finish(ENGINE *engine)
{
@@ -195,10 +212,8 @@ add_engine(ENGINE *engine)
ENGINE **d, *dup;
dup = ENGINE_by_id(engine->id);
- if (dup) {
- ENGINE_finish(dup);
+ if (dup)
return 0;
- }
d = realloc(engines, (num_engines + 1) * sizeof(*engines));
if (d == NULL)
@@ -215,19 +230,98 @@ ENGINE_load_builtin_engines(void)
ENGINE *engine;
int ret;
- engine = calloc(1, sizeof(*engine));
+ engine = ENGINE_new();
if (engine == NULL)
return;
ENGINE_set_id(engine, "builtin");
ENGINE_set_name(engine,
- "Heimdal crypto builtin engine version " PACKAGE_VERSION);
+ "Heimdal crypto builtin (ltm) engine version " PACKAGE_VERSION);
+ ENGINE_set_RSA(engine, RSA_ltm_method());
+ ENGINE_set_DH(engine, DH_ltm_method());
+
+ ret = add_engine(engine);
+ if (ret != 1)
+ ENGINE_finish(engine);
+
+#ifdef USE_HCRYPTO_TFM
+ /*
+ * TFM
+ */
+
+ engine = ENGINE_new();
+ if (engine == NULL)
+ return;
+
+ ENGINE_set_id(engine, "tfm");
+ ENGINE_set_name(engine,
+ "Heimdal crypto tfm engine version " PACKAGE_VERSION);
+ ENGINE_set_RSA(engine, RSA_tfm_method());
+ ENGINE_set_DH(engine, DH_tfm_method());
+
+ ret = add_engine(engine);
+ if (ret != 1)
+ ENGINE_finish(engine);
+#endif /* USE_HCRYPTO_TFM */
+
+#ifdef USE_HCRYPTO_LTM
+ /*
+ * ltm
+ */
+
+ engine = ENGINE_new();
+ if (engine == NULL)
+ return;
+
+ ENGINE_set_id(engine, "ltm");
+ ENGINE_set_name(engine,
+ "Heimdal crypto ltm engine version " PACKAGE_VERSION);
+ ENGINE_set_RSA(engine, RSA_ltm_method());
+ ENGINE_set_DH(engine, DH_ltm_method());
+
+ ret = add_engine(engine);
+ if (ret != 1)
+ ENGINE_finish(engine);
+#endif
+
+#ifdef USE_HCRYPTO_IMATH
+ /*
+ * imath
+ */
+
+ engine = ENGINE_new();
+ if (engine == NULL)
+ return;
+
+ ENGINE_set_id(engine, "imath");
+ ENGINE_set_name(engine,
+ "Heimdal crypto imath engine version " PACKAGE_VERSION);
ENGINE_set_RSA(engine, RSA_imath_method());
ENGINE_set_DH(engine, DH_imath_method());
ret = add_engine(engine);
if (ret != 1)
ENGINE_finish(engine);
+#endif
+
+#ifdef HAVE_GMP
+ /*
+ * gmp
+ */
+
+ engine = ENGINE_new();
+ if (engine == NULL)
+ return;
+
+ ENGINE_set_id(engine, "gmp");
+ ENGINE_set_name(engine,
+ "Heimdal crypto gmp engine version " PACKAGE_VERSION);
+ ENGINE_set_RSA(engine, RSA_gmp_method());
+
+ ret = add_engine(engine);
+ if (ret != 1)
+ ENGINE_finish(engine);
+#endif
}
ENGINE *
diff --git a/source4/heimdal/lib/hcrypto/engine.h b/source4/heimdal/lib/hcrypto/engine.h
index d3a1479ce2..7fd8f3e1e5 100644
--- a/source4/heimdal/lib/hcrypto/engine.h
+++ b/source4/heimdal/lib/hcrypto/engine.h
@@ -54,6 +54,8 @@
#define ENGINE_set_id hc_ENGINE_set_id
#define ENGINE_set_name hc_ENGINE_set_name
#define ENGINE_set_destroy_function hc_ENGINE_set_destroy_function
+#define ENGINE_new hc_ENGINE_new
+#define ENGINE_free hc_ENGINE_free
#define ENGINE_up_ref hc_ENGINE_up_ref
#define ENGINE_get_default_DH hc_ENGINE_get_default_DH
#define ENGINE_get_default_RSA hc_ENGINE_get_default_RSA
@@ -66,6 +68,16 @@
typedef struct hc_engine ENGINE;
+#define NID_md2 0
+#define NID_md4 1
+#define NID_md5 2
+#define NID_sha1 4
+#define NID_sha256 5
+
+/*
+ *
+ */
+
#include <hcrypto/rsa.h>
#include <hcrypto/dsa.h>
#include <hcrypto/dh.h>
@@ -76,6 +88,9 @@ typedef struct hc_engine ENGINE;
typedef int (*openssl_bind_engine)(ENGINE *, const char *, const void *);
typedef unsigned long (*openssl_v_check)(unsigned long);
+ENGINE *
+ ENGINE_new(void);
+int ENGINE_free(ENGINE *);
void ENGINE_add_conf_module(void);
void ENGINE_load_builtin_engines(void);
ENGINE *ENGINE_by_id(const char *);
diff --git a/source4/heimdal/lib/hcrypto/evp-cc.c b/source4/heimdal/lib/hcrypto/evp-cc.c
new file mode 100644
index 0000000000..bd084a25e2
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/evp-cc.c
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* CommonCrypto provider */
+
+#ifdef __APPLE__
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+#include <CommonCrypto/CommonDigest.h>
+#endif
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+#include <CommonCrypto/CommonCryptor.h>
+#endif
+
+#include <evp.h>
+#include <evp-cc.h>
+
+/*
+ *
+ */
+
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+
+struct cc_key {
+ CCCryptorRef href;
+};
+
+static int
+cc_do_cipher(EVP_CIPHER_CTX *ctx,
+ unsigned char *out,
+ const unsigned char *in,
+ unsigned int size)
+{
+ struct cc_key *cc = ctx->cipher_data;
+ CCCryptorStatus ret;
+ size_t moved;
+
+ memcpy(out, in, size);
+
+ ret = CCCryptorUpdate(cc->href, in, size, out, size, &moved);
+ if (ret)
+ return 0;
+
+ if (moved != size)
+ return 0;
+
+ return 1;
+}
+
+static int
+cc_do_cfb8_cipher(EVP_CIPHER_CTX *ctx,
+ unsigned char *out,
+ const unsigned char *in,
+ unsigned int size)
+{
+ struct cc_key *cc = ctx->cipher_data;
+ CCCryptorStatus ret;
+ size_t moved;
+ unsigned int i;
+
+ for (i = 0; i < size; i++) {
+ unsigned char oiv[EVP_MAX_IV_LENGTH + 1];
+
+ assert(ctx->cipher->iv_len + 1 <= sizeof(oiv));
+ memcpy(oiv, ctx->iv, ctx->cipher->iv_len);
+
+ ret = CCCryptorUpdate(cc->href, ctx->iv, ctx->cipher->iv_len,
+ ctx->iv, ctx->cipher->iv_len, &moved);
+ if (ret)
+ return 0;
+
+ if (moved != ctx->cipher->iv_len)
+ return 0;
+
+ if (!ctx->encrypt)
+ oiv[ctx->cipher->iv_len] = in[i];
+ out[i] = in[i] ^ ctx->iv[0];
+ if (ctx->encrypt)
+ oiv[ctx->cipher->iv_len] = out[i];
+
+ memcpy(ctx->iv, &oiv[1], ctx->cipher->iv_len);
+ }
+
+ return 1;
+}
+
+static int
+cc_cleanup(EVP_CIPHER_CTX *ctx)
+{
+ struct cc_key *cc = ctx->cipher_data;
+ if (cc->href)
+ CCCryptorRelease(cc->href);
+ return 1;
+}
+
+static int
+init_cc_key(int encp, CCAlgorithm alg, CCOptions opts, const void *key,
+ size_t keylen, const void *iv, CCCryptorRef *ref)
+{
+ CCOperation op = encp ? kCCEncrypt : kCCDecrypt;
+ CCCryptorStatus ret;
+
+ if (*ref) {
+ if (key == NULL && iv) {
+ CCCryptorReset(*ref, iv);
+ return 1;
+ }
+ CCCryptorRelease(*ref);
+ }
+
+ ret = CCCryptorCreate(op, alg, opts, key, keylen, iv, ref);
+ if (ret)
+ return 0;
+ return 1;
+}
+
+static int
+cc_des_ede3_cbc_init(EVP_CIPHER_CTX *ctx,
+ const unsigned char * key,
+ const unsigned char * iv,
+ int encp)
+{
+ struct cc_key *cc = ctx->cipher_data;
+ return init_cc_key(encp, kCCAlgorithm3DES, 0, key, kCCKeySize3DES, iv, &cc->href);
+}
+
+#endif /* HAVE_COMMONCRYPTO_COMMONCRYPTOR_H */
+
+/**
+ * The tripple DES cipher type (Apple CommonCrypto provider)
+ *
+ * @return the DES-EDE3-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_des_ede3_cbc(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER des_ede3_cbc = {
+ 0,
+ 8,
+ 24,
+ 8,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_des_ede3_cbc_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &des_ede3_cbc;
+#else
+ return NULL;
+#endif
+}
+
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+/*
+ *
+ */
+
+static int
+cc_des_cbc_init(EVP_CIPHER_CTX *ctx,
+ const unsigned char * key,
+ const unsigned char * iv,
+ int encp)
+{
+ struct cc_key *cc = ctx->cipher_data;
+ return init_cc_key(encp, kCCAlgorithmDES, 0, key, kCCBlockSizeDES, iv, &cc->href);
+}
+#endif
+
+/**
+ * The DES cipher type (Apple CommonCrypto provider)
+ *
+ * @return the DES-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_des_cbc(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER des_ede3_cbc = {
+ 0,
+ kCCBlockSizeDES,
+ kCCBlockSizeDES,
+ kCCBlockSizeDES,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_des_cbc_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &des_ede3_cbc;
+#else
+ return NULL;
+#endif
+}
+
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+/*
+ *
+ */
+
+static int
+cc_aes_cbc_init(EVP_CIPHER_CTX *ctx,
+ const unsigned char * key,
+ const unsigned char * iv,
+ int encp)
+{
+ struct cc_key *cc = ctx->cipher_data;
+ return init_cc_key(encp, kCCAlgorithmAES128, 0, key, ctx->cipher->key_len, iv, &cc->href);
+}
+#endif
+
+/**
+ * The AES-128 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-128-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_128_cbc(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER c = {
+ 0,
+ kCCBlockSizeAES128,
+ kCCKeySizeAES128,
+ kCCBlockSizeAES128,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_aes_cbc_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &c;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The AES-192 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-192-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_192_cbc(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER c = {
+ 0,
+ kCCBlockSizeAES128,
+ kCCKeySizeAES192,
+ kCCBlockSizeAES128,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_aes_cbc_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &c;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The AES-256 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-256-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_256_cbc(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER c = {
+ 0,
+ kCCBlockSizeAES128,
+ kCCKeySizeAES256,
+ kCCBlockSizeAES128,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_aes_cbc_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &c;
+#else
+ return NULL;
+#endif
+}
+
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+/*
+ *
+ */
+
+static int
+cc_aes_cfb8_init(EVP_CIPHER_CTX *ctx,
+ const unsigned char * key,
+ const unsigned char * iv,
+ int encp)
+{
+ struct cc_key *cc = ctx->cipher_data;
+ memcpy(ctx->iv, iv, ctx->cipher->iv_len);
+ return init_cc_key(1, kCCAlgorithmAES128, kCCOptionECBMode,
+ key, ctx->cipher->key_len, NULL, &cc->href);
+}
+#endif
+
+/**
+ * The AES-128 CFB8 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-128-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_128_cfb8(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER c = {
+ 0,
+ 1,
+ kCCKeySizeAES128,
+ kCCBlockSizeAES128,
+ EVP_CIPH_CFB8_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_aes_cfb8_init,
+ cc_do_cfb8_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &c;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The AES-192 CFB8 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-192-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_192_cfb8(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER c = {
+ 0,
+ 1,
+ kCCKeySizeAES192,
+ kCCBlockSizeAES128,
+ EVP_CIPH_CFB8_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_aes_cfb8_init,
+ cc_do_cfb8_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &c;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The AES-256 CFB8 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the AES-256-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_aes_256_cfb8(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER c = {
+ 0,
+ kCCBlockSizeAES128,
+ kCCKeySizeAES256,
+ kCCBlockSizeAES128,
+ EVP_CIPH_CFB8_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_aes_cfb8_init,
+ cc_do_cfb8_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &c;
+#else
+ return NULL;
+#endif
+}
+
+/*
+ *
+ */
+
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
+static int
+cc_rc2_cbc_init(EVP_CIPHER_CTX *ctx,
+ const unsigned char * key,
+ const unsigned char * iv,
+ int encp)
+{
+ struct cc_key *cc = ctx->cipher_data;
+ return init_cc_key(encp, kCCAlgorithmRC2, 0, key, ctx->cipher->key_len, iv, &cc->href);
+}
+#endif
+
+/**
+ * The RC2 cipher type - common crypto
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+
+const EVP_CIPHER *
+EVP_cc_rc2_cbc(void)
+{
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
+ static const EVP_CIPHER rc2_cbc = {
+ 0,
+ kCCBlockSizeRC2,
+ 16,
+ kCCBlockSizeRC2,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_rc2_cbc_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &rc2_cbc;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The RC2-40 cipher type - common crypto
+ *
+ * @return the RC2-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+
+const EVP_CIPHER *
+EVP_cc_rc2_40_cbc(void)
+{
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
+ static const EVP_CIPHER rc2_40_cbc = {
+ 0,
+ kCCBlockSizeRC2,
+ 5,
+ kCCBlockSizeRC2,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_rc2_cbc_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &rc2_40_cbc;
+#else
+ return NULL;
+#endif
+}
+
+
+/**
+ * The RC2-64 cipher type - common crypto
+ *
+ * @return the RC2-64 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+
+const EVP_CIPHER *
+EVP_cc_rc2_64_cbc(void)
+{
+#ifdef COMMONCRYPTO_SUPPORTS_RC2
+ static const EVP_CIPHER rc2_64_cbc = {
+ 0,
+ kCCBlockSizeRC2,
+ 8,
+ kCCBlockSizeRC2,
+ EVP_CIPH_CBC_MODE|EVP_CIPH_ALWAYS_CALL_INIT,
+ cc_rc2_cbc_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &rc2_64_cbc;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto md2 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_md2(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+ static const struct hc_evp_md md2 = {
+ CC_MD2_DIGEST_LENGTH,
+ CC_MD2_BLOCK_BYTES,
+ sizeof(CC_MD2_CTX),
+ (hc_evp_md_init)CC_MD2_Init,
+ (hc_evp_md_update)CC_MD2_Update,
+ (hc_evp_md_final)CC_MD2_Final,
+ (hc_evp_md_cleanup)NULL
+ };
+ return &md2;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto md4 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_md4(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+ static const struct hc_evp_md md4 = {
+ CC_MD4_DIGEST_LENGTH,
+ CC_MD4_BLOCK_BYTES,
+ sizeof(CC_MD4_CTX),
+ (hc_evp_md_init)CC_MD4_Init,
+ (hc_evp_md_update)CC_MD4_Update,
+ (hc_evp_md_final)CC_MD4_Final,
+ (hc_evp_md_cleanup)NULL
+ };
+ return &md4;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto md5 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_md5(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+ static const struct hc_evp_md md5 = {
+ CC_MD5_DIGEST_LENGTH,
+ CC_MD5_BLOCK_BYTES,
+ sizeof(CC_MD5_CTX),
+ (hc_evp_md_init)CC_MD5_Init,
+ (hc_evp_md_update)CC_MD5_Update,
+ (hc_evp_md_final)CC_MD5_Final,
+ (hc_evp_md_cleanup)NULL
+ };
+ return &md5;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto sha1 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_sha1(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+ static const struct hc_evp_md sha1 = {
+ CC_SHA1_DIGEST_LENGTH,
+ CC_SHA1_BLOCK_BYTES,
+ sizeof(CC_SHA1_CTX),
+ (hc_evp_md_init)CC_SHA1_Init,
+ (hc_evp_md_update)CC_SHA1_Update,
+ (hc_evp_md_final)CC_SHA1_Final,
+ (hc_evp_md_cleanup)NULL
+ };
+ return &sha1;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The CommonCrypto sha256 provider
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_MD *
+EVP_cc_sha256(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
+ static const struct hc_evp_md sha256 = {
+ CC_SHA256_DIGEST_LENGTH,
+ CC_SHA256_BLOCK_BYTES,
+ sizeof(CC_SHA256_CTX),
+ (hc_evp_md_init)CC_SHA256_Init,
+ (hc_evp_md_update)CC_SHA256_Update,
+ (hc_evp_md_final)CC_SHA256_Final,
+ (hc_evp_md_cleanup)NULL
+ };
+ return &sha256;
+#else
+ return NULL;
+#endif
+}
+
+/**
+ * The Camellia-128 cipher type - CommonCrypto
+ *
+ * @return the Camellia-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_camellia_128_cbc(void)
+{
+ return NULL;
+}
+
+/**
+ * The Camellia-198 cipher type - CommonCrypto
+ *
+ * @return the Camellia-198 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_camellia_192_cbc(void)
+{
+ return NULL;
+}
+
+/**
+ * The Camellia-256 cipher type - CommonCrypto
+ *
+ * @return the Camellia-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_camellia_256_cbc(void)
+{
+ return NULL;
+}
+
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+
+/*
+ *
+ */
+
+static int
+cc_rc4_init(EVP_CIPHER_CTX *ctx,
+ const unsigned char * key,
+ const unsigned char * iv,
+ int encp)
+{
+ struct cc_key *cc = ctx->cipher_data;
+ return init_cc_key(encp, kCCAlgorithmRC4, 0, key, ctx->key_len, iv, &cc->href);
+}
+
+#endif
+
+/**
+
+ * The RC4 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_rc4(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER rc4 = {
+ 0,
+ 1,
+ 16,
+ 0,
+ EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
+ cc_rc4_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &rc4;
+#else
+ return NULL;
+#endif
+}
+
+
+/**
+ * The RC4-40 cipher type (Apple CommonCrypto provider)
+ *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_cc_rc4_40(void)
+{
+#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H
+ static const EVP_CIPHER rc4_40 = {
+ 0,
+ 1,
+ 5,
+ 0,
+ EVP_CIPH_STREAM_CIPHER|EVP_CIPH_VARIABLE_LENGTH,
+ cc_rc4_init,
+ cc_do_cipher,
+ cc_cleanup,
+ sizeof(struct cc_key),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &rc4_40;
+#else
+ return NULL;
+#endif
+}
+
+#endif /* __APPLE__ */
+
diff --git a/source4/heimdal/lib/hcrypto/evp-cc.h b/source4/heimdal/lib/hcrypto/evp-cc.h
index 0febd21e98..9249bb226e 100644
--- a/source4/heimdal/lib/hcrypto/evp-cc.h
+++ b/source4/heimdal/lib/hcrypto/evp-cc.h
@@ -47,6 +47,9 @@
#define EVP_cc_aes_128_cbc hc_EVP_cc_aes_128_cbc
#define EVP_cc_aes_192_cbc hc_EVP_cc_aes_192_cbc
#define EVP_cc_aes_256_cbc hc_EVP_cc_aes_256_cbc
+#define EVP_cc_aes_128_cfb8 hc_EVP_cc_aes_128_cfb8
+#define EVP_cc_aes_192_cfb8 hc_EVP_cc_aes_192_cfb8
+#define EVP_cc_aes_256_cfb8 hc_EVP_cc_aes_256_cfb8
#define EVP_cc_rc4 hc_EVP_cc_rc4
#define EVP_cc_rc4_40 hc_EVP_cc_rc4_40
#define EVP_cc_rc2_40_cbc hc_EVP_cc_rc2_40_cbc
@@ -82,6 +85,10 @@ const EVP_CIPHER * EVP_cc_aes_128_cbc(void);
const EVP_CIPHER * EVP_cc_aes_192_cbc(void);
const EVP_CIPHER * EVP_cc_aes_256_cbc(void);
+const EVP_CIPHER * EVP_cc_aes_128_cfb8(void);
+const EVP_CIPHER * EVP_cc_aes_192_cfb8(void);
+const EVP_CIPHER * EVP_cc_aes_256_cfb8(void);
+
const EVP_CIPHER * EVP_cc_camellia_128_cbc(void);
const EVP_CIPHER * EVP_cc_camellia_192_cbc(void);
const EVP_CIPHER * EVP_cc_camellia_256_cbc(void);
diff --git a/source4/heimdal/lib/hcrypto/evp-hcrypto.c b/source4/heimdal/lib/hcrypto/evp-hcrypto.c
index 699fc667b0..9e063545e1 100644
--- a/source4/heimdal/lib/hcrypto/evp-hcrypto.c
+++ b/source4/heimdal/lib/hcrypto/evp-hcrypto.c
@@ -83,7 +83,10 @@ aes_do_cipher(EVP_CIPHER_CTX *ctx,
unsigned int size)
{
AES_KEY *k = ctx->cipher_data;
- AES_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
+ if (ctx->flags & EVP_CIPH_CFB8_MODE)
+ AES_cfb8_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
+ else
+ AES_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
return 1;
}
@@ -176,6 +179,94 @@ EVP_hcrypto_aes_256_cbc(void)
}
/**
+ * The AES-128 CFB8 cipher type (hcrypto)
+ *
+ * @return the AES-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_aes_128_cfb8(void)
+{
+ static const EVP_CIPHER aes_128_cfb8 = {
+ 0,
+ 1,
+ 16,
+ 16,
+ EVP_CIPH_CFB8_MODE,
+ aes_init,
+ aes_do_cipher,
+ NULL,
+ sizeof(AES_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+
+ return &aes_128_cfb8;
+}
+
+/**
+ * The AES-192 CFB8 cipher type (hcrypto)
+ *
+ * @return the AES-192 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_aes_192_cfb8(void)
+{
+ static const EVP_CIPHER aes_192_cfb8 = {
+ 0,
+ 1,
+ 24,
+ 16,
+ EVP_CIPH_CFB8_MODE,
+ aes_init,
+ aes_do_cipher,
+ NULL,
+ sizeof(AES_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &aes_192_cfb8;
+}
+
+/**
+ * The AES-256 CFB8 cipher type (hcrypto)
+ *
+ * @return the AES-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_hcrypto_aes_256_cfb8(void)
+{
+ static const EVP_CIPHER aes_256_cfb8 = {
+ 0,
+ 1,
+ 32,
+ 16,
+ EVP_CIPH_CFB8_MODE,
+ aes_init,
+ aes_do_cipher,
+ NULL,
+ sizeof(AES_KEY),
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ return &aes_256_cfb8;
+}
+
+/**
* The message digest SHA256 - hcrypto
*
* @return the message digest type.
diff --git a/source4/heimdal/lib/hcrypto/evp-hcrypto.h b/source4/heimdal/lib/hcrypto/evp-hcrypto.h
index c0fb89af71..7915046bdc 100644
--- a/source4/heimdal/lib/hcrypto/evp-hcrypto.h
+++ b/source4/heimdal/lib/hcrypto/evp-hcrypto.h
@@ -47,6 +47,9 @@
#define EVP_hcrypto_aes_128_cbc hc_EVP_hcrypto_aes_128_cbc
#define EVP_hcrypto_aes_192_cbc hc_EVP_hcrypto_aes_192_cbc
#define EVP_hcrypto_aes_256_cbc hc_EVP_hcrypto_aes_256_cbc
+#define EVP_hcrypto_aes_128_cfb8 hc_EVP_hcrypto_aes_128_cfb8
+#define EVP_hcrypto_aes_192_cfb8 hc_EVP_hcrypto_aes_192_cfb8
+#define EVP_hcrypto_aes_256_cfb8 hc_EVP_hcrypto_aes_256_cfb8
#define EVP_hcrypto_rc4 hc_EVP_hcrypto_rc4
#define EVP_hcrypto_rc4_40 hc_EVP_hcrypto_rc4_40
#define EVP_hcrypto_rc2_40_cbc hc_EVP_hcrypto_rc2_40_cbc
@@ -82,6 +85,10 @@ const EVP_CIPHER * EVP_hcrypto_aes_128_cbc(void);
const EVP_CIPHER * EVP_hcrypto_aes_192_cbc(void);
const EVP_CIPHER * EVP_hcrypto_aes_256_cbc(void);
+const EVP_CIPHER * EVP_hcrypto_aes_128_cfb8(void);
+const EVP_CIPHER * EVP_hcrypto_aes_192_cfb8(void);
+const EVP_CIPHER * EVP_hcrypto_aes_256_cfb8(void);
+
const EVP_CIPHER * EVP_hcrypto_camellia_128_cbc(void);
const EVP_CIPHER * EVP_hcrypto_camellia_192_cbc(void);
const EVP_CIPHER * EVP_hcrypto_camellia_256_cbc(void);
diff --git a/source4/heimdal/lib/hcrypto/evp.c b/source4/heimdal/lib/hcrypto/evp.c
index 72787e185f..da1a8940be 100644
--- a/source4/heimdal/lib/hcrypto/evp.c
+++ b/source4/heimdal/lib/hcrypto/evp.c
@@ -356,6 +356,7 @@ EVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize,
const EVP_MD *
EVP_sha256(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, sha256);
}
@@ -370,6 +371,7 @@ EVP_sha256(void)
const EVP_MD *
EVP_sha1(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, sha1);
}
@@ -385,6 +387,7 @@ const EVP_MD *
EVP_sha(void) HC_DEPRECATED
{
+ hcrypto_validate();
return EVP_sha1();
}
@@ -399,6 +402,7 @@ EVP_sha(void) HC_DEPRECATED
const EVP_MD *
EVP_md5(void) HC_DEPRECATED_CRYPTO
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md5);
}
@@ -413,6 +417,7 @@ EVP_md5(void) HC_DEPRECATED_CRYPTO
const EVP_MD *
EVP_md4(void) HC_DEPRECATED_CRYPTO
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md4);
}
@@ -427,6 +432,7 @@ EVP_md4(void) HC_DEPRECATED_CRYPTO
const EVP_MD *
EVP_md2(void) HC_DEPRECATED_CRYPTO
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, md2);
}
@@ -768,6 +774,10 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
case EVP_CIPH_STREAM_CIPHER:
break;
+ case EVP_CIPH_CFB8_MODE:
+ if (iv)
+ memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+ break;
default:
return 0;
@@ -996,6 +1006,7 @@ EVP_enc_null(void)
const EVP_CIPHER *
EVP_rc2_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc2_cbc);
}
@@ -1010,6 +1021,7 @@ EVP_rc2_cbc(void)
const EVP_CIPHER *
EVP_rc2_40_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc2_40_cbc);
}
@@ -1024,6 +1036,7 @@ EVP_rc2_40_cbc(void)
const EVP_CIPHER *
EVP_rc2_64_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc2_64_cbc);
}
@@ -1038,6 +1051,7 @@ EVP_rc2_64_cbc(void)
const EVP_CIPHER *
EVP_rc4(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc4);
}
@@ -1052,6 +1066,7 @@ EVP_rc4(void)
const EVP_CIPHER *
EVP_rc4_40(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, rc4_40);
}
@@ -1066,6 +1081,7 @@ EVP_rc4_40(void)
const EVP_CIPHER *
EVP_des_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, des_cbc);
}
@@ -1080,6 +1096,7 @@ EVP_des_cbc(void)
const EVP_CIPHER *
EVP_des_ede3_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, des_ede3_cbc);
}
@@ -1094,6 +1111,7 @@ EVP_des_ede3_cbc(void)
const EVP_CIPHER *
EVP_aes_128_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_128_cbc);
}
@@ -1108,6 +1126,7 @@ EVP_aes_128_cbc(void)
const EVP_CIPHER *
EVP_aes_192_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_192_cbc);
}
@@ -1122,10 +1141,56 @@ EVP_aes_192_cbc(void)
const EVP_CIPHER *
EVP_aes_256_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_256_cbc);
}
/**
+ * The AES-128 cipher type
+ *
+ * @return the AES-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_aes_128_cfb8(void)
+{
+ hcrypto_validate();
+ return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_128_cfb8);
+}
+
+/**
+ * The AES-192 cipher type
+ *
+ * @return the AES-192 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_aes_192_cfb8(void)
+{
+ hcrypto_validate();
+ return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_192_cfb8);
+}
+
+/**
+ * The AES-256 cipher type
+ *
+ * @return the AES-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_aes_256_cfb8(void)
+{
+ hcrypto_validate();
+ return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, aes_256_cfb8);
+}
+
+/**
* The Camellia-128 cipher type
*
* @return the Camellia-128 EVP_CIPHER pointer.
@@ -1136,6 +1201,7 @@ EVP_aes_256_cbc(void)
const EVP_CIPHER *
EVP_camellia_128_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, camellia_128_cbc);
}
@@ -1150,6 +1216,7 @@ EVP_camellia_128_cbc(void)
const EVP_CIPHER *
EVP_camellia_192_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, camellia_192_cbc);
}
@@ -1164,6 +1231,7 @@ EVP_camellia_192_cbc(void)
const EVP_CIPHER *
EVP_camellia_256_cbc(void)
{
+ hcrypto_validate();
return EVP_DEF_OP(HCRYPTO_DEF_PROVIDER, camellia_256_cbc);
}
@@ -1179,6 +1247,9 @@ static const struct cipher_name {
{ "aes-128-cbc", EVP_aes_128_cbc },
{ "aes-192-cbc", EVP_aes_192_cbc },
{ "aes-256-cbc", EVP_aes_256_cbc },
+ { "aes-128-cfb8", EVP_aes_128_cfb8 },
+ { "aes-192-cfb8", EVP_aes_192_cfb8 },
+ { "aes-256-cfb8", EVP_aes_256_cfb8 },
{ "camellia-128-cbc", EVP_camellia_128_cbc },
{ "camellia-192-cbc", EVP_camellia_192_cbc },
{ "camellia-256-cbc", EVP_camellia_256_cbc }
@@ -1243,7 +1314,8 @@ EVP_BytesToKey(const EVP_CIPHER *type,
void *keydata,
void *ivdata)
{
- int ivlen, keylen, first = 0;
+ unsigned int ivlen, keylen;
+ int first = 0;
unsigned int mds = 0, i;
unsigned char *key = keydata;
unsigned char *iv = ivdata;
diff --git a/source4/heimdal/lib/hcrypto/evp.h b/source4/heimdal/lib/hcrypto/evp.h
index ae92ab4899..03ec175d59 100644
--- a/source4/heimdal/lib/hcrypto/evp.h
+++ b/source4/heimdal/lib/hcrypto/evp.h
@@ -74,6 +74,9 @@
#define EVP_aes_128_cbc hc_EVP_aes_128_cbc
#define EVP_aes_192_cbc hc_EVP_aes_192_cbc
#define EVP_aes_256_cbc hc_EVP_aes_256_cbc
+#define EVP_aes_128_cfb8 hc_EVP_aes_128_cfb8
+#define EVP_aes_192_cfb8 hc_EVP_aes_192_cfb8
+#define EVP_aes_256_cfb8 hc_EVP_aes_256_cfb8
#define EVP_des_cbc hc_EVP_des_cbc
#define EVP_des_ede3_cbc hc_EVP_des_ede3_cbc
@@ -101,6 +104,7 @@
#define OpenSSL_add_all_algorithms_noconf hc_OpenSSL_add_all_algorithms_noconf
#define EVP_CIPHER_CTX_ctrl hc_EVP_CIPHER_CTX_ctrl
#define EVP_CIPHER_CTX_rand_key hc_EVP_CIPHER_CTX_rand_key
+#define hcrypto_validate hc_hcrypto_validate
/*
*
@@ -129,6 +133,7 @@ struct hc_CIPHER {
*/
#define EVP_CIPH_STREAM_CIPHER 0
#define EVP_CIPH_CBC_MODE 2
+#define EVP_CIPH_CFB8_MODE 4
#define EVP_CIPH_MODE 0x7
#define EVP_CIPH_VARIABLE_LENGTH 0x008 /* variable key length */
@@ -224,6 +229,9 @@ const EVP_MD *EVP_sha256(void);
const EVP_CIPHER * EVP_aes_128_cbc(void);
const EVP_CIPHER * EVP_aes_192_cbc(void);
const EVP_CIPHER * EVP_aes_256_cbc(void);
+const EVP_CIPHER * EVP_aes_128_cfb8(void);
+const EVP_CIPHER * EVP_aes_192_cfb8(void);
+const EVP_CIPHER * EVP_aes_256_cfb8(void);
HC_DEPRECATED_CRYPTO const EVP_CIPHER * EVP_des_cbc(void);
const EVP_CIPHER * EVP_des_ede3_cbc(void);
const EVP_CIPHER * EVP_enc_null(void);
@@ -309,6 +317,9 @@ void OpenSSL_add_all_algorithms(void);
void OpenSSL_add_all_algorithms_conf(void);
void OpenSSL_add_all_algorithms_noconf(void);
+void
+hcrypto_validate(void);
+
HC_CPP_END
#endif /* HEIM_EVP_H */
diff --git a/source4/heimdal/lib/hcrypto/hash.h b/source4/heimdal/lib/hcrypto/hash.h
index 78a795f2a7..cfec9cf3f3 100644
--- a/source4/heimdal/lib/hcrypto/hash.h
+++ b/source4/heimdal/lib/hcrypto/hash.h
@@ -37,9 +37,6 @@
#ifndef __hash_h__
#define __hash_h__
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
#ifdef KRB5
#include <krb5-types.h>
#endif
diff --git a/source4/heimdal/lib/hcrypto/imath/imath.c b/source4/heimdal/lib/hcrypto/imath/imath.c
index 4e47a76ce2..0079bafd02 100644
--- a/source4/heimdal/lib/hcrypto/imath/imath.c
+++ b/source4/heimdal/lib/hcrypto/imath/imath.c
@@ -3016,7 +3016,7 @@ STATIC mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
{
mp_digit *db, *dbt, umu, d;
mpz_t temp[3];
- mp_result res;
+ mp_result res = 0;
int last = 0;
umu = MP_USED(mu); db = MP_DIGITS(b); dbt = db + MP_USED(b) - 1;
diff --git a/source4/heimdal/lib/hcrypto/libtommath/LICENSE b/source4/heimdal/lib/hcrypto/libtommath/LICENSE
new file mode 100644
index 0000000000..5baa792a65
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/LICENSE
@@ -0,0 +1,4 @@
+LibTomMath is hereby released into the Public Domain.
+
+-- Tom St Denis
+
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn.ilg b/source4/heimdal/lib/hcrypto/libtommath/bn.ilg
new file mode 100644
index 0000000000..3c859f0346
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn.ilg
@@ -0,0 +1,6 @@
+This is makeindex, version 2.14 [02-Oct-2002] (kpathsea + Thai support).
+Scanning input file bn.idx....done (79 entries accepted, 0 rejected).
+Sorting entries....done (511 comparisons).
+Generating output file bn.ind....done (82 lines written, 0 warnings).
+Output written in bn.ind.
+Transcript written in bn.ilg.
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn.ind b/source4/heimdal/lib/hcrypto/libtommath/bn.ind
new file mode 100644
index 0000000000..c099b521d1
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn.ind
@@ -0,0 +1,82 @@
+\begin{theindex}
+
+ \item mp\_add, \hyperpage{31}
+ \item mp\_add\_d, \hyperpage{56}
+ \item mp\_and, \hyperpage{31}
+ \item mp\_clear, \hyperpage{12}
+ \item mp\_clear\_multi, \hyperpage{13}
+ \item mp\_cmp, \hyperpage{25}
+ \item mp\_cmp\_d, \hyperpage{26}
+ \item mp\_cmp\_mag, \hyperpage{23}
+ \item mp\_div, \hyperpage{32}
+ \item mp\_div\_2, \hyperpage{28}
+ \item mp\_div\_2d, \hyperpage{30}
+ \item mp\_div\_d, \hyperpage{56}
+ \item mp\_dr\_reduce, \hyperpage{45}
+ \item mp\_dr\_setup, \hyperpage{45}
+ \item MP\_EQ, \hyperpage{23}
+ \item mp\_error\_to\_string, \hyperpage{9}
+ \item mp\_expt\_d, \hyperpage{47}
+ \item mp\_exptmod, \hyperpage{47}
+ \item mp\_exteuclid, \hyperpage{55}
+ \item mp\_gcd, \hyperpage{55}
+ \item mp\_get\_int, \hyperpage{20}
+ \item mp\_grow, \hyperpage{17}
+ \item MP\_GT, \hyperpage{23}
+ \item mp\_init, \hyperpage{11}
+ \item mp\_init\_copy, \hyperpage{14}
+ \item mp\_init\_multi, \hyperpage{13}
+ \item mp\_init\_set, \hyperpage{21}
+ \item mp\_init\_set\_int, \hyperpage{21}
+ \item mp\_init\_size, \hyperpage{15}
+ \item mp\_int, \hyperpage{10}
+ \item mp\_invmod, \hyperpage{56}
+ \item mp\_jacobi, \hyperpage{56}
+ \item mp\_lcm, \hyperpage{56}
+ \item mp\_lshd, \hyperpage{30}
+ \item MP\_LT, \hyperpage{23}
+ \item MP\_MEM, \hyperpage{9}
+ \item mp\_mod, \hyperpage{39}
+ \item mp\_mod\_d, \hyperpage{56}
+ \item mp\_montgomery\_calc\_normalization, \hyperpage{42}
+ \item mp\_montgomery\_reduce, \hyperpage{42}
+ \item mp\_montgomery\_setup, \hyperpage{42}
+ \item mp\_mul, \hyperpage{33}
+ \item mp\_mul\_2, \hyperpage{28}
+ \item mp\_mul\_2d, \hyperpage{29}
+ \item mp\_mul\_d, \hyperpage{56}
+ \item mp\_n\_root, \hyperpage{48}
+ \item mp\_neg, \hyperpage{31, 32}
+ \item MP\_NO, \hyperpage{9}
+ \item MP\_OKAY, \hyperpage{9}
+ \item mp\_or, \hyperpage{31}
+ \item mp\_prime\_fermat, \hyperpage{49}
+ \item mp\_prime\_is\_divisible, \hyperpage{49}
+ \item mp\_prime\_is\_prime, \hyperpage{51}
+ \item mp\_prime\_miller\_rabin, \hyperpage{50}
+ \item mp\_prime\_next\_prime, \hyperpage{51}
+ \item mp\_prime\_rabin\_miller\_trials, \hyperpage{50}
+ \item mp\_prime\_random, \hyperpage{51}
+ \item mp\_prime\_random\_ex, \hyperpage{52}
+ \item mp\_radix\_size, \hyperpage{53}
+ \item mp\_read\_radix, \hyperpage{53}
+ \item mp\_read\_unsigned\_bin, \hyperpage{54}
+ \item mp\_reduce, \hyperpage{40}
+ \item mp\_reduce\_2k, \hyperpage{46}
+ \item mp\_reduce\_2k\_setup, \hyperpage{46}
+ \item mp\_reduce\_setup, \hyperpage{40}
+ \item mp\_rshd, \hyperpage{30}
+ \item mp\_set, \hyperpage{19}
+ \item mp\_set\_int, \hyperpage{20}
+ \item mp\_shrink, \hyperpage{16}
+ \item mp\_sqr, \hyperpage{35}
+ \item mp\_sub, \hyperpage{31}
+ \item mp\_sub\_d, \hyperpage{56}
+ \item mp\_to\_unsigned\_bin, \hyperpage{54}
+ \item mp\_toradix, \hyperpage{53}
+ \item mp\_unsigned\_bin\_size, \hyperpage{54}
+ \item MP\_VAL, \hyperpage{9}
+ \item mp\_xor, \hyperpage{31}
+ \item MP\_YES, \hyperpage{9}
+
+\end{theindex}
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_error.c b/source4/heimdal/lib/hcrypto/libtommath/bn_error.c
new file mode 100644
index 0000000000..b1b7177e61
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_error.c
@@ -0,0 +1,47 @@
+#include <tommath.h>
+#ifdef BN_ERROR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+static const struct {
+ int code;
+ char *msg;
+} msgs[] = {
+ { MP_OKAY, "Successful" },
+ { MP_MEM, "Out of heap" },
+ { MP_VAL, "Value out of range" }
+};
+
+/* return a char * string for a given code */
+char *mp_error_to_string(int code)
+{
+ int x;
+
+ /* scan the lookup table for the given message */
+ for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
+ if (msgs[x].code == code) {
+ return msgs[x].msg;
+ }
+ }
+
+ /* generic reply for invalid code */
+ return "Invalid error code";
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_error.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_fast_mp_invmod.c b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_mp_invmod.c
new file mode 100644
index 0000000000..ff03dfffe3
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_mp_invmod.c
@@ -0,0 +1,148 @@
+#include <tommath.h>
+#ifdef BN_FAST_MP_INVMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* computes the modular inverse via binary extended euclidean algorithm,
+ * that is c = 1/a mod b
+ *
+ * Based on slow invmod except this is optimized for the case where b is
+ * odd as per HAC Note 14.64 on pp. 610
+ */
+int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int x, y, u, v, B, D;
+ int res, neg;
+
+ /* 2. [modified] b must be odd */
+ if (mp_iseven (b) == 1) {
+ return MP_VAL;
+ }
+
+ /* init all our temps */
+ if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* x == modulus, y == value to invert */
+ if ((res = mp_copy (b, &x)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ /* we need y = |a| */
+ if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+ if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ mp_set (&D, 1);
+
+top:
+ /* 4. while u is even do */
+ while (mp_iseven (&u) == 1) {
+ /* 4.1 u = u/2 */
+ if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ /* 4.2 if B is odd then */
+ if (mp_isodd (&B) == 1) {
+ if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ /* B = B/2 */
+ if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* 5. while v is even do */
+ while (mp_iseven (&v) == 1) {
+ /* 5.1 v = v/2 */
+ if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ /* 5.2 if D is odd then */
+ if (mp_isodd (&D) == 1) {
+ /* D = (D-x)/2 */
+ if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ /* D = D/2 */
+ if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* 6. if u >= v then */
+ if (mp_cmp (&u, &v) != MP_LT) {
+ /* u = u - v, B = B - D */
+ if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ } else {
+ /* v - v - u, D = D - B */
+ if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* if not zero goto step 4 */
+ if (mp_iszero (&u) == 0) {
+ goto top;
+ }
+
+ /* now a = C, b = D, gcd == g*v */
+
+ /* if v != 1 then there is no inverse */
+ if (mp_cmp_d (&v, 1) != MP_EQ) {
+ res = MP_VAL;
+ goto LBL_ERR;
+ }
+
+ /* b is now the inverse */
+ neg = a->sign;
+ while (D.sign == MP_NEG) {
+ if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ mp_exch (&D, c);
+ c->sign = neg;
+ res = MP_OKAY;
+
+LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_mp_invmod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_fast_mp_montgomery_reduce.c b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_mp_montgomery_reduce.c
new file mode 100644
index 0000000000..b6c0694bd2
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_mp_montgomery_reduce.c
@@ -0,0 +1,172 @@
+#include <tommath.h>
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction
+ *
+ * This is an optimized implementation of montgomery_reduce
+ * which uses the comba method to quickly calculate the columns of the
+ * reduction.
+ *
+ * Based on Algorithm 14.32 on pp.601 of HAC.
+*/
+int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+ int ix, res, olduse;
+ mp_word W[MP_WARRAY];
+
+ /* get old used count */
+ olduse = x->used;
+
+ /* grow a as required */
+ if (x->alloc < n->used + 1) {
+ if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* first we have to get the digits of the input into
+ * an array of double precision words W[...]
+ */
+ {
+ register mp_word *_W;
+ register mp_digit *tmpx;
+
+ /* alias for the W[] array */
+ _W = W;
+
+ /* alias for the digits of x*/
+ tmpx = x->dp;
+
+ /* copy the digits of a into W[0..a->used-1] */
+ for (ix = 0; ix < x->used; ix++) {
+ *_W++ = *tmpx++;
+ }
+
+ /* zero the high words of W[a->used..m->used*2] */
+ for (; ix < n->used * 2 + 1; ix++) {
+ *_W++ = 0;
+ }
+ }
+
+ /* now we proceed to zero successive digits
+ * from the least significant upwards
+ */
+ for (ix = 0; ix < n->used; ix++) {
+ /* mu = ai * m' mod b
+ *
+ * We avoid a double precision multiplication (which isn't required)
+ * by casting the value down to a mp_digit. Note this requires
+ * that W[ix-1] have the carry cleared (see after the inner loop)
+ */
+ register mp_digit mu;
+ mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
+
+ /* a = a + mu * m * b**i
+ *
+ * This is computed in place and on the fly. The multiplication
+ * by b**i is handled by offseting which columns the results
+ * are added to.
+ *
+ * Note the comba method normally doesn't handle carries in the
+ * inner loop In this case we fix the carry from the previous
+ * column since the Montgomery reduction requires digits of the
+ * result (so far) [see above] to work. This is
+ * handled by fixing up one carry after the inner loop. The
+ * carry fixups are done in order so after these loops the
+ * first m->used words of W[] have the carries fixed
+ */
+ {
+ register int iy;
+ register mp_digit *tmpn;
+ register mp_word *_W;
+
+ /* alias for the digits of the modulus */
+ tmpn = n->dp;
+
+ /* Alias for the columns set by an offset of ix */
+ _W = W + ix;
+
+ /* inner loop */
+ for (iy = 0; iy < n->used; iy++) {
+ *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
+ }
+ }
+
+ /* now fix carry for next digit, W[ix+1] */
+ W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
+ }
+
+ /* now we have to propagate the carries and
+ * shift the words downward [all those least
+ * significant digits we zeroed].
+ */
+ {
+ register mp_digit *tmpx;
+ register mp_word *_W, *_W1;
+
+ /* nox fix rest of carries */
+
+ /* alias for current word */
+ _W1 = W + ix;
+
+ /* alias for next word, where the carry goes */
+ _W = W + ++ix;
+
+ for (; ix <= n->used * 2 + 1; ix++) {
+ *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
+ }
+
+ /* copy out, A = A/b**n
+ *
+ * The result is A/b**n but instead of converting from an
+ * array of mp_word to mp_digit than calling mp_rshd
+ * we just copy them in the right order
+ */
+
+ /* alias for destination word */
+ tmpx = x->dp;
+
+ /* alias for shifted double precision result */
+ _W = W + n->used;
+
+ for (ix = 0; ix < n->used + 1; ix++) {
+ *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
+ }
+
+ /* zero oldused digits, if the input a was larger than
+ * m->used+1 we'll have to clear the digits
+ */
+ for (; ix < olduse; ix++) {
+ *tmpx++ = 0;
+ }
+ }
+
+ /* set the max used and clamp */
+ x->used = n->used + 1;
+ mp_clamp (x);
+
+ /* if A >= m then A = A - m */
+ if (mp_cmp_mag (x, n) != MP_LT) {
+ return s_mp_sub (x, n, x);
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_mp_montgomery_reduce.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_mul_digs.c b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_mul_digs.c
new file mode 100644
index 0000000000..91e10d670f
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_mul_digs.c
@@ -0,0 +1,107 @@
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* Fast (comba) multiplier
+ *
+ * This is the fast column-array [comba] multiplier. It is
+ * designed to compute the columns of the product first
+ * then handle the carries afterwards. This has the effect
+ * of making the nested loops that compute the columns very
+ * simple and schedulable on super-scalar processors.
+ *
+ * This has been modified to produce a variable number of
+ * digits of output so if say only a half-product is required
+ * you don't have to compute the upper half (a feature
+ * required for fast Barrett reduction).
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ *
+ */
+int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ int olduse, res, pa, ix, iz;
+ mp_digit W[MP_WARRAY];
+ register mp_word _W;
+
+ /* grow the destination as required */
+ if (c->alloc < digs) {
+ if ((res = mp_grow (c, digs)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* number of output digits to produce */
+ pa = MIN(digs, a->used + b->used);
+
+ /* clear the carry */
+ _W = 0;
+ for (ix = 0; ix < pa; ix++) {
+ int tx, ty;
+ int iy;
+ mp_digit *tmpx, *tmpy;
+
+ /* get offsets into the two bignums */
+ ty = MIN(b->used-1, ix);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = a->dp + tx;
+ tmpy = b->dp + ty;
+
+ /* this is the number of times the loop will iterrate, essentially
+ while (tx++ < a->used && ty-- >= 0) { ... }
+ */
+ iy = MIN(a->used-tx, ty+1);
+
+ /* execute loop */
+ for (iz = 0; iz < iy; ++iz) {
+ _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+
+ }
+
+ /* store term */
+ W[ix] = ((mp_digit)_W) & MP_MASK;
+
+ /* make next carry */
+ _W = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+ /* setup dest */
+ olduse = c->used;
+ c->used = pa;
+
+ {
+ register mp_digit *tmpc;
+ tmpc = c->dp;
+ for (ix = 0; ix < pa+1; ix++) {
+ /* now extract the previous digit [below the carry] */
+ *tmpc++ = W[ix];
+ }
+
+ /* clear unused digits [that existed in the old copy of c] */
+ for (; ix < olduse; ix++) {
+ *tmpc++ = 0;
+ }
+ }
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_digs.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_mul_high_digs.c b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_mul_high_digs.c
new file mode 100644
index 0000000000..5b114d717a
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_mul_high_digs.c
@@ -0,0 +1,98 @@
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* this is a modified version of fast_s_mul_digs that only produces
+ * output digits *above* digs. See the comments for fast_s_mul_digs
+ * to see how it works.
+ *
+ * This is used in the Barrett reduction since for one of the multiplications
+ * only the higher digits were needed. This essentially halves the work.
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ */
+int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ int olduse, res, pa, ix, iz;
+ mp_digit W[MP_WARRAY];
+ mp_word _W;
+
+ /* grow the destination as required */
+ pa = a->used + b->used;
+ if (c->alloc < pa) {
+ if ((res = mp_grow (c, pa)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* number of output digits to produce */
+ pa = a->used + b->used;
+ _W = 0;
+ for (ix = digs; ix < pa; ix++) {
+ int tx, ty, iy;
+ mp_digit *tmpx, *tmpy;
+
+ /* get offsets into the two bignums */
+ ty = MIN(b->used-1, ix);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = a->dp + tx;
+ tmpy = b->dp + ty;
+
+ /* this is the number of times the loop will iterrate, essentially its
+ while (tx++ < a->used && ty-- >= 0) { ... }
+ */
+ iy = MIN(a->used-tx, ty+1);
+
+ /* execute loop */
+ for (iz = 0; iz < iy; iz++) {
+ _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+ }
+
+ /* store term */
+ W[ix] = ((mp_digit)_W) & MP_MASK;
+
+ /* make next carry */
+ _W = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+ /* setup dest */
+ olduse = c->used;
+ c->used = pa;
+
+ {
+ register mp_digit *tmpc;
+
+ tmpc = c->dp + digs;
+ for (ix = digs; ix < pa; ix++) {
+ /* now extract the previous digit [below the carry] */
+ *tmpc++ = W[ix];
+ }
+
+ /* clear unused digits [that existed in the old copy of c] */
+ for (; ix < olduse; ix++) {
+ *tmpc++ = 0;
+ }
+ }
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_mul_high_digs.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_sqr.c b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_sqr.c
new file mode 100644
index 0000000000..19e92ef180
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_fast_s_mp_sqr.c
@@ -0,0 +1,114 @@
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* the jist of squaring...
+ * you do like mult except the offset of the tmpx [one that
+ * starts closer to zero] can't equal the offset of tmpy.
+ * So basically you set up iy like before then you min it with
+ * (ty-tx) so that it never happens. You double all those
+ * you add in the inner loop
+
+After that loop you do the squares and add them in.
+*/
+
+int fast_s_mp_sqr (mp_int * a, mp_int * b)
+{
+ int olduse, res, pa, ix, iz;
+ mp_digit W[MP_WARRAY], *tmpx;
+ mp_word W1;
+
+ /* grow the destination as required */
+ pa = a->used + a->used;
+ if (b->alloc < pa) {
+ if ((res = mp_grow (b, pa)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* number of output digits to produce */
+ W1 = 0;
+ for (ix = 0; ix < pa; ix++) {
+ int tx, ty, iy;
+ mp_word _W;
+ mp_digit *tmpy;
+
+ /* clear counter */
+ _W = 0;
+
+ /* get offsets into the two bignums */
+ ty = MIN(a->used-1, ix);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = a->dp + tx;
+ tmpy = a->dp + ty;
+
+ /* this is the number of times the loop will iterrate, essentially
+ while (tx++ < a->used && ty-- >= 0) { ... }
+ */
+ iy = MIN(a->used-tx, ty+1);
+
+ /* now for squaring tx can never equal ty
+ * we halve the distance since they approach at a rate of 2x
+ * and we have to round because odd cases need to be executed
+ */
+ iy = MIN(iy, (ty-tx+1)>>1);
+
+ /* execute loop */
+ for (iz = 0; iz < iy; iz++) {
+ _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+ }
+
+ /* double the inner product and add carry */
+ _W = _W + _W + W1;
+
+ /* even columns have the square term in them */
+ if ((ix&1) == 0) {
+ _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
+ }
+
+ /* store it */
+ W[ix] = (mp_digit)(_W & MP_MASK);
+
+ /* make next carry */
+ W1 = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+ /* setup dest */
+ olduse = b->used;
+ b->used = a->used+a->used;
+
+ {
+ mp_digit *tmpb;
+ tmpb = b->dp;
+ for (ix = 0; ix < pa; ix++) {
+ *tmpb++ = W[ix] & MP_MASK;
+ }
+
+ /* clear unused digits [that existed in the old copy of c] */
+ for (; ix < olduse; ix++) {
+ *tmpb++ = 0;
+ }
+ }
+ mp_clamp (b);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_fast_s_mp_sqr.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_2expt.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_2expt.c
new file mode 100644
index 0000000000..f422ffc994
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_2expt.c
@@ -0,0 +1,48 @@
+#include <tommath.h>
+#ifdef BN_MP_2EXPT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* computes a = 2**b
+ *
+ * Simple algorithm which zeroes the int, grows it then just sets one bit
+ * as required.
+ */
+int
+mp_2expt (mp_int * a, int b)
+{
+ int res;
+
+ /* zero a as per default */
+ mp_zero (a);
+
+ /* grow a to accomodate the single bit */
+ if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
+ return res;
+ }
+
+ /* set the used count of where the bit will go */
+ a->used = b / DIGIT_BIT + 1;
+
+ /* put the single bit in its place */
+ a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_2expt.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_abs.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_abs.c
new file mode 100644
index 0000000000..09dd7229eb
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_abs.c
@@ -0,0 +1,43 @@
+#include <tommath.h>
+#ifdef BN_MP_ABS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* b = |a|
+ *
+ * Simple function copies the input and fixes the sign to positive
+ */
+int
+mp_abs (mp_int * a, mp_int * b)
+{
+ int res;
+
+ /* copy a to b */
+ if (a != b) {
+ if ((res = mp_copy (a, b)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* force the sign of b to positive */
+ b->sign = MP_ZPOS;
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_abs.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_add.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_add.c
new file mode 100644
index 0000000000..be20644770
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_add.c
@@ -0,0 +1,53 @@
+#include <tommath.h>
+#ifdef BN_MP_ADD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* high level addition (handles signs) */
+int mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+ int sa, sb, res;
+
+ /* get sign of both inputs */
+ sa = a->sign;
+ sb = b->sign;
+
+ /* handle two cases, not four */
+ if (sa == sb) {
+ /* both positive or both negative */
+ /* add their magnitudes, copy the sign */
+ c->sign = sa;
+ res = s_mp_add (a, b, c);
+ } else {
+ /* one positive, the other negative */
+ /* subtract the one with the greater magnitude from */
+ /* the one of the lesser magnitude. The result gets */
+ /* the sign of the one with the greater magnitude. */
+ if (mp_cmp_mag (a, b) == MP_LT) {
+ c->sign = sb;
+ res = s_mp_sub (b, a, c);
+ } else {
+ c->sign = sa;
+ res = s_mp_sub (a, b, c);
+ }
+ }
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_add.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_add_d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_add_d.c
new file mode 100644
index 0000000000..8ca36c1124
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_add_d.c
@@ -0,0 +1,112 @@
+#include <tommath.h>
+#ifdef BN_MP_ADD_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* single digit addition */
+int
+mp_add_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ int res, ix, oldused;
+ mp_digit *tmpa, *tmpc, mu;
+
+ /* grow c as required */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* if a is negative and |a| >= b, call c = |a| - b */
+ if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
+ /* temporarily fix sign of a */
+ a->sign = MP_ZPOS;
+
+ /* c = |a| - b */
+ res = mp_sub_d(a, b, c);
+
+ /* fix sign */
+ a->sign = c->sign = MP_NEG;
+
+ /* clamp */
+ mp_clamp(c);
+
+ return res;
+ }
+
+ /* old number of used digits in c */
+ oldused = c->used;
+
+ /* sign always positive */
+ c->sign = MP_ZPOS;
+
+ /* source alias */
+ tmpa = a->dp;
+
+ /* destination alias */
+ tmpc = c->dp;
+
+ /* if a is positive */
+ if (a->sign == MP_ZPOS) {
+ /* add digit, after this we're propagating
+ * the carry.
+ */
+ *tmpc = *tmpa++ + b;
+ mu = *tmpc >> DIGIT_BIT;
+ *tmpc++ &= MP_MASK;
+
+ /* now handle rest of the digits */
+ for (ix = 1; ix < a->used; ix++) {
+ *tmpc = *tmpa++ + mu;
+ mu = *tmpc >> DIGIT_BIT;
+ *tmpc++ &= MP_MASK;
+ }
+ /* set final carry */
+ ix++;
+ *tmpc++ = mu;
+
+ /* setup size */
+ c->used = a->used + 1;
+ } else {
+ /* a was negative and |a| < b */
+ c->used = 1;
+
+ /* the result is a single digit */
+ if (a->used == 1) {
+ *tmpc++ = b - a->dp[0];
+ } else {
+ *tmpc++ = b;
+ }
+
+ /* setup count so the clearing of oldused
+ * can fall through correctly
+ */
+ ix = 1;
+ }
+
+ /* now zero to oldused */
+ while (ix++ < oldused) {
+ *tmpc++ = 0;
+ }
+ mp_clamp(c);
+
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_add_d.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_addmod.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_addmod.c
new file mode 100644
index 0000000000..6d8afe18c9
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_addmod.c
@@ -0,0 +1,41 @@
+#include <tommath.h>
+#ifdef BN_MP_ADDMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* d = a + b (mod c) */
+int
+mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ int res;
+ mp_int t;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_add (a, b, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ res = mp_mod (&t, c, d);
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_addmod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_and.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_and.c
new file mode 100644
index 0000000000..8ea22878f9
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_and.c
@@ -0,0 +1,57 @@
+#include <tommath.h>
+#ifdef BN_MP_AND_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* AND two ints together */
+int
+mp_and (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, ix, px;
+ mp_int t, *x;
+
+ if (a->used > b->used) {
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+ px = b->used;
+ x = b;
+ } else {
+ if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+ return res;
+ }
+ px = a->used;
+ x = a;
+ }
+
+ for (ix = 0; ix < px; ix++) {
+ t.dp[ix] &= x->dp[ix];
+ }
+
+ /* zero digits above the last from the smallest mp_int */
+ for (; ix < t.used; ix++) {
+ t.dp[ix] = 0;
+ }
+
+ mp_clamp (&t);
+ mp_exch (c, &t);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_and.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_clamp.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_clamp.c
new file mode 100644
index 0000000000..359c2ff24d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_clamp.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_CLAMP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* trim unused digits
+ *
+ * This is used to ensure that leading zero digits are
+ * trimed and the leading "used" digit will be non-zero
+ * Typically very fast. Also fixes the sign if there
+ * are no more leading digits
+ */
+void
+mp_clamp (mp_int * a)
+{
+ /* decrease used while the most significant digit is
+ * zero.
+ */
+ while (a->used > 0 && a->dp[a->used - 1] == 0) {
+ --(a->used);
+ }
+
+ /* reset the sign flag if used == 0 */
+ if (a->used == 0) {
+ a->sign = MP_ZPOS;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_clamp.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_clear.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_clear.c
new file mode 100644
index 0000000000..a65f0a36c4
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_clear.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_CLEAR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* clear one (frees) */
+void
+mp_clear (mp_int * a)
+{
+ int i;
+
+ /* only do anything if a hasn't been freed previously */
+ if (a->dp != NULL) {
+ /* first zero the digits */
+ for (i = 0; i < a->used; i++) {
+ a->dp[i] = 0;
+ }
+
+ /* free ram */
+ XFREE(a->dp);
+
+ /* reset members to make debugging easier */
+ a->dp = NULL;
+ a->alloc = a->used = 0;
+ a->sign = MP_ZPOS;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_clear.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_clear_multi.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_clear_multi.c
new file mode 100644
index 0000000000..daaea79a3b
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_clear_multi.c
@@ -0,0 +1,34 @@
+#include <tommath.h>
+#ifdef BN_MP_CLEAR_MULTI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+#include <stdarg.h>
+
+void mp_clear_multi(mp_int *mp, ...)
+{
+ mp_int* next_mp = mp;
+ va_list args;
+ va_start(args, mp);
+ while (next_mp != NULL) {
+ mp_clear(next_mp);
+ next_mp = va_arg(args, mp_int*);
+ }
+ va_end(args);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_clear_multi.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp.c
new file mode 100644
index 0000000000..533f36bf93
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp.c
@@ -0,0 +1,43 @@
+#include <tommath.h>
+#ifdef BN_MP_CMP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* compare two ints (signed)*/
+int
+mp_cmp (mp_int * a, mp_int * b)
+{
+ /* compare based on sign */
+ if (a->sign != b->sign) {
+ if (a->sign == MP_NEG) {
+ return MP_LT;
+ } else {
+ return MP_GT;
+ }
+ }
+
+ /* compare digits */
+ if (a->sign == MP_NEG) {
+ /* if negative compare opposite direction */
+ return mp_cmp_mag(b, a);
+ } else {
+ return mp_cmp_mag(a, b);
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_cmp.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp_d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp_d.c
new file mode 100644
index 0000000000..724c1c3634
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp_d.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_CMP_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* compare a digit */
+int mp_cmp_d(mp_int * a, mp_digit b)
+{
+ /* compare based on sign */
+ if (a->sign == MP_NEG) {
+ return MP_LT;
+ }
+
+ /* compare based on magnitude */
+ if (a->used > 1) {
+ return MP_GT;
+ }
+
+ /* compare the only digit of a to b */
+ if (a->dp[0] > b) {
+ return MP_GT;
+ } else if (a->dp[0] < b) {
+ return MP_LT;
+ } else {
+ return MP_EQ;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp_mag.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp_mag.c
new file mode 100644
index 0000000000..693eb7cc72
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cmp_mag.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_CMP_MAG_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* compare maginitude of two ints (unsigned) */
+int mp_cmp_mag (mp_int * a, mp_int * b)
+{
+ int n;
+ mp_digit *tmpa, *tmpb;
+
+ /* compare based on # of non-zero digits */
+ if (a->used > b->used) {
+ return MP_GT;
+ }
+
+ if (a->used < b->used) {
+ return MP_LT;
+ }
+
+ /* alias for a */
+ tmpa = a->dp + (a->used - 1);
+
+ /* alias for b */
+ tmpb = b->dp + (a->used - 1);
+
+ /* compare based on digits */
+ for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
+ if (*tmpa > *tmpb) {
+ return MP_GT;
+ }
+
+ if (*tmpa < *tmpb) {
+ return MP_LT;
+ }
+ }
+ return MP_EQ;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_cmp_mag.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cnt_lsb.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cnt_lsb.c
new file mode 100644
index 0000000000..66d1a74714
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_cnt_lsb.c
@@ -0,0 +1,53 @@
+#include <tommath.h>
+#ifdef BN_MP_CNT_LSB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+static const int lnz[16] = {
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(mp_int *a)
+{
+ int x;
+ mp_digit q, qq;
+
+ /* easy out */
+ if (mp_iszero(a) == 1) {
+ return 0;
+ }
+
+ /* scan lower digits until non-zero */
+ for (x = 0; x < a->used && a->dp[x] == 0; x++);
+ q = a->dp[x];
+ x *= DIGIT_BIT;
+
+ /* now scan this digit until a 1 is found */
+ if ((q & 1) == 0) {
+ do {
+ qq = q & 15;
+ x += lnz[qq];
+ q >>= 4;
+ } while (qq == 0);
+ }
+ return x;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_cnt_lsb.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_copy.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_copy.c
new file mode 100644
index 0000000000..b0de16d8ab
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_copy.c
@@ -0,0 +1,68 @@
+#include <tommath.h>
+#ifdef BN_MP_COPY_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* copy, b = a */
+int
+mp_copy (mp_int * a, mp_int * b)
+{
+ int res, n;
+
+ /* if dst == src do nothing */
+ if (a == b) {
+ return MP_OKAY;
+ }
+
+ /* grow dest */
+ if (b->alloc < a->used) {
+ if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* zero b and copy the parameters over */
+ {
+ register mp_digit *tmpa, *tmpb;
+
+ /* pointer aliases */
+
+ /* source */
+ tmpa = a->dp;
+
+ /* destination */
+ tmpb = b->dp;
+
+ /* copy all the digits */
+ for (n = 0; n < a->used; n++) {
+ *tmpb++ = *tmpa++;
+ }
+
+ /* clear high digits */
+ for (; n < b->used; n++) {
+ *tmpb++ = 0;
+ }
+ }
+
+ /* copy used count and sign */
+ b->used = a->used;
+ b->sign = a->sign;
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_copy.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_count_bits.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_count_bits.c
new file mode 100644
index 0000000000..8bc5657a33
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_count_bits.c
@@ -0,0 +1,45 @@
+#include <tommath.h>
+#ifdef BN_MP_COUNT_BITS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* returns the number of bits in an int */
+int
+mp_count_bits (mp_int * a)
+{
+ int r;
+ mp_digit q;
+
+ /* shortcut */
+ if (a->used == 0) {
+ return 0;
+ }
+
+ /* get number of digits and add that */
+ r = (a->used - 1) * DIGIT_BIT;
+
+ /* take the last digit and count the bits in it */
+ q = a->dp[a->used - 1];
+ while (q > ((mp_digit) 0)) {
+ ++r;
+ q >>= ((mp_digit) 1);
+ }
+ return r;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_count_bits.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div.c
new file mode 100644
index 0000000000..aee9c94324
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div.c
@@ -0,0 +1,292 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+#ifdef BN_MP_DIV_SMALL
+
+/* slower bit-bang division... also smaller */
+int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ mp_int ta, tb, tq, q;
+ int res, n, n2;
+
+ /* is divisor zero ? */
+ if (mp_iszero (b) == 1) {
+ return MP_VAL;
+ }
+
+ /* if a < b then q=0, r = a */
+ if (mp_cmp_mag (a, b) == MP_LT) {
+ if (d != NULL) {
+ res = mp_copy (a, d);
+ } else {
+ res = MP_OKAY;
+ }
+ if (c != NULL) {
+ mp_zero (c);
+ }
+ return res;
+ }
+
+ /* init our temps */
+ if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {
+ return res;
+ }
+
+
+ mp_set(&tq, 1);
+ n = mp_count_bits(a) - mp_count_bits(b);
+ if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
+ ((res = mp_abs(b, &tb)) != MP_OKAY) ||
+ ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
+ ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
+ goto LBL_ERR;
+ }
+
+ while (n-- >= 0) {
+ if (mp_cmp(&tb, &ta) != MP_GT) {
+ if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
+ ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
+ goto LBL_ERR;
+ }
+ }
+ if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
+ ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* now q == quotient and ta == remainder */
+ n = a->sign;
+ n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
+ if (c != NULL) {
+ mp_exch(c, &q);
+ c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
+ }
+ if (d != NULL) {
+ mp_exch(d, &ta);
+ d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
+ }
+LBL_ERR:
+ mp_clear_multi(&ta, &tb, &tq, &q, NULL);
+ return res;
+}
+
+#else
+
+/* integer signed division.
+ * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
+ * HAC pp.598 Algorithm 14.20
+ *
+ * Note that the description in HAC is horribly
+ * incomplete. For example, it doesn't consider
+ * the case where digits are removed from 'x' in
+ * the inner loop. It also doesn't consider the
+ * case that y has fewer than three digits, etc..
+ *
+ * The overall algorithm is as described as
+ * 14.20 from HAC but fixed to treat these cases.
+*/
+int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ mp_int q, x, y, t1, t2;
+ int res, n, t, i, norm, neg;
+
+ /* is divisor zero ? */
+ if (mp_iszero (b) == 1) {
+ return MP_VAL;
+ }
+
+ /* if a < b then q=0, r = a */
+ if (mp_cmp_mag (a, b) == MP_LT) {
+ if (d != NULL) {
+ res = mp_copy (a, d);
+ } else {
+ res = MP_OKAY;
+ }
+ if (c != NULL) {
+ mp_zero (c);
+ }
+ return res;
+ }
+
+ if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
+ return res;
+ }
+ q.used = a->used + 2;
+
+ if ((res = mp_init (&t1)) != MP_OKAY) {
+ goto LBL_Q;
+ }
+
+ if ((res = mp_init (&t2)) != MP_OKAY) {
+ goto LBL_T1;
+ }
+
+ if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
+ goto LBL_T2;
+ }
+
+ if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
+ goto LBL_X;
+ }
+
+ /* fix the sign */
+ neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+ x.sign = y.sign = MP_ZPOS;
+
+ /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
+ norm = mp_count_bits(&y) % DIGIT_BIT;
+ if (norm < (int)(DIGIT_BIT-1)) {
+ norm = (DIGIT_BIT-1) - norm;
+ if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ } else {
+ norm = 0;
+ }
+
+ /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
+ n = x.used - 1;
+ t = y.used - 1;
+
+ /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
+ if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
+ goto LBL_Y;
+ }
+
+ while (mp_cmp (&x, &y) != MP_LT) {
+ ++(q.dp[n - t]);
+ if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ }
+
+ /* reset y by shifting it back down */
+ mp_rshd (&y, n - t);
+
+ /* step 3. for i from n down to (t + 1) */
+ for (i = n; i >= (t + 1); i--) {
+ if (i > x.used) {
+ continue;
+ }
+
+ /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
+ * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
+ if (x.dp[i] == y.dp[t]) {
+ q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
+ } else {
+ mp_word tmp;
+ tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
+ tmp |= ((mp_word) x.dp[i - 1]);
+ tmp /= ((mp_word) y.dp[t]);
+ if (tmp > (mp_word) MP_MASK)
+ tmp = MP_MASK;
+ q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
+ }
+
+ /* while (q{i-t-1} * (yt * b + y{t-1})) >
+ xi * b**2 + xi-1 * b + xi-2
+
+ do q{i-t-1} -= 1;
+ */
+ q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
+ do {
+ q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;
+
+ /* find left hand */
+ mp_zero (&t1);
+ t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
+ t1.dp[1] = y.dp[t];
+ t1.used = 2;
+ if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* find right hand */
+ t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
+ t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
+ t2.dp[2] = x.dp[i];
+ t2.used = 3;
+ } while (mp_cmp_mag(&t1, &t2) == MP_GT);
+
+ /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
+ if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
+ if (x.sign == MP_NEG) {
+ if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
+ }
+ }
+
+ /* now q is the quotient and x is the remainder
+ * [which we have to normalize]
+ */
+
+ /* get sign before writing to c */
+ x.sign = x.used == 0 ? MP_ZPOS : a->sign;
+
+ if (c != NULL) {
+ mp_clamp (&q);
+ mp_exch (&q, c);
+ c->sign = neg;
+ }
+
+ if (d != NULL) {
+ mp_div_2d (&x, norm, &x, NULL);
+ mp_exch (&x, d);
+ }
+
+ res = MP_OKAY;
+
+LBL_Y:mp_clear (&y);
+LBL_X:mp_clear (&x);
+LBL_T2:mp_clear (&t2);
+LBL_T1:mp_clear (&t1);
+LBL_Q:mp_clear (&q);
+ return res;
+}
+
+#endif
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_2.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_2.c
new file mode 100644
index 0000000000..7ee3e5b70f
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_2.c
@@ -0,0 +1,68 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_2_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* b = a/2 */
+int mp_div_2(mp_int * a, mp_int * b)
+{
+ int x, res, oldused;
+
+ /* copy */
+ if (b->alloc < a->used) {
+ if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ oldused = b->used;
+ b->used = a->used;
+ {
+ register mp_digit r, rr, *tmpa, *tmpb;
+
+ /* source alias */
+ tmpa = a->dp + b->used - 1;
+
+ /* dest alias */
+ tmpb = b->dp + b->used - 1;
+
+ /* carry */
+ r = 0;
+ for (x = b->used - 1; x >= 0; x--) {
+ /* get the carry for the next iteration */
+ rr = *tmpa & 1;
+
+ /* shift the current digit, add in carry and store */
+ *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
+
+ /* forward carry to next iteration */
+ r = rr;
+ }
+
+ /* zero excess digits */
+ tmpb = b->dp + b->used;
+ for (x = b->used; x < oldused; x++) {
+ *tmpb++ = 0;
+ }
+ }
+ b->sign = a->sign;
+ mp_clamp (b);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div_2.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_2d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_2d.c
new file mode 100644
index 0000000000..4f7fa59e3f
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_2d.c
@@ -0,0 +1,97 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* shift right by a certain bit count (store quotient in c, optional remainder in d) */
+int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
+{
+ mp_digit D, r, rr;
+ int x, res;
+ mp_int t;
+
+
+ /* if the shift count is <= 0 then we do no work */
+ if (b <= 0) {
+ res = mp_copy (a, c);
+ if (d != NULL) {
+ mp_zero (d);
+ }
+ return res;
+ }
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ /* get the remainder */
+ if (d != NULL) {
+ if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ }
+
+ /* copy */
+ if ((res = mp_copy (a, c)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+
+ /* shift by as many digits in the bit count */
+ if (b >= (int)DIGIT_BIT) {
+ mp_rshd (c, b / DIGIT_BIT);
+ }
+
+ /* shift any bit count < DIGIT_BIT */
+ D = (mp_digit) (b % DIGIT_BIT);
+ if (D != 0) {
+ register mp_digit *tmpc, mask, shift;
+
+ /* mask */
+ mask = (((mp_digit)1) << D) - 1;
+
+ /* shift for lsb */
+ shift = DIGIT_BIT - D;
+
+ /* alias */
+ tmpc = c->dp + (c->used - 1);
+
+ /* carry */
+ r = 0;
+ for (x = c->used - 1; x >= 0; x--) {
+ /* get the lower bits of this word in a temp */
+ rr = *tmpc & mask;
+
+ /* shift the current word and mix in the carry bits from the previous word */
+ *tmpc = (*tmpc >> D) | (r << shift);
+ --tmpc;
+
+ /* set the carry to the carry bits of the current word found above */
+ r = rr;
+ }
+ }
+ mp_clamp (c);
+ if (d != NULL) {
+ mp_exch (&t, d);
+ }
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div_2d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_3.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_3.c
new file mode 100644
index 0000000000..3c60269ece
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_3.c
@@ -0,0 +1,79 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_3_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* divide by three (based on routine from MPI and the GMP manual) */
+int
+mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
+{
+ mp_int q;
+ mp_word w, t;
+ mp_digit b;
+ int res, ix;
+
+ /* b = 2**DIGIT_BIT / 3 */
+ b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
+
+ if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+ return res;
+ }
+
+ q.used = a->used;
+ q.sign = a->sign;
+ w = 0;
+ for (ix = a->used - 1; ix >= 0; ix--) {
+ w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+ if (w >= 3) {
+ /* multiply w by [1/3] */
+ t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
+
+ /* now subtract 3 * [w/3] from w, to get the remainder */
+ w -= t+t+t;
+
+ /* fixup the remainder as required since
+ * the optimization is not exact.
+ */
+ while (w >= 3) {
+ t += 1;
+ w -= 3;
+ }
+ } else {
+ t = 0;
+ }
+ q.dp[ix] = (mp_digit)t;
+ }
+
+ /* [optional] store the remainder */
+ if (d != NULL) {
+ *d = (mp_digit)w;
+ }
+
+ /* [optional] store the quotient */
+ if (c != NULL) {
+ mp_clamp(&q);
+ mp_exch(&q, c);
+ }
+ mp_clear(&q);
+
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div_3.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_d.c
new file mode 100644
index 0000000000..6a26d4f0cf
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_div_d.c
@@ -0,0 +1,115 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+static int s_is_power_of_two(mp_digit b, int *p)
+{
+ int x;
+
+ /* fast return if no power of two */
+ if ((b==0) || (b & (b-1))) {
+ return 0;
+ }
+
+ for (x = 0; x < DIGIT_BIT; x++) {
+ if (b == (((mp_digit)1)<<x)) {
+ *p = x;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* single digit division (based on routine from MPI) */
+int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
+{
+ mp_int q;
+ mp_word w;
+ mp_digit t;
+ int res, ix;
+
+ /* cannot divide by zero */
+ if (b == 0) {
+ return MP_VAL;
+ }
+
+ /* quick outs */
+ if (b == 1 || mp_iszero(a) == 1) {
+ if (d != NULL) {
+ *d = 0;
+ }
+ if (c != NULL) {
+ return mp_copy(a, c);
+ }
+ return MP_OKAY;
+ }
+
+ /* power of two ? */
+ if (s_is_power_of_two(b, &ix) == 1) {
+ if (d != NULL) {
+ *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
+ }
+ if (c != NULL) {
+ return mp_div_2d(a, ix, c, NULL);
+ }
+ return MP_OKAY;
+ }
+
+#ifdef BN_MP_DIV_3_C
+ /* three? */
+ if (b == 3) {
+ return mp_div_3(a, c, d);
+ }
+#endif
+
+ /* no easy answer [c'est la vie]. Just division */
+ if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+ return res;
+ }
+
+ q.used = a->used;
+ q.sign = a->sign;
+ w = 0;
+ for (ix = a->used - 1; ix >= 0; ix--) {
+ w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+ if (w >= b) {
+ t = (mp_digit)(w / b);
+ w -= ((mp_word)t) * ((mp_word)b);
+ } else {
+ t = 0;
+ }
+ q.dp[ix] = (mp_digit)t;
+ }
+
+ if (d != NULL) {
+ *d = (mp_digit)w;
+ }
+
+ if (c != NULL) {
+ mp_clamp(&q);
+ mp_exch(&q, c);
+ }
+ mp_clear(&q);
+
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_div_d.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2007/01/09 04:44:32 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_is_modulus.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_is_modulus.c
new file mode 100644
index 0000000000..52373440d8
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_is_modulus.c
@@ -0,0 +1,43 @@
+#include <tommath.h>
+#ifdef BN_MP_DR_IS_MODULUS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* determines if a number is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a)
+{
+ int ix;
+
+ /* must be at least two digits */
+ if (a->used < 2) {
+ return 0;
+ }
+
+ /* must be of the form b**k - a [a <= b] so all
+ * but the first digit must be equal to -1 (mod b).
+ */
+ for (ix = 1; ix < a->used; ix++) {
+ if (a->dp[ix] != MP_MASK) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_dr_is_modulus.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_reduce.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_reduce.c
new file mode 100644
index 0000000000..e60b5784f1
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_reduce.c
@@ -0,0 +1,94 @@
+#include <tommath.h>
+#ifdef BN_MP_DR_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
+ *
+ * Based on algorithm from the paper
+ *
+ * "Generating Efficient Primes for Discrete Log Cryptosystems"
+ * Chae Hoon Lim, Pil Joong Lee,
+ * POSTECH Information Research Laboratories
+ *
+ * The modulus must be of a special format [see manual]
+ *
+ * Has been modified to use algorithm 7.10 from the LTM book instead
+ *
+ * Input x must be in the range 0 <= x <= (n-1)**2
+ */
+int
+mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
+{
+ int err, i, m;
+ mp_word r;
+ mp_digit mu, *tmpx1, *tmpx2;
+
+ /* m = digits in modulus */
+ m = n->used;
+
+ /* ensure that "x" has at least 2m digits */
+ if (x->alloc < m + m) {
+ if ((err = mp_grow (x, m + m)) != MP_OKAY) {
+ return err;
+ }
+ }
+
+/* top of loop, this is where the code resumes if
+ * another reduction pass is required.
+ */
+top:
+ /* aliases for digits */
+ /* alias for lower half of x */
+ tmpx1 = x->dp;
+
+ /* alias for upper half of x, or x/B**m */
+ tmpx2 = x->dp + m;
+
+ /* set carry to zero */
+ mu = 0;
+
+ /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
+ for (i = 0; i < m; i++) {
+ r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
+ *tmpx1++ = (mp_digit)(r & MP_MASK);
+ mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
+ }
+
+ /* set final carry */
+ *tmpx1++ = mu;
+
+ /* zero words above m */
+ for (i = m + 1; i < x->used; i++) {
+ *tmpx1++ = 0;
+ }
+
+ /* clamp, sub and return */
+ mp_clamp (x);
+
+ /* if x >= n then subtract and reduce again
+ * Each successive "recursion" makes the input smaller and smaller.
+ */
+ if (mp_cmp_mag (x, n) != MP_LT) {
+ s_mp_sub(x, n, x);
+ goto top;
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_dr_reduce.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_setup.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_setup.c
new file mode 100644
index 0000000000..1d7d856ef0
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_dr_setup.c
@@ -0,0 +1,32 @@
+#include <tommath.h>
+#ifdef BN_MP_DR_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* determines the setup value */
+void mp_dr_setup(mp_int *a, mp_digit *d)
+{
+ /* the casts are required if DIGIT_BIT is one less than
+ * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
+ */
+ *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) -
+ ((mp_word)a->dp[0]));
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_dr_setup.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exch.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exch.c
new file mode 100644
index 0000000000..38574e0a5e
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exch.c
@@ -0,0 +1,34 @@
+#include <tommath.h>
+#ifdef BN_MP_EXCH_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* swap the elements of two integers, for cases where you can't simply swap the
+ * mp_int pointers around
+ */
+void
+mp_exch (mp_int * a, mp_int * b)
+{
+ mp_int t;
+
+ t = *a;
+ *a = *b;
+ *b = t;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_exch.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_expt_d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_expt_d.c
new file mode 100644
index 0000000000..4bdc2d13a6
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_expt_d.c
@@ -0,0 +1,57 @@
+#include <tommath.h>
+#ifdef BN_MP_EXPT_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* calculate c = a**b using a square-multiply algorithm */
+int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ int res, x;
+ mp_int g;
+
+ if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* set initial result */
+ mp_set (c, 1);
+
+ for (x = 0; x < (int) DIGIT_BIT; x++) {
+ /* square */
+ if ((res = mp_sqr (c, c)) != MP_OKAY) {
+ mp_clear (&g);
+ return res;
+ }
+
+ /* if the bit is set multiply */
+ if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
+ if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
+ mp_clear (&g);
+ return res;
+ }
+ }
+
+ /* shift to next bit */
+ b <<= 1;
+ }
+
+ mp_clear (&g);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_expt_d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exptmod.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exptmod.c
new file mode 100644
index 0000000000..023191657a
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exptmod.c
@@ -0,0 +1,112 @@
+#include <tommath.h>
+#ifdef BN_MP_EXPTMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+
+/* this is a shell function that calls either the normal or Montgomery
+ * exptmod functions. Originally the call to the montgomery code was
+ * embedded in the normal function but that wasted alot of stack space
+ * for nothing (since 99% of the time the Montgomery code would be called)
+ */
+int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+{
+ int dr;
+
+ /* modulus P must be positive */
+ if (P->sign == MP_NEG) {
+ return MP_VAL;
+ }
+
+ /* if exponent X is negative we have to recurse */
+ if (X->sign == MP_NEG) {
+#ifdef BN_MP_INVMOD_C
+ mp_int tmpG, tmpX;
+ int err;
+
+ /* first compute 1/G mod P */
+ if ((err = mp_init(&tmpG)) != MP_OKAY) {
+ return err;
+ }
+ if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
+ mp_clear(&tmpG);
+ return err;
+ }
+
+ /* now get |X| */
+ if ((err = mp_init(&tmpX)) != MP_OKAY) {
+ mp_clear(&tmpG);
+ return err;
+ }
+ if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
+ mp_clear_multi(&tmpG, &tmpX, NULL);
+ return err;
+ }
+
+ /* and now compute (1/G)**|X| instead of G**X [X < 0] */
+ err = mp_exptmod(&tmpG, &tmpX, P, Y);
+ mp_clear_multi(&tmpG, &tmpX, NULL);
+ return err;
+#else
+ /* no invmod */
+ return MP_VAL;
+#endif
+ }
+
+/* modified diminished radix reduction */
+#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
+ if (mp_reduce_is_2k_l(P) == MP_YES) {
+ return s_mp_exptmod(G, X, P, Y, 1);
+ }
+#endif
+
+#ifdef BN_MP_DR_IS_MODULUS_C
+ /* is it a DR modulus? */
+ dr = mp_dr_is_modulus(P);
+#else
+ /* default to no */
+ dr = 0;
+#endif
+
+#ifdef BN_MP_REDUCE_IS_2K_C
+ /* if not, is it a unrestricted DR modulus? */
+ if (dr == 0) {
+ dr = mp_reduce_is_2k(P) << 1;
+ }
+#endif
+
+ /* if the modulus is odd or dr != 0 use the montgomery method */
+#ifdef BN_MP_EXPTMOD_FAST_C
+ if (mp_isodd (P) == 1 || dr != 0) {
+ return mp_exptmod_fast (G, X, P, Y, dr);
+ } else {
+#endif
+#ifdef BN_S_MP_EXPTMOD_C
+ /* otherwise use the generic Barrett reduction technique */
+ return s_mp_exptmod (G, X, P, Y, 0);
+#else
+ /* no exptmod for evens */
+ return MP_VAL;
+#endif
+#ifdef BN_MP_EXPTMOD_FAST_C
+ }
+#endif
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exptmod_fast.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exptmod_fast.c
new file mode 100644
index 0000000000..2a3b3c9e81
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exptmod_fast.c
@@ -0,0 +1,321 @@
+#include <tommath.h>
+#ifdef BN_MP_EXPTMOD_FAST_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
+ *
+ * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
+ * The value of k changes based on the size of the exponent.
+ *
+ * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
+ */
+
+#ifdef MP_LOW_MEM
+ #define TAB_SIZE 32
+#else
+ #define TAB_SIZE 256
+#endif
+
+int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
+{
+ mp_int M[TAB_SIZE], res;
+ mp_digit buf, mp;
+ int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+
+ /* use a pointer to the reduction algorithm. This allows us to use
+ * one of many reduction algorithms without modding the guts of
+ * the code with if statements everywhere.
+ */
+ int (*redux)(mp_int*,mp_int*,mp_digit);
+
+ /* find window size */
+ x = mp_count_bits (X);
+ if (x <= 7) {
+ winsize = 2;
+ } else if (x <= 36) {
+ winsize = 3;
+ } else if (x <= 140) {
+ winsize = 4;
+ } else if (x <= 450) {
+ winsize = 5;
+ } else if (x <= 1303) {
+ winsize = 6;
+ } else if (x <= 3529) {
+ winsize = 7;
+ } else {
+ winsize = 8;
+ }
+
+#ifdef MP_LOW_MEM
+ if (winsize > 5) {
+ winsize = 5;
+ }
+#endif
+
+ /* init M array */
+ /* init first cell */
+ if ((err = mp_init(&M[1])) != MP_OKAY) {
+ return err;
+ }
+
+ /* now init the second half of the array */
+ for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+ if ((err = mp_init(&M[x])) != MP_OKAY) {
+ for (y = 1<<(winsize-1); y < x; y++) {
+ mp_clear (&M[y]);
+ }
+ mp_clear(&M[1]);
+ return err;
+ }
+ }
+
+ /* determine and setup reduction code */
+ if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_SETUP_C
+ /* now setup montgomery */
+ if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
+ goto LBL_M;
+ }
+#else
+ err = MP_VAL;
+ goto LBL_M;
+#endif
+
+ /* automatically pick the comba one if available (saves quite a few calls/ifs) */
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+ if (((P->used * 2 + 1) < MP_WARRAY) &&
+ P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ redux = fast_mp_montgomery_reduce;
+ } else
+#endif
+ {
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+ /* use slower baseline Montgomery method */
+ redux = mp_montgomery_reduce;
+#else
+ err = MP_VAL;
+ goto LBL_M;
+#endif
+ }
+ } else if (redmode == 1) {
+#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
+ /* setup DR reduction for moduli of the form B**k - b */
+ mp_dr_setup(P, &mp);
+ redux = mp_dr_reduce;
+#else
+ err = MP_VAL;
+ goto LBL_M;
+#endif
+ } else {
+#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
+ /* setup DR reduction for moduli of the form 2**k - b */
+ if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
+ goto LBL_M;
+ }
+ redux = mp_reduce_2k;
+#else
+ err = MP_VAL;
+ goto LBL_M;
+#endif
+ }
+
+ /* setup result */
+ if ((err = mp_init (&res)) != MP_OKAY) {
+ goto LBL_M;
+ }
+
+ /* create M table
+ *
+
+ *
+ * The first half of the table is not computed though accept for M[0] and M[1]
+ */
+
+ if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+ /* now we need R mod m */
+ if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+#else
+ err = MP_VAL;
+ goto LBL_RES;
+#endif
+
+ /* now set M[1] to G * R mod m */
+ if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ } else {
+ mp_set(&res, 1);
+ if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
+ if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ for (x = 0; x < (winsize - 1); x++) {
+ if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* create upper table */
+ for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+ if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* set initial mode and bit cnt */
+ mode = 0;
+ bitcnt = 1;
+ buf = 0;
+ digidx = X->used - 1;
+ bitcpy = 0;
+ bitbuf = 0;
+
+ for (;;) {
+ /* grab next digit as required */
+ if (--bitcnt == 0) {
+ /* if digidx == -1 we are out of digits so break */
+ if (digidx == -1) {
+ break;
+ }
+ /* read next digit and reset bitcnt */
+ buf = X->dp[digidx--];
+ bitcnt = (int)DIGIT_BIT;
+ }
+
+ /* grab the next msb from the exponent */
+ y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
+ buf <<= (mp_digit)1;
+
+ /* if the bit is zero and mode == 0 then we ignore it
+ * These represent the leading zero bits before the first 1 bit
+ * in the exponent. Technically this opt is not required but it
+ * does lower the # of trivial squaring/reductions used
+ */
+ if (mode == 0 && y == 0) {
+ continue;
+ }
+
+ /* if the bit is zero and mode == 1 then we square */
+ if (mode == 1 && y == 0) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ continue;
+ }
+
+ /* else we add it to the window */
+ bitbuf |= (y << (winsize - ++bitcpy));
+ mode = 2;
+
+ if (bitcpy == winsize) {
+ /* ok window is filled so square as required and multiply */
+ /* square first */
+ for (x = 0; x < winsize; x++) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* then multiply */
+ if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ /* empty window and reset */
+ bitcpy = 0;
+ bitbuf = 0;
+ mode = 1;
+ }
+ }
+
+ /* if bits remain then square/multiply */
+ if (mode == 2 && bitcpy > 0) {
+ /* square then multiply if the bit is set */
+ for (x = 0; x < bitcpy; x++) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ /* get next bit of the window */
+ bitbuf <<= 1;
+ if ((bitbuf & (1 << winsize)) != 0) {
+ /* then multiply */
+ if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+ }
+ }
+
+ if (redmode == 0) {
+ /* fixup result if Montgomery reduction is used
+ * recall that any value in a Montgomery system is
+ * actually multiplied by R mod n. So we have
+ * to reduce one more time to cancel out the factor
+ * of R.
+ */
+ if ((err = redux(&res, P, mp)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* swap res with Y */
+ mp_exch (&res, Y);
+ err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_M:
+ mp_clear(&M[1]);
+ for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+ mp_clear (&M[x]);
+ }
+ return err;
+}
+#endif
+
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_exptmod_fast.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exteuclid.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exteuclid.c
new file mode 100644
index 0000000000..e6c4ce2b85
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_exteuclid.c
@@ -0,0 +1,82 @@
+#include <tommath.h>
+#ifdef BN_MP_EXTEUCLID_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* Extended euclidean algorithm of (a, b) produces
+ a*u1 + b*u2 = u3
+ */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
+{
+ mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
+ int err;
+
+ if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
+ return err;
+ }
+
+ /* initialize, (u1,u2,u3) = (1,0,a) */
+ mp_set(&u1, 1);
+ if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
+
+ /* initialize, (v1,v2,v3) = (0,1,b) */
+ mp_set(&v2, 1);
+ if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
+
+ /* loop while v3 != 0 */
+ while (mp_iszero(&v3) == MP_NO) {
+ /* q = u3/v3 */
+ if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
+
+ /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
+ if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
+
+ /* (u1,u2,u3) = (v1,v2,v3) */
+ if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
+
+ /* (v1,v2,v3) = (t1,t2,t3) */
+ if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
+ if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
+ }
+
+ /* make sure U3 >= 0 */
+ if (u3.sign == MP_NEG) {
+ mp_neg(&u1, &u1);
+ mp_neg(&u2, &u2);
+ mp_neg(&u3, &u3);
+ }
+
+ /* copy result out */
+ if (U1 != NULL) { mp_exch(U1, &u1); }
+ if (U2 != NULL) { mp_exch(U2, &u2); }
+ if (U3 != NULL) { mp_exch(U3, &u3); }
+
+ err = MP_OKAY;
+_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_exteuclid.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_find_prime.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_find_prime.c
new file mode 100644
index 0000000000..0458744fc7
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_find_prime.c
@@ -0,0 +1,26 @@
+/* TomsFastMath, a fast ISO C bignum library.
+ *
+ * This project is public domain and free for all purposes.
+ *
+ * Love Hornquist Astrand <lha@h5l.org>
+ */
+#include <tommath.h>
+
+int mp_find_prime(mp_int *a)
+{
+ int res;
+
+ if (mp_iseven(a))
+ mp_add_d(a, 1, a);
+
+ do {
+
+ if ((res = mp_isprime(a)) == MP_NO) {
+ mp_add_d(a, 2, a);
+ continue;
+ }
+
+ } while (res != MP_YES);
+
+ return res;
+}
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_fread.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_fread.c
new file mode 100644
index 0000000000..b344b6f05d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_fread.c
@@ -0,0 +1,67 @@
+#include <tommath.h>
+#ifdef BN_MP_FREAD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* read a bigint from a file stream in ASCII */
+int mp_fread(mp_int *a, int radix, FILE *stream)
+{
+ int err, ch, neg, y;
+
+ /* clear a */
+ mp_zero(a);
+
+ /* if first digit is - then set negative */
+ ch = fgetc(stream);
+ if (ch == '-') {
+ neg = MP_NEG;
+ ch = fgetc(stream);
+ } else {
+ neg = MP_ZPOS;
+ }
+
+ for (;;) {
+ /* find y in the radix map */
+ for (y = 0; y < radix; y++) {
+ if (mp_s_rmap[y] == ch) {
+ break;
+ }
+ }
+ if (y == radix) {
+ break;
+ }
+
+ /* shift up and add */
+ if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
+ return err;
+ }
+ if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
+ return err;
+ }
+
+ ch = fgetc(stream);
+ }
+ if (mp_cmp_d(a, 0) != MP_EQ) {
+ a->sign = neg;
+ }
+
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_fread.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_fwrite.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_fwrite.c
new file mode 100644
index 0000000000..a0b4c6b6d1
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_fwrite.c
@@ -0,0 +1,52 @@
+#include <tommath.h>
+#ifdef BN_MP_FWRITE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+int mp_fwrite(mp_int *a, int radix, FILE *stream)
+{
+ char *buf;
+ int err, len, x;
+
+ if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
+ return err;
+ }
+
+ buf = OPT_CAST(char) XMALLOC (len);
+ if (buf == NULL) {
+ return MP_MEM;
+ }
+
+ if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
+ XFREE (buf);
+ return err;
+ }
+
+ for (x = 0; x < len; x++) {
+ if (fputc(buf[x], stream) == EOF) {
+ XFREE (buf);
+ return MP_VAL;
+ }
+ }
+
+ XFREE (buf);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_fwrite.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_gcd.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_gcd.c
new file mode 100644
index 0000000000..b39ba9041d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_gcd.c
@@ -0,0 +1,105 @@
+#include <tommath.h>
+#ifdef BN_MP_GCD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* Greatest Common Divisor using the binary method */
+int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int u, v;
+ int k, u_lsb, v_lsb, res;
+
+ /* either zero than gcd is the largest */
+ if (mp_iszero (a) == MP_YES) {
+ return mp_abs (b, c);
+ }
+ if (mp_iszero (b) == MP_YES) {
+ return mp_abs (a, c);
+ }
+
+ /* get copies of a and b we can modify */
+ if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
+ goto LBL_U;
+ }
+
+ /* must be positive for the remainder of the algorithm */
+ u.sign = v.sign = MP_ZPOS;
+
+ /* B1. Find the common power of two for u and v */
+ u_lsb = mp_cnt_lsb(&u);
+ v_lsb = mp_cnt_lsb(&v);
+ k = MIN(u_lsb, v_lsb);
+
+ if (k > 0) {
+ /* divide the power of two out */
+ if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+
+ if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ }
+
+ /* divide any remaining factors of two out */
+ if (u_lsb != k) {
+ if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ }
+
+ if (v_lsb != k) {
+ if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ }
+
+ while (mp_iszero(&v) == 0) {
+ /* make sure v is the largest */
+ if (mp_cmp_mag(&u, &v) == MP_GT) {
+ /* swap u and v to make sure v is >= u */
+ mp_exch(&u, &v);
+ }
+
+ /* subtract smallest from largest */
+ if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
+ goto LBL_V;
+ }
+
+ /* Divide out all factors of two */
+ if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ }
+
+ /* multiply by 2**k which we divided out at the beginning */
+ if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
+ goto LBL_V;
+ }
+ c->sign = MP_ZPOS;
+ res = MP_OKAY;
+LBL_V:mp_clear (&u);
+LBL_U:mp_clear (&v);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_gcd.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_get_int.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_get_int.c
new file mode 100644
index 0000000000..17162e2bf1
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_get_int.c
@@ -0,0 +1,45 @@
+#include <tommath.h>
+#ifdef BN_MP_GET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* get the lower 32-bits of an mp_int */
+unsigned long mp_get_int(mp_int * a)
+{
+ int i;
+ unsigned long res;
+
+ if (a->used == 0) {
+ return 0;
+ }
+
+ /* get number of digits of the lsb we have to read */
+ i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1;
+
+ /* get most significant digit of result */
+ res = DIGIT(a,i);
+
+ while (--i >= 0) {
+ res = (res << DIGIT_BIT) | DIGIT(a,i);
+ }
+
+ /* force result to 32-bits always so it is consistent on non 32-bit platforms */
+ return res & 0xFFFFFFFFUL;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_get_int.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_grow.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_grow.c
new file mode 100644
index 0000000000..cf2b949b24
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_grow.c
@@ -0,0 +1,57 @@
+#include <tommath.h>
+#ifdef BN_MP_GROW_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* grow as required */
+int mp_grow (mp_int * a, int size)
+{
+ int i;
+ mp_digit *tmp;
+
+ /* if the alloc size is smaller alloc more ram */
+ if (a->alloc < size) {
+ /* ensure there are always at least MP_PREC digits extra on top */
+ size += (MP_PREC * 2) - (size % MP_PREC);
+
+ /* reallocate the array a->dp
+ *
+ * We store the return in a temporary variable
+ * in case the operation failed we don't want
+ * to overwrite the dp member of a.
+ */
+ tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
+ if (tmp == NULL) {
+ /* reallocation failed but "a" is still valid [can be freed] */
+ return MP_MEM;
+ }
+
+ /* reallocation succeeded so set a->dp */
+ a->dp = tmp;
+
+ /* zero excess digits */
+ i = a->alloc;
+ a->alloc = size;
+ for (; i < a->alloc; i++) {
+ a->dp[i] = 0;
+ }
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_grow.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init.c
new file mode 100644
index 0000000000..8be27f5696
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init.c
@@ -0,0 +1,46 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* init a new mp_int */
+int mp_init (mp_int * a)
+{
+ int i;
+
+ /* allocate memory required and clear it */
+ a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
+ if (a->dp == NULL) {
+ return MP_MEM;
+ }
+
+ /* set the digits to zero */
+ for (i = 0; i < MP_PREC; i++) {
+ a->dp[i] = 0;
+ }
+
+ /* set the used to zero, allocated digits to the default precision
+ * and sign to positive */
+ a->used = 0;
+ a->alloc = MP_PREC;
+ a->sign = MP_ZPOS;
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_copy.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_copy.c
new file mode 100644
index 0000000000..0160811aff
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_copy.c
@@ -0,0 +1,32 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_COPY_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* creates "a" then copies b into it */
+int mp_init_copy (mp_int * a, mp_int * b)
+{
+ int res;
+
+ if ((res = mp_init (a)) != MP_OKAY) {
+ return res;
+ }
+ return mp_copy (b, a);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_copy.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_multi.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_multi.c
new file mode 100644
index 0000000000..59dc3a9ea7
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_multi.c
@@ -0,0 +1,59 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_MULTI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+#include <stdarg.h>
+
+int mp_init_multi(mp_int *mp, ...)
+{
+ mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
+ int n = 0; /* Number of ok inits */
+ mp_int* cur_arg = mp;
+ va_list args;
+
+ va_start(args, mp); /* init args to next argument from caller */
+ while (cur_arg != NULL) {
+ if (mp_init(cur_arg) != MP_OKAY) {
+ /* Oops - error! Back-track and mp_clear what we already
+ succeeded in init-ing, then return error.
+ */
+ va_list clean_args;
+
+ /* end the current list */
+ va_end(args);
+
+ /* now start cleaning up */
+ cur_arg = mp;
+ va_start(clean_args, mp);
+ while (n--) {
+ mp_clear(cur_arg);
+ cur_arg = va_arg(clean_args, mp_int*);
+ }
+ va_end(clean_args);
+ res = MP_MEM;
+ break;
+ }
+ n++;
+ cur_arg = va_arg(args, mp_int*);
+ }
+ va_end(args);
+ return res; /* Assumed ok, if error flagged above. */
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_multi.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_set.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_set.c
new file mode 100644
index 0000000000..34edad92ff
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_set.c
@@ -0,0 +1,32 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_SET_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b)
+{
+ int err;
+ if ((err = mp_init(a)) != MP_OKAY) {
+ return err;
+ }
+ mp_set(a, b);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_set.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_set_int.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_set_int.c
new file mode 100644
index 0000000000..5c55993152
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_set_int.c
@@ -0,0 +1,31 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_SET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* initialize and set a digit */
+int mp_init_set_int (mp_int * a, unsigned long b)
+{
+ int err;
+ if ((err = mp_init(a)) != MP_OKAY) {
+ return err;
+ }
+ return mp_set_int(a, b);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_set_int.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_size.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_size.c
new file mode 100644
index 0000000000..8e014183a3
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_init_size.c
@@ -0,0 +1,48 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* init an mp_init for a given size */
+int mp_init_size (mp_int * a, int size)
+{
+ int x;
+
+ /* pad size so there are always extra digits */
+ size += (MP_PREC * 2) - (size % MP_PREC);
+
+ /* alloc mem */
+ a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
+ if (a->dp == NULL) {
+ return MP_MEM;
+ }
+
+ /* set the members */
+ a->used = 0;
+ a->alloc = size;
+ a->sign = MP_ZPOS;
+
+ /* zero the digits */
+ for (x = 0; x < size; x++) {
+ a->dp[x] = 0;
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_init_size.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_invmod.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_invmod.c
new file mode 100644
index 0000000000..154651468f
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_invmod.c
@@ -0,0 +1,43 @@
+#include <tommath.h>
+#ifdef BN_MP_INVMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* hac 14.61, pp608 */
+int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+ /* b cannot be negative */
+ if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+ return MP_VAL;
+ }
+
+#ifdef BN_FAST_MP_INVMOD_C
+ /* if the modulus is odd we can use a faster routine instead */
+ if (mp_isodd (b) == 1) {
+ return fast_mp_invmod (a, b, c);
+ }
+#endif
+
+#ifdef BN_MP_INVMOD_SLOW_C
+ return mp_invmod_slow(a, b, c);
+#endif
+
+ return MP_VAL;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_invmod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_invmod_slow.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_invmod_slow.c
new file mode 100644
index 0000000000..eedd47dcf1
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_invmod_slow.c
@@ -0,0 +1,175 @@
+#include <tommath.h>
+#ifdef BN_MP_INVMOD_SLOW_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* hac 14.61, pp608 */
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int x, y, u, v, A, B, C, D;
+ int res;
+
+ /* b cannot be negative */
+ if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+ return MP_VAL;
+ }
+
+ /* init temps */
+ if ((res = mp_init_multi(&x, &y, &u, &v,
+ &A, &B, &C, &D, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* x = a, y = b */
+ if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_copy (b, &y)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ /* 2. [modified] if x,y are both even then return an error! */
+ if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
+ res = MP_VAL;
+ goto LBL_ERR;
+ }
+
+ /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+ if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ mp_set (&A, 1);
+ mp_set (&D, 1);
+
+top:
+ /* 4. while u is even do */
+ while (mp_iseven (&u) == 1) {
+ /* 4.1 u = u/2 */
+ if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ /* 4.2 if A or B is odd then */
+ if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
+ /* A = (A+y)/2, B = (B-x)/2 */
+ if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ /* A = A/2, B = B/2 */
+ if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* 5. while v is even do */
+ while (mp_iseven (&v) == 1) {
+ /* 5.1 v = v/2 */
+ if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ /* 5.2 if C or D is odd then */
+ if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
+ /* C = (C+y)/2, D = (D-x)/2 */
+ if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+ /* C = C/2, D = D/2 */
+ if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* 6. if u >= v then */
+ if (mp_cmp (&u, &v) != MP_LT) {
+ /* u = u - v, A = A - C, B = B - D */
+ if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ } else {
+ /* v - v - u, C = C - A, D = D - B */
+ if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* if not zero goto step 4 */
+ if (mp_iszero (&u) == 0)
+ goto top;
+
+ /* now a = C, b = D, gcd == g*v */
+
+ /* if v != 1 then there is no inverse */
+ if (mp_cmp_d (&v, 1) != MP_EQ) {
+ res = MP_VAL;
+ goto LBL_ERR;
+ }
+
+ /* if its too low */
+ while (mp_cmp_d(&C, 0) == MP_LT) {
+ if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* too big */
+ while (mp_cmp_mag(&C, b) != MP_LT) {
+ if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* C is now the inverse */
+ mp_exch (&C, c);
+ res = MP_OKAY;
+LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_invmod_slow.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_is_square.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_is_square.c
new file mode 100644
index 0000000000..50c524444e
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_is_square.c
@@ -0,0 +1,109 @@
+#include <tommath.h>
+#ifdef BN_MP_IS_SQUARE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* Check if remainders are possible squares - fast exclude non-squares */
+static const char rem_128[128] = {
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
+};
+
+static const char rem_105[105] = {
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
+};
+
+/* Store non-zero to ret if arg is square, and zero if not */
+int mp_is_square(mp_int *arg,int *ret)
+{
+ int res;
+ mp_digit c;
+ mp_int t;
+ unsigned long r;
+
+ /* Default to Non-square :) */
+ *ret = MP_NO;
+
+ if (arg->sign == MP_NEG) {
+ return MP_VAL;
+ }
+
+ /* digits used? (TSD) */
+ if (arg->used == 0) {
+ return MP_OKAY;
+ }
+
+ /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
+ if (rem_128[127 & DIGIT(arg,0)] == 1) {
+ return MP_OKAY;
+ }
+
+ /* Next check mod 105 (3*5*7) */
+ if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
+ return res;
+ }
+ if (rem_105[c] == 1) {
+ return MP_OKAY;
+ }
+
+
+ if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
+ return res;
+ }
+ if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
+ goto ERR;
+ }
+ r = mp_get_int(&t);
+ /* Check for other prime modules, note it's not an ERROR but we must
+ * free "t" so the easiest way is to goto ERR. We know that res
+ * is already equal to MP_OKAY from the mp_mod call
+ */
+ if ( (1L<<(r%11)) & 0x5C4L ) goto ERR;
+ if ( (1L<<(r%13)) & 0x9E4L ) goto ERR;
+ if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR;
+ if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR;
+ if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR;
+ if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR;
+ if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR;
+
+ /* Final check - is sqr(sqrt(arg)) == arg ? */
+ if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
+ERR:mp_clear(&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_is_square.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_isprime.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_isprime.c
new file mode 100644
index 0000000000..07ce86f296
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_isprime.c
@@ -0,0 +1,75 @@
+/* TomsFastMath, a fast ISO C bignum library.
+ *
+ * This project is meant to fill in where LibTomMath
+ * falls short. That is speed ;-)
+ *
+ * This project is public domain and free for all purposes.
+ *
+ * Tom St Denis, tomstdenis@gmail.com
+ */
+#include <tommath.h>
+
+/* a few primes */
+static const mp_digit primes[256] = {
+ 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
+ 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
+ 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
+ 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083,
+ 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
+ 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
+ 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
+ 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
+
+ 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
+ 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
+ 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
+ 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
+ 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
+ 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
+ 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
+ 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
+
+ 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
+ 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
+ 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
+ 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
+ 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
+ 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
+ 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
+ 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
+
+ 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
+ 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
+ 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
+ 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
+ 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
+ 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
+ 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
+ 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
+};
+
+int mp_isprime(mp_int *a)
+{
+ mp_int b;
+ mp_digit d;
+ int r, res;
+
+ /* do trial division */
+ for (r = 0; r < 256; r++) {
+ mp_mod_d(a, primes[r], &d);
+ if (d == 0) {
+ return MP_NO;
+ }
+ }
+
+ /* now do 8 miller rabins */
+ mp_init(&b);
+ for (r = 0; r < 128; r++) {
+ mp_set(&b, primes[r]);
+ mp_prime_miller_rabin(a, &b, &res);
+ if (res == MP_NO) {
+ return MP_NO;
+ }
+ }
+ return MP_YES;
+}
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_jacobi.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_jacobi.c
new file mode 100644
index 0000000000..91cfeeade4
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_jacobi.c
@@ -0,0 +1,105 @@
+#include <tommath.h>
+#ifdef BN_MP_JACOBI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* computes the jacobi c = (a | n) (or Legendre if n is prime)
+ * HAC pp. 73 Algorithm 2.149
+ */
+int mp_jacobi (mp_int * a, mp_int * p, int *c)
+{
+ mp_int a1, p1;
+ int k, s, r, res;
+ mp_digit residue;
+
+ /* if p <= 0 return MP_VAL */
+ if (mp_cmp_d(p, 0) != MP_GT) {
+ return MP_VAL;
+ }
+
+ /* step 1. if a == 0, return 0 */
+ if (mp_iszero (a) == 1) {
+ *c = 0;
+ return MP_OKAY;
+ }
+
+ /* step 2. if a == 1, return 1 */
+ if (mp_cmp_d (a, 1) == MP_EQ) {
+ *c = 1;
+ return MP_OKAY;
+ }
+
+ /* default */
+ s = 0;
+
+ /* step 3. write a = a1 * 2**k */
+ if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_init (&p1)) != MP_OKAY) {
+ goto LBL_A1;
+ }
+
+ /* divide out larger power of two */
+ k = mp_cnt_lsb(&a1);
+ if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
+ goto LBL_P1;
+ }
+
+ /* step 4. if e is even set s=1 */
+ if ((k & 1) == 0) {
+ s = 1;
+ } else {
+ /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
+ residue = p->dp[0] & 7;
+
+ if (residue == 1 || residue == 7) {
+ s = 1;
+ } else if (residue == 3 || residue == 5) {
+ s = -1;
+ }
+ }
+
+ /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
+ if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
+ s = -s;
+ }
+
+ /* if a1 == 1 we're done */
+ if (mp_cmp_d (&a1, 1) == MP_EQ) {
+ *c = s;
+ } else {
+ /* n1 = n mod a1 */
+ if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) {
+ goto LBL_P1;
+ }
+ if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
+ goto LBL_P1;
+ }
+ *c = s * r;
+ }
+
+ /* done */
+ res = MP_OKAY;
+LBL_P1:mp_clear (&p1);
+LBL_A1:mp_clear (&a1);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_jacobi.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_karatsuba_mul.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_karatsuba_mul.c
new file mode 100644
index 0000000000..8ea2c2792a
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_karatsuba_mul.c
@@ -0,0 +1,167 @@
+#include <tommath.h>
+#ifdef BN_MP_KARATSUBA_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* c = |a| * |b| using Karatsuba Multiplication using
+ * three half size multiplications
+ *
+ * Let B represent the radix [e.g. 2**DIGIT_BIT] and
+ * let n represent half of the number of digits in
+ * the min(a,b)
+ *
+ * a = a1 * B**n + a0
+ * b = b1 * B**n + b0
+ *
+ * Then, a * b =>
+ a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
+ *
+ * Note that a1b1 and a0b0 are used twice and only need to be
+ * computed once. So in total three half size (half # of
+ * digit) multiplications are performed, a0b0, a1b1 and
+ * (a1+b1)(a0+b0)
+ *
+ * Note that a multiplication of half the digits requires
+ * 1/4th the number of single precision multiplications so in
+ * total after one call 25% of the single precision multiplications
+ * are saved. Note also that the call to mp_mul can end up back
+ * in this function if the a0, a1, b0, or b1 are above the threshold.
+ * This is known as divide-and-conquer and leads to the famous
+ * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
+ * the standard O(N**2) that the baseline/comba methods use.
+ * Generally though the overhead of this method doesn't pay off
+ * until a certain size (N ~ 80) is reached.
+ */
+int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int x0, x1, y0, y1, t1, x0y0, x1y1;
+ int B, err;
+
+ /* default the return code to an error */
+ err = MP_MEM;
+
+ /* min # of digits */
+ B = MIN (a->used, b->used);
+
+ /* now divide in two */
+ B = B >> 1;
+
+ /* init copy all the temps */
+ if (mp_init_size (&x0, B) != MP_OKAY)
+ goto ERR;
+ if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+ goto X0;
+ if (mp_init_size (&y0, B) != MP_OKAY)
+ goto X1;
+ if (mp_init_size (&y1, b->used - B) != MP_OKAY)
+ goto Y0;
+
+ /* init temps */
+ if (mp_init_size (&t1, B * 2) != MP_OKAY)
+ goto Y1;
+ if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
+ goto T1;
+ if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
+ goto X0Y0;
+
+ /* now shift the digits */
+ x0.used = y0.used = B;
+ x1.used = a->used - B;
+ y1.used = b->used - B;
+
+ {
+ register int x;
+ register mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
+
+ /* we copy the digits directly instead of using higher level functions
+ * since we also need to shift the digits
+ */
+ tmpa = a->dp;
+ tmpb = b->dp;
+
+ tmpx = x0.dp;
+ tmpy = y0.dp;
+ for (x = 0; x < B; x++) {
+ *tmpx++ = *tmpa++;
+ *tmpy++ = *tmpb++;
+ }
+
+ tmpx = x1.dp;
+ for (x = B; x < a->used; x++) {
+ *tmpx++ = *tmpa++;
+ }
+
+ tmpy = y1.dp;
+ for (x = B; x < b->used; x++) {
+ *tmpy++ = *tmpb++;
+ }
+ }
+
+ /* only need to clamp the lower words since by definition the
+ * upper words x1/y1 must have a known number of digits
+ */
+ mp_clamp (&x0);
+ mp_clamp (&y0);
+
+ /* now calc the products x0y0 and x1y1 */
+ /* after this x0 is no longer required, free temp [x0==t2]! */
+ if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)
+ goto X1Y1; /* x0y0 = x0*y0 */
+ if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
+ goto X1Y1; /* x1y1 = x1*y1 */
+
+ /* now calc x1+x0 and y1+y0 */
+ if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = x1 - x0 */
+ if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
+ goto X1Y1; /* t2 = y1 - y0 */
+ if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */
+
+ /* add x0y0 */
+ if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
+ goto X1Y1; /* t2 = x0y0 + x1y1 */
+ if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
+
+ /* shift by B */
+ if (mp_lshd (&t1, B) != MP_OKAY)
+ goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
+ if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
+ goto X1Y1; /* x1y1 = x1y1 << 2*B */
+
+ if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = x0y0 + t1 */
+ if (mp_add (&t1, &x1y1, c) != MP_OKAY)
+ goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
+
+ /* Algorithm succeeded set the return code to MP_OKAY */
+ err = MP_OKAY;
+
+X1Y1:mp_clear (&x1y1);
+X0Y0:mp_clear (&x0y0);
+T1:mp_clear (&t1);
+Y1:mp_clear (&y1);
+Y0:mp_clear (&y0);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_mul.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_karatsuba_sqr.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_karatsuba_sqr.c
new file mode 100644
index 0000000000..a5e198be12
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_karatsuba_sqr.c
@@ -0,0 +1,121 @@
+#include <tommath.h>
+#ifdef BN_MP_KARATSUBA_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* Karatsuba squaring, computes b = a*a using three
+ * half size squarings
+ *
+ * See comments of karatsuba_mul for details. It
+ * is essentially the same algorithm but merely
+ * tuned to perform recursive squarings.
+ */
+int mp_karatsuba_sqr (mp_int * a, mp_int * b)
+{
+ mp_int x0, x1, t1, t2, x0x0, x1x1;
+ int B, err;
+
+ err = MP_MEM;
+
+ /* min # of digits */
+ B = a->used;
+
+ /* now divide in two */
+ B = B >> 1;
+
+ /* init copy all the temps */
+ if (mp_init_size (&x0, B) != MP_OKAY)
+ goto ERR;
+ if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+ goto X0;
+
+ /* init temps */
+ if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
+ goto X1;
+ if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
+ goto T1;
+ if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
+ goto T2;
+ if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
+ goto X0X0;
+
+ {
+ register int x;
+ register mp_digit *dst, *src;
+
+ src = a->dp;
+
+ /* now shift the digits */
+ dst = x0.dp;
+ for (x = 0; x < B; x++) {
+ *dst++ = *src++;
+ }
+
+ dst = x1.dp;
+ for (x = B; x < a->used; x++) {
+ *dst++ = *src++;
+ }
+ }
+
+ x0.used = B;
+ x1.used = a->used - B;
+
+ mp_clamp (&x0);
+
+ /* now calc the products x0*x0 and x1*x1 */
+ if (mp_sqr (&x0, &x0x0) != MP_OKAY)
+ goto X1X1; /* x0x0 = x0*x0 */
+ if (mp_sqr (&x1, &x1x1) != MP_OKAY)
+ goto X1X1; /* x1x1 = x1*x1 */
+
+ /* now calc (x1+x0)**2 */
+ if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = x1 - x0 */
+ if (mp_sqr (&t1, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */
+
+ /* add x0y0 */
+ if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
+ goto X1X1; /* t2 = x0x0 + x1x1 */
+ if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
+
+ /* shift by B */
+ if (mp_lshd (&t1, B) != MP_OKAY)
+ goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
+ if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
+ goto X1X1; /* x1x1 = x1x1 << 2*B */
+
+ if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = x0x0 + t1 */
+ if (mp_add (&t1, &x1x1, b) != MP_OKAY)
+ goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
+
+ err = MP_OKAY;
+
+X1X1:mp_clear (&x1x1);
+X0X0:mp_clear (&x0x0);
+T2:mp_clear (&t2);
+T1:mp_clear (&t1);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_sqr.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_lcm.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_lcm.c
new file mode 100644
index 0000000000..781eef5659
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_lcm.c
@@ -0,0 +1,60 @@
+#include <tommath.h>
+#ifdef BN_MP_LCM_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* computes least common multiple as |a*b|/(a, b) */
+int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res;
+ mp_int t1, t2;
+
+
+ if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* t1 = get the GCD of the two inputs */
+ if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
+ goto LBL_T;
+ }
+
+ /* divide the smallest by the GCD */
+ if (mp_cmp_mag(a, b) == MP_LT) {
+ /* store quotient in t2 such that t2 * b is the LCM */
+ if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
+ goto LBL_T;
+ }
+ res = mp_mul(b, &t2, c);
+ } else {
+ /* store quotient in t2 such that t2 * a is the LCM */
+ if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
+ goto LBL_T;
+ }
+ res = mp_mul(a, &t2, c);
+ }
+
+ /* fix the sign to positive */
+ c->sign = MP_ZPOS;
+
+LBL_T:
+ mp_clear_multi (&t1, &t2, NULL);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_lcm.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_lshd.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_lshd.c
new file mode 100644
index 0000000000..f118cf1ae5
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_lshd.c
@@ -0,0 +1,67 @@
+#include <tommath.h>
+#ifdef BN_MP_LSHD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* shift left a certain amount of digits */
+int mp_lshd (mp_int * a, int b)
+{
+ int x, res;
+
+ /* if its less than zero return */
+ if (b <= 0) {
+ return MP_OKAY;
+ }
+
+ /* grow to fit the new digits */
+ if (a->alloc < a->used + b) {
+ if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ {
+ register mp_digit *top, *bottom;
+
+ /* increment the used by the shift amount then copy upwards */
+ a->used += b;
+
+ /* top */
+ top = a->dp + a->used - 1;
+
+ /* base */
+ bottom = a->dp + a->used - 1 - b;
+
+ /* much like mp_rshd this is implemented using a sliding window
+ * except the window goes the otherway around. Copying from
+ * the bottom to the top. see bn_mp_rshd.c for more info.
+ */
+ for (x = a->used - 1; x >= b; x--) {
+ *top-- = *bottom--;
+ }
+
+ /* zero the lower digits */
+ top = a->dp;
+ for (x = 0; x < b; x++) {
+ *top++ = 0;
+ }
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_lshd.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod.c
new file mode 100644
index 0000000000..f5cf8d09f2
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod.c
@@ -0,0 +1,48 @@
+#include <tommath.h>
+#ifdef BN_MP_MOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* c = a mod b, 0 <= c < b */
+int
+mp_mod (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int t;
+ int res;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+
+ if (t.sign != b->sign) {
+ res = mp_add (b, &t, c);
+ } else {
+ res = MP_OKAY;
+ mp_exch (&t, c);
+ }
+
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod_2d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod_2d.c
new file mode 100644
index 0000000000..e194a06870
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod_2d.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_MOD_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* calc a value mod 2**b */
+int
+mp_mod_2d (mp_int * a, int b, mp_int * c)
+{
+ int x, res;
+
+ /* if b is <= 0 then zero the int */
+ if (b <= 0) {
+ mp_zero (c);
+ return MP_OKAY;
+ }
+
+ /* if the modulus is larger than the value than return */
+ if (b >= (int) (a->used * DIGIT_BIT)) {
+ res = mp_copy (a, c);
+ return res;
+ }
+
+ /* copy */
+ if ((res = mp_copy (a, c)) != MP_OKAY) {
+ return res;
+ }
+
+ /* zero digits above the last digit of the modulus */
+ for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
+ c->dp[x] = 0;
+ }
+ /* clear the digit that is not completely outside/inside the modulus */
+ c->dp[b / DIGIT_BIT] &=
+ (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mod_2d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod_d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod_d.c
new file mode 100644
index 0000000000..9ca37e6732
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mod_d.c
@@ -0,0 +1,27 @@
+#include <tommath.h>
+#ifdef BN_MP_MOD_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+int
+mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
+{
+ return mp_div_d(a, b, NULL, c);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mod_d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_calc_normalization.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_calc_normalization.c
new file mode 100644
index 0000000000..c669fe0ec3
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_calc_normalization.c
@@ -0,0 +1,59 @@
+#include <tommath.h>
+#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/*
+ * shifts with subtractions when the result is greater than b.
+ *
+ * The method is slightly modified to shift B unconditionally upto just under
+ * the leading bit of b. This saves alot of multiple precision shifting.
+ */
+int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
+{
+ int x, bits, res;
+
+ /* how many bits of last digit does b use */
+ bits = mp_count_bits (b) % DIGIT_BIT;
+
+ if (b->used > 1) {
+ if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
+ return res;
+ }
+ } else {
+ mp_set(a, 1);
+ bits = 1;
+ }
+
+
+ /* now compute C = A * B mod b */
+ for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
+ if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
+ return res;
+ }
+ if (mp_cmp_mag (a, b) != MP_LT) {
+ if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
+ return res;
+ }
+ }
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_calc_normalization.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_reduce.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_reduce.c
new file mode 100644
index 0000000000..b76509051b
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_reduce.c
@@ -0,0 +1,118 @@
+#include <tommath.h>
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction */
+int
+mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+ int ix, res, digs;
+ mp_digit mu;
+
+ /* can the fast reduction [comba] method be used?
+ *
+ * Note that unlike in mul you're safely allowed *less*
+ * than the available columns [255 per default] since carries
+ * are fixed up in the inner loop.
+ */
+ digs = n->used * 2 + 1;
+ if ((digs < MP_WARRAY) &&
+ n->used <
+ (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ return fast_mp_montgomery_reduce (x, n, rho);
+ }
+
+ /* grow the input as required */
+ if (x->alloc < digs) {
+ if ((res = mp_grow (x, digs)) != MP_OKAY) {
+ return res;
+ }
+ }
+ x->used = digs;
+
+ for (ix = 0; ix < n->used; ix++) {
+ /* mu = ai * rho mod b
+ *
+ * The value of rho must be precalculated via
+ * montgomery_setup() such that
+ * it equals -1/n0 mod b this allows the
+ * following inner loop to reduce the
+ * input one digit at a time
+ */
+ mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
+
+ /* a = a + mu * m * b**i */
+ {
+ register int iy;
+ register mp_digit *tmpn, *tmpx, u;
+ register mp_word r;
+
+ /* alias for digits of the modulus */
+ tmpn = n->dp;
+
+ /* alias for the digits of x [the input] */
+ tmpx = x->dp + ix;
+
+ /* set the carry to zero */
+ u = 0;
+
+ /* Multiply and add in place */
+ for (iy = 0; iy < n->used; iy++) {
+ /* compute product and sum */
+ r = ((mp_word)mu) * ((mp_word)*tmpn++) +
+ ((mp_word) u) + ((mp_word) * tmpx);
+
+ /* get carry */
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+ /* fix digit */
+ *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
+ }
+ /* At this point the ix'th digit of x should be zero */
+
+
+ /* propagate carries upwards as required*/
+ while (u) {
+ *tmpx += u;
+ u = *tmpx >> DIGIT_BIT;
+ *tmpx++ &= MP_MASK;
+ }
+ }
+ }
+
+ /* at this point the n.used'th least
+ * significant digits of x are all zero
+ * which means we can shift x to the
+ * right by n.used digits and the
+ * residue is unchanged.
+ */
+
+ /* x = x/b**n.used */
+ mp_clamp(x);
+ mp_rshd (x, n->used);
+
+ /* if x >= n then x = x - n */
+ if (mp_cmp_mag (x, n) != MP_LT) {
+ return s_mp_sub (x, n, x);
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_reduce.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_setup.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_setup.c
new file mode 100644
index 0000000000..f08274936e
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_montgomery_setup.c
@@ -0,0 +1,59 @@
+#include <tommath.h>
+#ifdef BN_MP_MONTGOMERY_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* setups the montgomery reduction stuff */
+int
+mp_montgomery_setup (mp_int * n, mp_digit * rho)
+{
+ mp_digit x, b;
+
+/* fast inversion mod 2**k
+ *
+ * Based on the fact that
+ *
+ * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
+ * => 2*X*A - X*X*A*A = 1
+ * => 2*(1) - (1) = 1
+ */
+ b = n->dp[0];
+
+ if ((b & 1) == 0) {
+ return MP_VAL;
+ }
+
+ x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
+ x *= 2 - b * x; /* here x*a==1 mod 2**8 */
+#if !defined(MP_8BIT)
+ x *= 2 - b * x; /* here x*a==1 mod 2**16 */
+#endif
+#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
+ x *= 2 - b * x; /* here x*a==1 mod 2**32 */
+#endif
+#ifdef MP_64BIT
+ x *= 2 - b * x; /* here x*a==1 mod 2**64 */
+#endif
+
+ /* rho = -1/m mod b */
+ *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK;
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_montgomery_setup.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul.c
new file mode 100644
index 0000000000..8b1117a63b
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul.c
@@ -0,0 +1,66 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* high level multiplication (handles sign) */
+int mp_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, neg;
+ neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+
+ /* use Toom-Cook? */
+#ifdef BN_MP_TOOM_MUL_C
+ if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
+ res = mp_toom_mul(a, b, c);
+ } else
+#endif
+#ifdef BN_MP_KARATSUBA_MUL_C
+ /* use Karatsuba? */
+ if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
+ res = mp_karatsuba_mul (a, b, c);
+ } else
+#endif
+ {
+ /* can we use the fast multiplier?
+ *
+ * The fast multiplier can be used if the output will
+ * have less than MP_WARRAY digits and the number of
+ * digits won't affect carry propagation
+ */
+ int digs = a->used + b->used + 1;
+
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+ if ((digs < MP_WARRAY) &&
+ MIN(a->used, b->used) <=
+ (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ res = fast_s_mp_mul_digs (a, b, c, digs);
+ } else
+#endif
+#ifdef BN_S_MP_MUL_DIGS_C
+ res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
+#else
+ res = MP_VAL;
+#endif
+
+ }
+ c->sign = (c->used > 0) ? neg : MP_ZPOS;
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mul.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_2.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_2.c
new file mode 100644
index 0000000000..02455fc35d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_2.c
@@ -0,0 +1,82 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_2_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* b = a*2 */
+int mp_mul_2(mp_int * a, mp_int * b)
+{
+ int x, res, oldused;
+
+ /* grow to accomodate result */
+ if (b->alloc < a->used + 1) {
+ if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ oldused = b->used;
+ b->used = a->used;
+
+ {
+ register mp_digit r, rr, *tmpa, *tmpb;
+
+ /* alias for source */
+ tmpa = a->dp;
+
+ /* alias for dest */
+ tmpb = b->dp;
+
+ /* carry */
+ r = 0;
+ for (x = 0; x < a->used; x++) {
+
+ /* get what will be the *next* carry bit from the
+ * MSB of the current digit
+ */
+ rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
+
+ /* now shift up this digit, add in the carry [from the previous] */
+ *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
+
+ /* copy the carry that would be from the source
+ * digit into the next iteration
+ */
+ r = rr;
+ }
+
+ /* new leading digit? */
+ if (r != 0) {
+ /* add a MSB which is always 1 at this point */
+ *tmpb = 1;
+ ++(b->used);
+ }
+
+ /* now zero any excess digits on the destination
+ * that we didn't write to
+ */
+ tmpb = b->dp + b->used;
+ for (x = b->used; x < oldused; x++) {
+ *tmpb++ = 0;
+ }
+ }
+ b->sign = a->sign;
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_2d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_2d.c
new file mode 100644
index 0000000000..efeff2e751
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_2d.c
@@ -0,0 +1,85 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* shift left by a certain bit count */
+int mp_mul_2d (mp_int * a, int b, mp_int * c)
+{
+ mp_digit d;
+ int res;
+
+ /* copy */
+ if (a != c) {
+ if ((res = mp_copy (a, c)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
+ if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* shift by as many digits in the bit count */
+ if (b >= (int)DIGIT_BIT) {
+ if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* shift any bit count < DIGIT_BIT */
+ d = (mp_digit) (b % DIGIT_BIT);
+ if (d != 0) {
+ register mp_digit *tmpc, shift, mask, r, rr;
+ register int x;
+
+ /* bitmask for carries */
+ mask = (((mp_digit)1) << d) - 1;
+
+ /* shift for msbs */
+ shift = DIGIT_BIT - d;
+
+ /* alias */
+ tmpc = c->dp;
+
+ /* carry */
+ r = 0;
+ for (x = 0; x < c->used; x++) {
+ /* get the higher bits of the current word */
+ rr = (*tmpc >> shift) & mask;
+
+ /* shift the current word and OR in the carry */
+ *tmpc = ((*tmpc << d) | r) & MP_MASK;
+ ++tmpc;
+
+ /* set the carry to the carry bits of the current word */
+ r = rr;
+ }
+
+ /* set final carry */
+ if (r != 0) {
+ c->dp[(c->used)++] = r;
+ }
+ }
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mul_2d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_d.c
new file mode 100644
index 0000000000..00f9a899ef
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mul_d.c
@@ -0,0 +1,79 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* multiply by a digit */
+int
+mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ mp_digit u, *tmpa, *tmpc;
+ mp_word r;
+ int ix, res, olduse;
+
+ /* make sure c is big enough to hold a*b */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* get the original destinations used count */
+ olduse = c->used;
+
+ /* set the sign */
+ c->sign = a->sign;
+
+ /* alias for a->dp [source] */
+ tmpa = a->dp;
+
+ /* alias for c->dp [dest] */
+ tmpc = c->dp;
+
+ /* zero carry */
+ u = 0;
+
+ /* compute columns */
+ for (ix = 0; ix < a->used; ix++) {
+ /* compute product and carry sum for this term */
+ r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
+
+ /* mask off higher bits to get a single digit */
+ *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* send carry into next iteration */
+ u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+ }
+
+ /* store final carry [if any] and increment ix offset */
+ *tmpc++ = u;
+ ++ix;
+
+ /* now zero digits above the top */
+ while (ix++ < olduse) {
+ *tmpc++ = 0;
+ }
+
+ /* set used count */
+ c->used = a->used + 1;
+ mp_clamp(c);
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mul_d.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mulmod.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mulmod.c
new file mode 100644
index 0000000000..003ceb9b97
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_mulmod.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_MULMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* d = a * b (mod c) */
+int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ int res;
+ mp_int t;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ res = mp_mod (&t, c, d);
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_mulmod.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_n_root.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_n_root.c
new file mode 100644
index 0000000000..0e7bedca72
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_n_root.c
@@ -0,0 +1,132 @@
+#include <tommath.h>
+#ifdef BN_MP_N_ROOT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* find the n'th root of an integer
+ *
+ * Result found such that (c)**b <= a and (c+1)**b > a
+ *
+ * This algorithm uses Newton's approximation
+ * x[i+1] = x[i] - f(x[i])/f'(x[i])
+ * which will find the root in log(N) time where
+ * each step involves a fair bit. This is not meant to
+ * find huge roots [square and cube, etc].
+ */
+int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
+{
+ mp_int t1, t2, t3;
+ int res, neg;
+
+ /* input must be positive if b is even */
+ if ((b & 1) == 0 && a->sign == MP_NEG) {
+ return MP_VAL;
+ }
+
+ if ((res = mp_init (&t1)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_init (&t2)) != MP_OKAY) {
+ goto LBL_T1;
+ }
+
+ if ((res = mp_init (&t3)) != MP_OKAY) {
+ goto LBL_T2;
+ }
+
+ /* if a is negative fudge the sign but keep track */
+ neg = a->sign;
+ a->sign = MP_ZPOS;
+
+ /* t2 = 2 */
+ mp_set (&t2, 2);
+
+ do {
+ /* t1 = t2 */
+ if ((res = mp_copy (&t2, &t1)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
+
+ /* t3 = t1**(b-1) */
+ if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* numerator */
+ /* t2 = t1**b */
+ if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* t2 = t1**b - a */
+ if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* denominator */
+ /* t3 = t1**(b-1) * b */
+ if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ /* t3 = (t1**b - a)/(b * t1**(b-1)) */
+ if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+ } while (mp_cmp (&t1, &t2) != MP_EQ);
+
+ /* result can be off by a few so check */
+ for (;;) {
+ if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+
+ if (mp_cmp (&t2, a) == MP_GT) {
+ if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) {
+ goto LBL_T3;
+ }
+ } else {
+ break;
+ }
+ }
+
+ /* reset the sign of a first */
+ a->sign = neg;
+
+ /* set the result */
+ mp_exch (&t1, c);
+
+ /* set the sign of the result */
+ c->sign = neg;
+
+ res = MP_OKAY;
+
+LBL_T3:mp_clear (&t3);
+LBL_T2:mp_clear (&t2);
+LBL_T1:mp_clear (&t1);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_n_root.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_neg.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_neg.c
new file mode 100644
index 0000000000..a7d035ab6d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_neg.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_NEG_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* b = -a */
+int mp_neg (mp_int * a, mp_int * b)
+{
+ int res;
+ if (a != b) {
+ if ((res = mp_copy (a, b)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ if (mp_iszero(b) != MP_YES) {
+ b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+ } else {
+ b->sign = MP_ZPOS;
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_neg.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_or.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_or.c
new file mode 100644
index 0000000000..bff4995489
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_or.c
@@ -0,0 +1,50 @@
+#include <tommath.h>
+#ifdef BN_MP_OR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* OR two ints together */
+int mp_or (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, ix, px;
+ mp_int t, *x;
+
+ if (a->used > b->used) {
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+ px = b->used;
+ x = b;
+ } else {
+ if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+ return res;
+ }
+ px = a->used;
+ x = a;
+ }
+
+ for (ix = 0; ix < px; ix++) {
+ t.dp[ix] |= x->dp[ix];
+ }
+ mp_clamp (&t);
+ mp_exch (c, &t);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_or.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_fermat.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_fermat.c
new file mode 100644
index 0000000000..c23d77f6de
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_fermat.c
@@ -0,0 +1,62 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_FERMAT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* performs one Fermat test.
+ *
+ * If "a" were prime then b**a == b (mod a) since the order of
+ * the multiplicative sub-group would be phi(a) = a-1. That means
+ * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
+ *
+ * Sets result to 1 if the congruence holds, or zero otherwise.
+ */
+int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
+{
+ mp_int t;
+ int err;
+
+ /* default to composite */
+ *result = MP_NO;
+
+ /* ensure b > 1 */
+ if (mp_cmp_d(b, 1) != MP_GT) {
+ return MP_VAL;
+ }
+
+ /* init t */
+ if ((err = mp_init (&t)) != MP_OKAY) {
+ return err;
+ }
+
+ /* compute t = b**a mod a */
+ if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
+ goto LBL_T;
+ }
+
+ /* is it equal to b? */
+ if (mp_cmp (&t, b) == MP_EQ) {
+ *result = MP_YES;
+ }
+
+ err = MP_OKAY;
+LBL_T:mp_clear (&t);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_fermat.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_is_divisible.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_is_divisible.c
new file mode 100644
index 0000000000..8e7871c2c6
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_is_divisible.c
@@ -0,0 +1,50 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_IS_DIVISIBLE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* determines if an integers is divisible by one
+ * of the first PRIME_SIZE primes or not
+ *
+ * sets result to 0 if not, 1 if yes
+ */
+int mp_prime_is_divisible (mp_int * a, int *result)
+{
+ int err, ix;
+ mp_digit res;
+
+ /* default to not */
+ *result = MP_NO;
+
+ for (ix = 0; ix < PRIME_SIZE; ix++) {
+ /* what is a mod LBL_prime_tab[ix] */
+ if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
+ return err;
+ }
+
+ /* is the residue zero? */
+ if (res == 0) {
+ *result = MP_YES;
+ return MP_OKAY;
+ }
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_divisible.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_is_prime.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_is_prime.c
new file mode 100644
index 0000000000..c316d62109
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_is_prime.c
@@ -0,0 +1,83 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_IS_PRIME_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* performs a variable number of rounds of Miller-Rabin
+ *
+ * Probability of error after t rounds is no more than
+
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime (mp_int * a, int t, int *result)
+{
+ mp_int b;
+ int ix, err, res;
+
+ /* default to no */
+ *result = MP_NO;
+
+ /* valid value of t? */
+ if (t <= 0 || t > PRIME_SIZE) {
+ return MP_VAL;
+ }
+
+ /* is the input equal to one of the primes in the table? */
+ for (ix = 0; ix < PRIME_SIZE; ix++) {
+ if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
+ *result = 1;
+ return MP_OKAY;
+ }
+ }
+
+ /* first perform trial division */
+ if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
+ return err;
+ }
+
+ /* return if it was trivially divisible */
+ if (res == MP_YES) {
+ return MP_OKAY;
+ }
+
+ /* now perform the miller-rabin rounds */
+ if ((err = mp_init (&b)) != MP_OKAY) {
+ return err;
+ }
+
+ for (ix = 0; ix < t; ix++) {
+ /* set the prime */
+ mp_set (&b, ltm_prime_tab[ix]);
+
+ if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
+ goto LBL_B;
+ }
+
+ if (res == MP_NO) {
+ goto LBL_B;
+ }
+ }
+
+ /* passed the test */
+ *result = MP_YES;
+LBL_B:mp_clear (&b);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_is_prime.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_miller_rabin.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_miller_rabin.c
new file mode 100644
index 0000000000..ddf03582ac
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_miller_rabin.c
@@ -0,0 +1,103 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_MILLER_RABIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* Miller-Rabin test of "a" to the base of "b" as described in
+ * HAC pp. 139 Algorithm 4.24
+ *
+ * Sets result to 0 if definitely composite or 1 if probably prime.
+ * Randomly the chance of error is no more than 1/4 and often
+ * very much lower.
+ */
+int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
+{
+ mp_int n1, y, r;
+ int s, j, err;
+
+ /* default */
+ *result = MP_NO;
+
+ /* ensure b > 1 */
+ if (mp_cmp_d(b, 1) != MP_GT) {
+ return MP_VAL;
+ }
+
+ /* get n1 = a - 1 */
+ if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
+ return err;
+ }
+ if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
+ goto LBL_N1;
+ }
+
+ /* set 2**s * r = n1 */
+ if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
+ goto LBL_N1;
+ }
+
+ /* count the number of least significant bits
+ * which are zero
+ */
+ s = mp_cnt_lsb(&r);
+
+ /* now divide n - 1 by 2**s */
+ if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
+ goto LBL_R;
+ }
+
+ /* compute y = b**r mod a */
+ if ((err = mp_init (&y)) != MP_OKAY) {
+ goto LBL_R;
+ }
+ if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* if y != 1 and y != n1 do */
+ if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
+ j = 1;
+ /* while j <= s-1 and y != n1 */
+ while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
+ if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* if y == 1 then composite */
+ if (mp_cmp_d (&y, 1) == MP_EQ) {
+ goto LBL_Y;
+ }
+
+ ++j;
+ }
+
+ /* if y != n1 then composite */
+ if (mp_cmp (&y, &n1) != MP_EQ) {
+ goto LBL_Y;
+ }
+ }
+
+ /* probably prime now */
+ *result = MP_YES;
+LBL_Y:mp_clear (&y);
+LBL_R:mp_clear (&r);
+LBL_N1:mp_clear (&n1);
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_miller_rabin.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_next_prime.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_next_prime.c
new file mode 100644
index 0000000000..daf2ec7c64
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_next_prime.c
@@ -0,0 +1,170 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_NEXT_PRIME_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
+{
+ int err, res, x, y;
+ mp_digit res_tab[PRIME_SIZE], step, kstep;
+ mp_int b;
+
+ /* ensure t is valid */
+ if (t <= 0 || t > PRIME_SIZE) {
+ return MP_VAL;
+ }
+
+ /* force positive */
+ a->sign = MP_ZPOS;
+
+ /* simple algo if a is less than the largest prime in the table */
+ if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) {
+ /* find which prime it is bigger than */
+ for (x = PRIME_SIZE - 2; x >= 0; x--) {
+ if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
+ if (bbs_style == 1) {
+ /* ok we found a prime smaller or
+ * equal [so the next is larger]
+ *
+ * however, the prime must be
+ * congruent to 3 mod 4
+ */
+ if ((ltm_prime_tab[x + 1] & 3) != 3) {
+ /* scan upwards for a prime congruent to 3 mod 4 */
+ for (y = x + 1; y < PRIME_SIZE; y++) {
+ if ((ltm_prime_tab[y] & 3) == 3) {
+ mp_set(a, ltm_prime_tab[y]);
+ return MP_OKAY;
+ }
+ }
+ }
+ } else {
+ mp_set(a, ltm_prime_tab[x + 1]);
+ return MP_OKAY;
+ }
+ }
+ }
+ /* at this point a maybe 1 */
+ if (mp_cmp_d(a, 1) == MP_EQ) {
+ mp_set(a, 2);
+ return MP_OKAY;
+ }
+ /* fall through to the sieve */
+ }
+
+ /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */
+ if (bbs_style == 1) {
+ kstep = 4;
+ } else {
+ kstep = 2;
+ }
+
+ /* at this point we will use a combination of a sieve and Miller-Rabin */
+
+ if (bbs_style == 1) {
+ /* if a mod 4 != 3 subtract the correct value to make it so */
+ if ((a->dp[0] & 3) != 3) {
+ if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; };
+ }
+ } else {
+ if (mp_iseven(a) == 1) {
+ /* force odd */
+ if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) {
+ return err;
+ }
+ }
+ }
+
+ /* generate the restable */
+ for (x = 1; x < PRIME_SIZE; x++) {
+ if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) {
+ return err;
+ }
+ }
+
+ /* init temp used for Miller-Rabin Testing */
+ if ((err = mp_init(&b)) != MP_OKAY) {
+ return err;
+ }
+
+ for (;;) {
+ /* skip to the next non-trivially divisible candidate */
+ step = 0;
+ do {
+ /* y == 1 if any residue was zero [e.g. cannot be prime] */
+ y = 0;
+
+ /* increase step to next candidate */
+ step += kstep;
+
+ /* compute the new residue without using division */
+ for (x = 1; x < PRIME_SIZE; x++) {
+ /* add the step to each residue */
+ res_tab[x] += kstep;
+
+ /* subtract the modulus [instead of using division] */
+ if (res_tab[x] >= ltm_prime_tab[x]) {
+ res_tab[x] -= ltm_prime_tab[x];
+ }
+
+ /* set flag if zero */
+ if (res_tab[x] == 0) {
+ y = 1;
+ }
+ }
+ } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep));
+
+ /* add the step */
+ if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+
+ /* if didn't pass sieve and step == MAX then skip test */
+ if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) {
+ continue;
+ }
+
+ /* is this prime? */
+ for (x = 0; x < t; x++) {
+ mp_set(&b, ltm_prime_tab[t]);
+ if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if (res == MP_NO) {
+ break;
+ }
+ }
+
+ if (res == MP_YES) {
+ break;
+ }
+ }
+
+ err = MP_OKAY;
+LBL_ERR:
+ mp_clear(&b);
+ return err;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_next_prime.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_rabin_miller_trials.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_rabin_miller_trials.c
new file mode 100644
index 0000000000..248c2fd2e6
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_rabin_miller_trials.c
@@ -0,0 +1,52 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+
+static const struct {
+ int k, t;
+} sizes[] = {
+{ 128, 28 },
+{ 256, 16 },
+{ 384, 10 },
+{ 512, 7 },
+{ 640, 6 },
+{ 768, 5 },
+{ 896, 4 },
+{ 1024, 4 }
+};
+
+/* returns # of RM trials required for a given bit size */
+int mp_prime_rabin_miller_trials(int size)
+{
+ int x;
+
+ for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
+ if (sizes[x].k == size) {
+ return sizes[x].t;
+ } else if (sizes[x].k > size) {
+ return (x == 0) ? sizes[0].t : sizes[x - 1].t;
+ }
+ }
+ return sizes[x-1].t + 1;
+}
+
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_rabin_miller_trials.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_random_ex.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_random_ex.c
new file mode 100644
index 0000000000..07aae4b072
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_prime_random_ex.c
@@ -0,0 +1,125 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_RANDOM_EX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ *
+ * LTM_PRIME_BBS - make prime congruent to 3 mod 4
+ * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+
+/* This is possibly the mother of all prime generation functions, muahahahahaha! */
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat)
+{
+ unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
+ int res, err, bsize, maskOR_msb_offset;
+
+ /* sanity check the input */
+ if (size <= 1 || t <= 0) {
+ return MP_VAL;
+ }
+
+ /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */
+ if (flags & LTM_PRIME_SAFE) {
+ flags |= LTM_PRIME_BBS;
+ }
+
+ /* calc the byte size */
+ bsize = (size>>3) + ((size&7)?1:0);
+
+ /* we need a buffer of bsize bytes */
+ tmp = OPT_CAST(unsigned char) XMALLOC(bsize);
+ if (tmp == NULL) {
+ return MP_MEM;
+ }
+
+ /* calc the maskAND value for the MSbyte*/
+ maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7)));
+
+ /* calc the maskOR_msb */
+ maskOR_msb = 0;
+ maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0;
+ if (flags & LTM_PRIME_2MSB_ON) {
+ maskOR_msb |= 0x80 >> ((9 - size) & 7);
+ }
+
+ /* get the maskOR_lsb */
+ maskOR_lsb = 1;
+ if (flags & LTM_PRIME_BBS) {
+ maskOR_lsb |= 3;
+ }
+
+ do {
+ /* read the bytes */
+ if (cb(tmp, bsize, dat) != bsize) {
+ err = MP_VAL;
+ goto error;
+ }
+
+ /* work over the MSbyte */
+ tmp[0] &= maskAND;
+ tmp[0] |= 1 << ((size - 1) & 7);
+
+ /* mix in the maskORs */
+ tmp[maskOR_msb_offset] |= maskOR_msb;
+ tmp[bsize-1] |= maskOR_lsb;
+
+ /* read it in */
+ if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; }
+
+ /* is it prime? */
+ if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
+ if (res == MP_NO) {
+ continue;
+ }
+
+ if (flags & LTM_PRIME_SAFE) {
+ /* see if (a-1)/2 is prime */
+ if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; }
+ if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; }
+
+ /* is it prime? */
+ if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; }
+ }
+ } while (res == MP_NO);
+
+ if (flags & LTM_PRIME_SAFE) {
+ /* restore a to the original value */
+ if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; }
+ if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; }
+ }
+
+ err = MP_OKAY;
+error:
+ XFREE(tmp);
+ return err;
+}
+
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_prime_random_ex.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_radix_size.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_radix_size.c
new file mode 100644
index 0000000000..1b61e3a1be
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_radix_size.c
@@ -0,0 +1,78 @@
+#include <tommath.h>
+#ifdef BN_MP_RADIX_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* returns size of ASCII reprensentation */
+int mp_radix_size (mp_int * a, int radix, int *size)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+
+ *size = 0;
+
+ /* special case for binary */
+ if (radix == 2) {
+ *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+ return MP_OKAY;
+ }
+
+ /* make sure the radix is in range */
+ if (radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ if (mp_iszero(a) == MP_YES) {
+ *size = 2;
+ return MP_OKAY;
+ }
+
+ /* digs is the digit count */
+ digs = 0;
+
+ /* if it's negative add one for the sign */
+ if (a->sign == MP_NEG) {
+ ++digs;
+ }
+
+ /* init a copy of the input */
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* force temp to positive */
+ t.sign = MP_ZPOS;
+
+ /* fetch out all of the digits */
+ while (mp_iszero (&t) == MP_NO) {
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ ++digs;
+ }
+ mp_clear (&t);
+
+ /* return digs + 1, the 1 is for the NULL byte that would be required. */
+ *size = digs + 1;
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_radix_size.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_radix_smap.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_radix_smap.c
new file mode 100644
index 0000000000..7d72feb84e
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_radix_smap.c
@@ -0,0 +1,24 @@
+#include <tommath.h>
+#ifdef BN_MP_RADIX_SMAP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* chars used in radix conversions */
+const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_radix_smap.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_rand.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_rand.c
new file mode 100644
index 0000000000..af66a67eea
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_rand.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_RAND_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* makes a pseudo-random int of a given size */
+int
+mp_rand (mp_int * a, int digits)
+{
+ int res;
+ mp_digit d;
+
+ mp_zero (a);
+ if (digits <= 0) {
+ return MP_OKAY;
+ }
+
+ /* first place a random non-zero digit */
+ do {
+ d = ((mp_digit) abs (rand ())) & MP_MASK;
+ } while (d == 0);
+
+ if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
+ return res;
+ }
+
+ while (--digits > 0) {
+ if ((res = mp_lshd (a, 1)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_rand.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_radix.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_radix.c
new file mode 100644
index 0000000000..91c46c22f7
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_radix.c
@@ -0,0 +1,85 @@
+#include <tommath.h>
+#ifdef BN_MP_READ_RADIX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* read a string [ASCII] in a given radix */
+int mp_read_radix (mp_int * a, const char *str, int radix)
+{
+ int y, res, neg;
+ char ch;
+
+ /* zero the digit bignum */
+ mp_zero(a);
+
+ /* make sure the radix is ok */
+ if (radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ /* if the leading digit is a
+ * minus set the sign to negative.
+ */
+ if (*str == '-') {
+ ++str;
+ neg = MP_NEG;
+ } else {
+ neg = MP_ZPOS;
+ }
+
+ /* set the integer to the default of zero */
+ mp_zero (a);
+
+ /* process each digit of the string */
+ while (*str) {
+ /* if the radix < 36 the conversion is case insensitive
+ * this allows numbers like 1AB and 1ab to represent the same value
+ * [e.g. in hex]
+ */
+ ch = (char) ((radix < 36) ? toupper (*str) : *str);
+ for (y = 0; y < 64; y++) {
+ if (ch == mp_s_rmap[y]) {
+ break;
+ }
+ }
+
+ /* if the char was found in the map
+ * and is less than the given radix add it
+ * to the number, otherwise exit the loop.
+ */
+ if (y < radix) {
+ if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
+ return res;
+ }
+ if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
+ return res;
+ }
+ } else {
+ break;
+ }
+ ++str;
+ }
+
+ /* set the sign only if a != 0 */
+ if (mp_iszero(a) != 1) {
+ a->sign = neg;
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_read_radix.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_signed_bin.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_signed_bin.c
new file mode 100644
index 0000000000..8da651ce30
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_signed_bin.c
@@ -0,0 +1,41 @@
+#include <tommath.h>
+#ifdef BN_MP_READ_SIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* read signed bin, big endian, first byte is 0==positive or 1==negative */
+int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c)
+{
+ int res;
+
+ /* read magnitude */
+ if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
+ return res;
+ }
+
+ /* first byte is 0 for positive, non-zero for negative */
+ if (b[0] == 0) {
+ a->sign = MP_ZPOS;
+ } else {
+ a->sign = MP_NEG;
+ }
+
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_read_signed_bin.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_unsigned_bin.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_unsigned_bin.c
new file mode 100644
index 0000000000..1ebba13a02
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_read_unsigned_bin.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_READ_UNSIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* reads a unsigned char array, assumes the msb is stored first [big endian] */
+int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
+{
+ int res;
+
+ /* make sure there are at least two digits */
+ if (a->alloc < 2) {
+ if ((res = mp_grow(a, 2)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* zero the int */
+ mp_zero (a);
+
+ /* read the bytes in */
+ while (c-- > 0) {
+ if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
+ return res;
+ }
+
+#ifndef MP_8BIT
+ a->dp[0] |= *b++;
+ a->used += 1;
+#else
+ a->dp[0] = (*b & MP_MASK);
+ a->dp[1] |= ((*b++ >> 7U) & 1);
+ a->used += 2;
+#endif
+ }
+ mp_clamp (a);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_read_unsigned_bin.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce.c
new file mode 100644
index 0000000000..21d0730905
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce.c
@@ -0,0 +1,100 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* reduces x mod m, assumes 0 < x < m**2, mu is
+ * precomputed via mp_reduce_setup.
+ * From HAC pp.604 Algorithm 14.42
+ */
+int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
+{
+ mp_int q;
+ int res, um = m->used;
+
+ /* q = x */
+ if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
+ return res;
+ }
+
+ /* q1 = x / b**(k-1) */
+ mp_rshd (&q, um - 1);
+
+ /* according to HAC this optimization is ok */
+ if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
+ if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+ } else {
+#ifdef BN_S_MP_MUL_HIGH_DIGS_C
+ if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+ if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+#else
+ {
+ res = MP_VAL;
+ goto CLEANUP;
+ }
+#endif
+ }
+
+ /* q3 = q2 / b**(k+1) */
+ mp_rshd (&q, um + 1);
+
+ /* x = x mod b**(k+1), quick (no division) */
+ if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+
+ /* q = q * m mod b**(k+1), quick (no division) */
+ if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+
+ /* x = x - q */
+ if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+
+ /* If x < 0, add b**(k+1) to it */
+ if (mp_cmp_d (x, 0) == MP_LT) {
+ mp_set (&q, 1);
+ if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
+ goto CLEANUP;
+ if ((res = mp_add (x, &q, x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ /* Back off if it's too big */
+ while (mp_cmp (x, m) != MP_LT) {
+ if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
+ goto CLEANUP;
+ }
+ }
+
+CLEANUP:
+ mp_clear (&q);
+
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k.c
new file mode 100644
index 0000000000..d9620c221c
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k.c
@@ -0,0 +1,61 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* reduces a modulo n where n is of the form 2**p - d */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
+{
+ mp_int q;
+ int p, res;
+
+ if ((res = mp_init(&q)) != MP_OKAY) {
+ return res;
+ }
+
+ p = mp_count_bits(n);
+top:
+ /* q = a/2**p, a = a mod 2**p */
+ if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if (d != 1) {
+ /* q = q * d */
+ if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
+ goto ERR;
+ }
+ }
+
+ /* a = a + q */
+ if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if (mp_cmp_mag(a, n) != MP_LT) {
+ s_mp_sub(a, n, a);
+ goto top;
+ }
+
+ERR:
+ mp_clear(&q);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_l.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_l.c
new file mode 100644
index 0000000000..f06103d6a6
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_l.c
@@ -0,0 +1,62 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* reduces a modulo n where n is of the form 2**p - d
+ This differs from reduce_2k since "d" can be larger
+ than a single digit.
+*/
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
+{
+ mp_int q;
+ int p, res;
+
+ if ((res = mp_init(&q)) != MP_OKAY) {
+ return res;
+ }
+
+ p = mp_count_bits(n);
+top:
+ /* q = a/2**p, a = a mod 2**p */
+ if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* q = q * d */
+ if ((res = mp_mul(&q, d, &q)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* a = a + q */
+ if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if (mp_cmp_mag(a, n) != MP_LT) {
+ s_mp_sub(a, n, a);
+ goto top;
+ }
+
+ERR:
+ mp_clear(&q);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_l.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_setup.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_setup.c
new file mode 100644
index 0000000000..a80e7a22f2
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_setup.c
@@ -0,0 +1,47 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* determines the setup value */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
+{
+ int res, p;
+ mp_int tmp;
+
+ if ((res = mp_init(&tmp)) != MP_OKAY) {
+ return res;
+ }
+
+ p = mp_count_bits(a);
+ if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
+ mp_clear(&tmp);
+ return res;
+ }
+
+ if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
+ mp_clear(&tmp);
+ return res;
+ }
+
+ *d = tmp.dp[0];
+ mp_clear(&tmp);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_setup_l.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_setup_l.c
new file mode 100644
index 0000000000..7cf002e888
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_2k_setup_l.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_SETUP_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* determines the setup value */
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
+{
+ int res;
+ mp_int tmp;
+
+ if ((res = mp_init(&tmp)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ERR:
+ mp_clear(&tmp);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_2k_setup_l.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_is_2k.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_is_2k.c
new file mode 100644
index 0000000000..7308be73e2
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_is_2k.c
@@ -0,0 +1,52 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_IS_2K_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* determines if mp_reduce_2k can be used */
+int mp_reduce_is_2k(mp_int *a)
+{
+ int ix, iy, iw;
+ mp_digit iz;
+
+ if (a->used == 0) {
+ return MP_NO;
+ } else if (a->used == 1) {
+ return MP_YES;
+ } else if (a->used > 1) {
+ iy = mp_count_bits(a);
+ iz = 1;
+ iw = 1;
+
+ /* Test every bit from the second digit up, must be 1 */
+ for (ix = DIGIT_BIT; ix < iy; ix++) {
+ if ((a->dp[iw] & iz) == 0) {
+ return MP_NO;
+ }
+ iz <<= 1;
+ if (iz > (mp_digit)MP_MASK) {
+ ++iw;
+ iz = 1;
+ }
+ }
+ }
+ return MP_YES;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_is_2k_l.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_is_2k_l.c
new file mode 100644
index 0000000000..14a4d21846
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_is_2k_l.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_IS_2K_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* determines if reduce_2k_l can be used */
+int mp_reduce_is_2k_l(mp_int *a)
+{
+ int ix, iy;
+
+ if (a->used == 0) {
+ return MP_NO;
+ } else if (a->used == 1) {
+ return MP_YES;
+ } else if (a->used > 1) {
+ /* if more than half of the digits are -1 we're sold */
+ for (iy = ix = 0; ix < a->used; ix++) {
+ if (a->dp[ix] == MP_MASK) {
+ ++iy;
+ }
+ }
+ return (iy >= (a->used/2)) ? MP_YES : MP_NO;
+
+ }
+ return MP_NO;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_is_2k_l.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_setup.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_setup.c
new file mode 100644
index 0000000000..370f20bb17
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_reduce_setup.c
@@ -0,0 +1,34 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* pre-calculate the value required for Barrett reduction
+ * For a given modulus "b" it calulates the value required in "a"
+ */
+int mp_reduce_setup (mp_int * a, mp_int * b)
+{
+ int res;
+
+ if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
+ return res;
+ }
+ return mp_div (a, b, a, NULL);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_reduce_setup.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_rshd.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_rshd.c
new file mode 100644
index 0000000000..2a693c5a5b
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_rshd.c
@@ -0,0 +1,72 @@
+#include <tommath.h>
+#ifdef BN_MP_RSHD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* shift right a certain amount of digits */
+void mp_rshd (mp_int * a, int b)
+{
+ int x;
+
+ /* if b <= 0 then ignore it */
+ if (b <= 0) {
+ return;
+ }
+
+ /* if b > used then simply zero it and return */
+ if (a->used <= b) {
+ mp_zero (a);
+ return;
+ }
+
+ {
+ register mp_digit *bottom, *top;
+
+ /* shift the digits down */
+
+ /* bottom */
+ bottom = a->dp;
+
+ /* top [offset into digits] */
+ top = a->dp + b;
+
+ /* this is implemented as a sliding window where
+ * the window is b-digits long and digits from
+ * the top of the window are copied to the bottom
+ *
+ * e.g.
+
+ b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
+ /\ | ---->
+ \-------------------/ ---->
+ */
+ for (x = 0; x < (a->used - b); x++) {
+ *bottom++ = *top++;
+ }
+
+ /* zero the top digits */
+ for (; x < a->used; x++) {
+ *bottom++ = 0;
+ }
+ }
+
+ /* remove excess digits */
+ a->used -= b;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_rshd.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_set.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_set.c
new file mode 100644
index 0000000000..174adcbc6d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_set.c
@@ -0,0 +1,29 @@
+#include <tommath.h>
+#ifdef BN_MP_SET_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* set to a digit */
+void mp_set (mp_int * a, mp_digit b)
+{
+ mp_zero (a);
+ a->dp[0] = b & MP_MASK;
+ a->used = (a->dp[0] != 0) ? 1 : 0;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_set.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_set_int.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_set_int.c
new file mode 100644
index 0000000000..cf10ea1a44
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_set_int.c
@@ -0,0 +1,48 @@
+#include <tommath.h>
+#ifdef BN_MP_SET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* set a 32-bit const */
+int mp_set_int (mp_int * a, unsigned long b)
+{
+ int x, res;
+
+ mp_zero (a);
+
+ /* set four bits at a time */
+ for (x = 0; x < 8; x++) {
+ /* shift the number up four bits */
+ if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* OR in the top four bits of the source */
+ a->dp[0] |= (b >> 28) & 15;
+
+ /* shift the source up to the next four bits */
+ b <<= 4;
+
+ /* ensure that digits are not clamped off */
+ a->used += 1;
+ }
+ mp_clamp (a);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_set_int.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_shrink.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_shrink.c
new file mode 100644
index 0000000000..4b8c5ef11a
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_shrink.c
@@ -0,0 +1,35 @@
+#include <tommath.h>
+#ifdef BN_MP_SHRINK_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* shrink a bignum */
+int mp_shrink (mp_int * a)
+{
+ mp_digit *tmp;
+ if (a->alloc != a->used && a->used > 0) {
+ if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
+ return MP_MEM;
+ }
+ a->dp = tmp;
+ a->alloc = a->used;
+ }
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_shrink.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_signed_bin_size.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_signed_bin_size.c
new file mode 100644
index 0000000000..6739d19e2b
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_signed_bin_size.c
@@ -0,0 +1,27 @@
+#include <tommath.h>
+#ifdef BN_MP_SIGNED_BIN_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* get the size for an signed equivalent */
+int mp_signed_bin_size (mp_int * a)
+{
+ return 1 + mp_unsigned_bin_size (a);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_signed_bin_size.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqr.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqr.c
new file mode 100644
index 0000000000..868ccbbaef
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqr.c
@@ -0,0 +1,58 @@
+#include <tommath.h>
+#ifdef BN_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* computes b = a*a */
+int
+mp_sqr (mp_int * a, mp_int * b)
+{
+ int res;
+
+#ifdef BN_MP_TOOM_SQR_C
+ /* use Toom-Cook? */
+ if (a->used >= TOOM_SQR_CUTOFF) {
+ res = mp_toom_sqr(a, b);
+ /* Karatsuba? */
+ } else
+#endif
+#ifdef BN_MP_KARATSUBA_SQR_C
+if (a->used >= KARATSUBA_SQR_CUTOFF) {
+ res = mp_karatsuba_sqr (a, b);
+ } else
+#endif
+ {
+#ifdef BN_FAST_S_MP_SQR_C
+ /* can we use the fast comba multiplier? */
+ if ((a->used * 2 + 1) < MP_WARRAY &&
+ a->used <
+ (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
+ res = fast_s_mp_sqr (a, b);
+ } else
+#endif
+#ifdef BN_S_MP_SQR_C
+ res = s_mp_sqr (a, b);
+#else
+ res = MP_VAL;
+#endif
+ }
+ b->sign = MP_ZPOS;
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sqr.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqrmod.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqrmod.c
new file mode 100644
index 0000000000..161cbbb30d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqrmod.c
@@ -0,0 +1,41 @@
+#include <tommath.h>
+#ifdef BN_MP_SQRMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* c = a * a (mod b) */
+int
+mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res;
+ mp_int t;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_sqr (a, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ res = mp_mod (&t, b, c);
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sqrmod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqrt.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqrt.c
new file mode 100644
index 0000000000..8fd057ceed
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sqrt.c
@@ -0,0 +1,81 @@
+#include <tommath.h>
+#ifdef BN_MP_SQRT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* this function is less generic than mp_n_root, simpler and faster */
+int mp_sqrt(mp_int *arg, mp_int *ret)
+{
+ int res;
+ mp_int t1,t2;
+
+ /* must be positive */
+ if (arg->sign == MP_NEG) {
+ return MP_VAL;
+ }
+
+ /* easy out */
+ if (mp_iszero(arg) == MP_YES) {
+ mp_zero(ret);
+ return MP_OKAY;
+ }
+
+ if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_init(&t2)) != MP_OKAY) {
+ goto E2;
+ }
+
+ /* First approx. (not very bad for large arg) */
+ mp_rshd (&t1,t1.used/2);
+
+ /* t1 > 0 */
+ if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ /* And now t1 > sqrt(arg) */
+ do {
+ if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ /* t1 >= sqrt(arg) >= t2 at this point */
+ } while (mp_cmp_mag(&t1,&t2) == MP_GT);
+
+ mp_exch(&t1,ret);
+
+E1: mp_clear(&t2);
+E2: mp_clear(&t1);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sqrt.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sub.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sub.c
new file mode 100644
index 0000000000..f5015cce45
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sub.c
@@ -0,0 +1,59 @@
+#include <tommath.h>
+#ifdef BN_MP_SUB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* high level subtraction (handles signs) */
+int
+mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+ int sa, sb, res;
+
+ sa = a->sign;
+ sb = b->sign;
+
+ if (sa != sb) {
+ /* subtract a negative from a positive, OR */
+ /* subtract a positive from a negative. */
+ /* In either case, ADD their magnitudes, */
+ /* and use the sign of the first number. */
+ c->sign = sa;
+ res = s_mp_add (a, b, c);
+ } else {
+ /* subtract a positive from a positive, OR */
+ /* subtract a negative from a negative. */
+ /* First, take the difference between their */
+ /* magnitudes, then... */
+ if (mp_cmp_mag (a, b) != MP_LT) {
+ /* Copy the sign from the first */
+ c->sign = sa;
+ /* The first has a larger or equal magnitude */
+ res = s_mp_sub (a, b, c);
+ } else {
+ /* The result has the *opposite* sign from */
+ /* the first number. */
+ c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+ /* The second has a larger magnitude */
+ res = s_mp_sub (b, a, c);
+ }
+ }
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sub.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sub_d.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sub_d.c
new file mode 100644
index 0000000000..06cdca636d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_sub_d.c
@@ -0,0 +1,93 @@
+#include <tommath.h>
+#ifdef BN_MP_SUB_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* single digit subtraction */
+int
+mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ mp_digit *tmpa, *tmpc, mu;
+ int res, ix, oldused;
+
+ /* grow c as required */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* if a is negative just do an unsigned
+ * addition [with fudged signs]
+ */
+ if (a->sign == MP_NEG) {
+ a->sign = MP_ZPOS;
+ res = mp_add_d(a, b, c);
+ a->sign = c->sign = MP_NEG;
+
+ /* clamp */
+ mp_clamp(c);
+
+ return res;
+ }
+
+ /* setup regs */
+ oldused = c->used;
+ tmpa = a->dp;
+ tmpc = c->dp;
+
+ /* if a <= b simply fix the single digit */
+ if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
+ if (a->used == 1) {
+ *tmpc++ = b - *tmpa;
+ } else {
+ *tmpc++ = b;
+ }
+ ix = 1;
+
+ /* negative/1digit */
+ c->sign = MP_NEG;
+ c->used = 1;
+ } else {
+ /* positive/size */
+ c->sign = MP_ZPOS;
+ c->used = a->used;
+
+ /* subtract first digit */
+ *tmpc = *tmpa++ - b;
+ mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+ *tmpc++ &= MP_MASK;
+
+ /* handle rest of the digits */
+ for (ix = 1; ix < a->used; ix++) {
+ *tmpc = *tmpa++ - mu;
+ mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+ *tmpc++ &= MP_MASK;
+ }
+ }
+
+ /* zero excess digits */
+ while (ix++ < oldused) {
+ *tmpc++ = 0;
+ }
+ mp_clamp(c);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_sub_d.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_submod.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_submod.c
new file mode 100644
index 0000000000..869e23cded
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_submod.c
@@ -0,0 +1,42 @@
+#include <tommath.h>
+#ifdef BN_MP_SUBMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* d = a - b (mod c) */
+int
+mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ int res;
+ mp_int t;
+
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ res = mp_mod (&t, c, d);
+ mp_clear (&t);
+ return res;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_submod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_signed_bin.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_signed_bin.c
new file mode 100644
index 0000000000..9df83ca526
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_signed_bin.c
@@ -0,0 +1,33 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_SIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* store in signed [big endian] format */
+int mp_to_signed_bin (mp_int * a, unsigned char *b)
+{
+ int res;
+
+ if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) {
+ return res;
+ }
+ b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_signed_bin_n.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_signed_bin_n.c
new file mode 100644
index 0000000000..677f827d4f
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_signed_bin_n.c
@@ -0,0 +1,31 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_SIGNED_BIN_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* store in signed [big endian] format */
+int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
+{
+ if (*outlen < (unsigned long)mp_signed_bin_size(a)) {
+ return MP_VAL;
+ }
+ *outlen = mp_signed_bin_size(a);
+ return mp_to_signed_bin(a, b);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_to_signed_bin_n.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_unsigned_bin.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_unsigned_bin.c
new file mode 100644
index 0000000000..c137f104ac
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_unsigned_bin.c
@@ -0,0 +1,48 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_UNSIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
+{
+ int x, res;
+ mp_int t;
+
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ x = 0;
+ while (mp_iszero (&t) == 0) {
+#ifndef MP_8BIT
+ b[x++] = (unsigned char) (t.dp[0] & 255);
+#else
+ b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
+#endif
+ if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ }
+ bn_reverse (b, x);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_unsigned_bin_n.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_unsigned_bin_n.c
new file mode 100644
index 0000000000..0dc00c623d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_to_unsigned_bin_n.c
@@ -0,0 +1,31 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_UNSIGNED_BIN_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
+{
+ if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) {
+ return MP_VAL;
+ }
+ *outlen = mp_unsigned_bin_size(a);
+ return mp_to_unsigned_bin(a, b);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_to_unsigned_bin_n.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toom_mul.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toom_mul.c
new file mode 100644
index 0000000000..ad5d9e9b64
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toom_mul.c
@@ -0,0 +1,284 @@
+#include <tommath.h>
+#ifdef BN_MP_TOOM_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* multiplication using the Toom-Cook 3-way algorithm
+ *
+ * Much more complicated than Karatsuba but has a lower
+ * asymptotic running time of O(N**1.464). This algorithm is
+ * only particularly useful on VERY large inputs
+ * (we're talking 1000s of digits here...).
+*/
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
+{
+ mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
+ int res, B;
+
+ /* init temps */
+ if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
+ &a0, &a1, &a2, &b0, &b1,
+ &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* B */
+ B = MIN(a->used, b->used) / 3;
+
+ /* a = a2 * B**2 + a1 * B + a0 */
+ if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a1, B);
+ mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+ if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a2, B*2);
+
+ /* b = b2 * B**2 + b1 * B + b0 */
+ if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_copy(b, &b1)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&b1, B);
+ mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
+
+ if ((res = mp_copy(b, &b2)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&b2, B*2);
+
+ /* w0 = a0*b0 */
+ if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w4 = a2 * b2 */
+ if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
+ if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
+ if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+
+
+ /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
+ if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* now solve the matrix
+
+ 0 0 0 0 1
+ 1 2 4 8 16
+ 1 1 1 1 1
+ 16 8 4 2 1
+ 1 0 0 0 0
+
+ using 12 subtractions, 4 shifts,
+ 2 small divisions and 1 small multiplication
+ */
+
+ /* r1 - r4 */
+ if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r0 */
+ if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/2 */
+ if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/2 */
+ if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r2 - r0 - r4 */
+ if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - 8r0 */
+ if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - 8r4 */
+ if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* 3r2 - r1 - r3 */
+ if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/3 */
+ if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/3 */
+ if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* at this point shift W[n] by B*n */
+ if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ERR:
+ mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
+ &a0, &a1, &a2, &b0, &b1,
+ &b2, &tmp1, &tmp2, NULL);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_toom_mul.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toom_sqr.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toom_sqr.c
new file mode 100644
index 0000000000..48880d0350
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toom_sqr.c
@@ -0,0 +1,226 @@
+#include <tommath.h>
+#ifdef BN_MP_TOOM_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* squaring using Toom-Cook 3-way algorithm */
+int
+mp_toom_sqr(mp_int *a, mp_int *b)
+{
+ mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
+ int res, B;
+
+ /* init temps */
+ if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* B */
+ B = a->used / 3;
+
+ /* a = a2 * B**2 + a1 * B + a0 */
+ if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a1, B);
+ mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+ if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a2, B*2);
+
+ /* w0 = a0*a0 */
+ if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w4 = a2 * a2 */
+ if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w1 = (a2 + 2(a1 + 2a0))**2 */
+ if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w3 = (a0 + 2(a1 + 2a2))**2 */
+ if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+
+
+ /* w2 = (a2 + a1 + a0)**2 */
+ if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* now solve the matrix
+
+ 0 0 0 0 1
+ 1 2 4 8 16
+ 1 1 1 1 1
+ 16 8 4 2 1
+ 1 0 0 0 0
+
+ using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
+ */
+
+ /* r1 - r4 */
+ if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r0 */
+ if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/2 */
+ if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/2 */
+ if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r2 - r0 - r4 */
+ if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - 8r0 */
+ if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - 8r4 */
+ if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* 3r2 - r1 - r3 */
+ if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/3 */
+ if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/3 */
+ if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* at this point shift W[n] by B*n */
+ if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ERR:
+ mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
+ return res;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_toom_sqr.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toradix.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toradix.c
new file mode 100644
index 0000000000..0adc28d2fd
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toradix.c
@@ -0,0 +1,75 @@
+#include <tommath.h>
+#ifdef BN_MP_TORADIX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* stores a bignum as a ASCII string in a given radix (2..64) */
+int mp_toradix (mp_int * a, char *str, int radix)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+ char *_s = str;
+
+ /* check range of the radix */
+ if (radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ /* quick out if its zero */
+ if (mp_iszero(a) == 1) {
+ *str++ = '0';
+ *str = '\0';
+ return MP_OKAY;
+ }
+
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* if it is negative output a - */
+ if (t.sign == MP_NEG) {
+ ++_s;
+ *str++ = '-';
+ t.sign = MP_ZPOS;
+ }
+
+ digs = 0;
+ while (mp_iszero (&t) == 0) {
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ *str++ = mp_s_rmap[d];
+ ++digs;
+ }
+
+ /* reverse the digits of the string. In this case _s points
+ * to the first digit [exluding the sign] of the number]
+ */
+ bn_reverse ((unsigned char *)_s, digs);
+
+ /* append a NULL so the string is properly terminated */
+ *str = '\0';
+
+ mp_clear (&t);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_toradix.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toradix_n.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toradix_n.c
new file mode 100644
index 0000000000..796ed55c65
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_toradix_n.c
@@ -0,0 +1,88 @@
+#include <tommath.h>
+#ifdef BN_MP_TORADIX_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* stores a bignum as a ASCII string in a given radix (2..64)
+ *
+ * Stores upto maxlen-1 chars and always a NULL byte
+ */
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+ char *_s = str;
+
+ /* check range of the maxlen, radix */
+ if (maxlen < 2 || radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ /* quick out if its zero */
+ if (mp_iszero(a) == MP_YES) {
+ *str++ = '0';
+ *str = '\0';
+ return MP_OKAY;
+ }
+
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* if it is negative output a - */
+ if (t.sign == MP_NEG) {
+ /* we have to reverse our digits later... but not the - sign!! */
+ ++_s;
+
+ /* store the flag and mark the number as positive */
+ *str++ = '-';
+ t.sign = MP_ZPOS;
+
+ /* subtract a char */
+ --maxlen;
+ }
+
+ digs = 0;
+ while (mp_iszero (&t) == 0) {
+ if (--maxlen < 1) {
+ /* no more room */
+ break;
+ }
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ *str++ = mp_s_rmap[d];
+ ++digs;
+ }
+
+ /* reverse the digits of the string. In this case _s points
+ * to the first digit [exluding the sign] of the number
+ */
+ bn_reverse ((unsigned char *)_s, digs);
+
+ /* append a NULL so the string is properly terminated */
+ *str = '\0';
+
+ mp_clear (&t);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_toradix_n.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_unsigned_bin_size.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_unsigned_bin_size.c
new file mode 100644
index 0000000000..6dc3bd5fc1
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_unsigned_bin_size.c
@@ -0,0 +1,28 @@
+#include <tommath.h>
+#ifdef BN_MP_UNSIGNED_BIN_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* get the size for an unsigned equivalent */
+int mp_unsigned_bin_size (mp_int * a)
+{
+ int size = mp_count_bits (a);
+ return (size / 8 + ((size & 7) != 0 ? 1 : 0));
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_unsigned_bin_size.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_xor.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_xor.c
new file mode 100644
index 0000000000..59ff2e1832
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_xor.c
@@ -0,0 +1,51 @@
+#include <tommath.h>
+#ifdef BN_MP_XOR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* XOR two ints together */
+int
+mp_xor (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, ix, px;
+ mp_int t, *x;
+
+ if (a->used > b->used) {
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+ px = b->used;
+ x = b;
+ } else {
+ if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+ return res;
+ }
+ px = a->used;
+ x = a;
+ }
+
+ for (ix = 0; ix < px; ix++) {
+ t.dp[ix] ^= x->dp[ix];
+ }
+ mp_clamp (&t);
+ mp_exch (c, &t);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_xor.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_zero.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_zero.c
new file mode 100644
index 0000000000..b0977d4431
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_zero.c
@@ -0,0 +1,36 @@
+#include <tommath.h>
+#ifdef BN_MP_ZERO_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* set to zero */
+void mp_zero (mp_int * a)
+{
+ int n;
+ mp_digit *tmp;
+
+ a->sign = MP_ZPOS;
+ a->used = 0;
+
+ tmp = a->dp;
+ for (n = 0; n < a->alloc; n++) {
+ *tmp++ = 0;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_zero.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_mp_zero_multi.c b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_zero_multi.c
new file mode 100644
index 0000000000..339a75fbf8
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_mp_zero_multi.c
@@ -0,0 +1,35 @@
+#include <tommath.h>
+#ifdef BN_MP_ZERO_MULTI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+#include <stdarg.h>
+
+/* set to zero */
+void mp_zero_multi (mp_int * mp, ...)
+{
+ mp_int* next_mp = mp;
+ va_list args;
+ va_start(args, mp);
+ while (next_mp != NULL) {
+ mp_zero(next_mp);
+ next_mp = va_arg(args, mp_int*);
+ }
+ va_end(args);
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_mp_zero.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_prime_tab.c b/source4/heimdal/lib/hcrypto/libtommath/bn_prime_tab.c
new file mode 100644
index 0000000000..bd252477ec
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_prime_tab.c
@@ -0,0 +1,61 @@
+#include <tommath.h>
+#ifdef BN_PRIME_TAB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+const mp_digit ltm_prime_tab[] = {
+ 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
+ 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
+ 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
+ 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
+#ifndef MP_8BIT
+ 0x0083,
+ 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
+ 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
+ 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
+ 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
+
+ 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
+ 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
+ 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
+ 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
+ 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
+ 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
+ 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
+ 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
+
+ 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
+ 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
+ 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
+ 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
+ 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
+ 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
+ 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
+ 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
+
+ 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
+ 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
+ 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
+ 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
+ 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
+ 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
+ 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
+ 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
+#endif
+};
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_prime_tab.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_reverse.c b/source4/heimdal/lib/hcrypto/libtommath/bn_reverse.c
new file mode 100644
index 0000000000..ddfa827a09
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_reverse.c
@@ -0,0 +1,39 @@
+#include <tommath.h>
+#ifdef BN_REVERSE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* reverse an array, used for radix code */
+void
+bn_reverse (unsigned char *s, int len)
+{
+ int ix, iy;
+ unsigned char t;
+
+ ix = 0;
+ iy = len - 1;
+ while (ix < iy) {
+ t = s[ix];
+ s[ix] = s[iy];
+ s[iy] = t;
+ ++ix;
+ --iy;
+ }
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_reverse.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_add.c b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_add.c
new file mode 100644
index 0000000000..f034ae62aa
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_add.c
@@ -0,0 +1,109 @@
+#include <tommath.h>
+#ifdef BN_S_MP_ADD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* low level addition, based on HAC pp.594, Algorithm 14.7 */
+int
+s_mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int *x;
+ int olduse, res, min, max;
+
+ /* find sizes, we let |a| <= |b| which means we have to sort
+ * them. "x" will point to the input with the most digits
+ */
+ if (a->used > b->used) {
+ min = b->used;
+ max = a->used;
+ x = a;
+ } else {
+ min = a->used;
+ max = b->used;
+ x = b;
+ }
+
+ /* init result */
+ if (c->alloc < max + 1) {
+ if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* get old used digit count and set new one */
+ olduse = c->used;
+ c->used = max + 1;
+
+ {
+ register mp_digit u, *tmpa, *tmpb, *tmpc;
+ register int i;
+
+ /* alias for digit pointers */
+
+ /* first input */
+ tmpa = a->dp;
+
+ /* second input */
+ tmpb = b->dp;
+
+ /* destination */
+ tmpc = c->dp;
+
+ /* zero the carry */
+ u = 0;
+ for (i = 0; i < min; i++) {
+ /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
+ *tmpc = *tmpa++ + *tmpb++ + u;
+
+ /* U = carry bit of T[i] */
+ u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+ /* take away carry bit from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+
+ /* now copy higher words if any, that is in A+B
+ * if A or B has more digits add those in
+ */
+ if (min != max) {
+ for (; i < max; i++) {
+ /* T[i] = X[i] + U */
+ *tmpc = x->dp[i] + u;
+
+ /* U = carry bit of T[i] */
+ u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+ /* take away carry bit from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+ }
+
+ /* add carry */
+ *tmpc++ = u;
+
+ /* clear digits above oldused */
+ for (i = c->used; i < olduse; i++) {
+ *tmpc++ = 0;
+ }
+ }
+
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_add.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_exptmod.c b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_exptmod.c
new file mode 100644
index 0000000000..097d894702
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_exptmod.c
@@ -0,0 +1,252 @@
+#include <tommath.h>
+#ifdef BN_S_MP_EXPTMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+#ifdef MP_LOW_MEM
+ #define TAB_SIZE 32
+#else
+ #define TAB_SIZE 256
+#endif
+
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
+{
+ mp_int M[TAB_SIZE], res, mu;
+ mp_digit buf;
+ int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+ int (*redux)(mp_int*,mp_int*,mp_int*);
+
+ /* find window size */
+ x = mp_count_bits (X);
+ if (x <= 7) {
+ winsize = 2;
+ } else if (x <= 36) {
+ winsize = 3;
+ } else if (x <= 140) {
+ winsize = 4;
+ } else if (x <= 450) {
+ winsize = 5;
+ } else if (x <= 1303) {
+ winsize = 6;
+ } else if (x <= 3529) {
+ winsize = 7;
+ } else {
+ winsize = 8;
+ }
+
+#ifdef MP_LOW_MEM
+ if (winsize > 5) {
+ winsize = 5;
+ }
+#endif
+
+ /* init M array */
+ /* init first cell */
+ if ((err = mp_init(&M[1])) != MP_OKAY) {
+ return err;
+ }
+
+ /* now init the second half of the array */
+ for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+ if ((err = mp_init(&M[x])) != MP_OKAY) {
+ for (y = 1<<(winsize-1); y < x; y++) {
+ mp_clear (&M[y]);
+ }
+ mp_clear(&M[1]);
+ return err;
+ }
+ }
+
+ /* create mu, used for Barrett reduction */
+ if ((err = mp_init (&mu)) != MP_OKAY) {
+ goto LBL_M;
+ }
+
+ if (redmode == 0) {
+ if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ redux = mp_reduce;
+ } else {
+ if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ redux = mp_reduce_2k_l;
+ }
+
+ /* create M table
+ *
+ * The M table contains powers of the base,
+ * e.g. M[x] = G**x mod P
+ *
+ * The first half of the table is not
+ * computed though accept for M[0] and M[1]
+ */
+ if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
+ goto LBL_MU;
+ }
+
+ /* compute the value at M[1<<(winsize-1)] by squaring
+ * M[1] (winsize-1) times
+ */
+ if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
+ goto LBL_MU;
+ }
+
+ for (x = 0; x < (winsize - 1); x++) {
+ /* square it */
+ if ((err = mp_sqr (&M[1 << (winsize - 1)],
+ &M[1 << (winsize - 1)])) != MP_OKAY) {
+ goto LBL_MU;
+ }
+
+ /* reduce modulo P */
+ if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ }
+
+ /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
+ * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
+ */
+ for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+ if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ }
+
+ /* setup result */
+ if ((err = mp_init (&res)) != MP_OKAY) {
+ goto LBL_MU;
+ }
+ mp_set (&res, 1);
+
+ /* set initial mode and bit cnt */
+ mode = 0;
+ bitcnt = 1;
+ buf = 0;
+ digidx = X->used - 1;
+ bitcpy = 0;
+ bitbuf = 0;
+
+ for (;;) {
+ /* grab next digit as required */
+ if (--bitcnt == 0) {
+ /* if digidx == -1 we are out of digits */
+ if (digidx == -1) {
+ break;
+ }
+ /* read next digit and reset the bitcnt */
+ buf = X->dp[digidx--];
+ bitcnt = (int) DIGIT_BIT;
+ }
+
+ /* grab the next msb from the exponent */
+ y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
+ buf <<= (mp_digit)1;
+
+ /* if the bit is zero and mode == 0 then we ignore it
+ * These represent the leading zero bits before the first 1 bit
+ * in the exponent. Technically this opt is not required but it
+ * does lower the # of trivial squaring/reductions used
+ */
+ if (mode == 0 && y == 0) {
+ continue;
+ }
+
+ /* if the bit is zero and mode == 1 then we square */
+ if (mode == 1 && y == 0) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ continue;
+ }
+
+ /* else we add it to the window */
+ bitbuf |= (y << (winsize - ++bitcpy));
+ mode = 2;
+
+ if (bitcpy == winsize) {
+ /* ok window is filled so square as required and multiply */
+ /* square first */
+ for (x = 0; x < winsize; x++) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* then multiply */
+ if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ /* empty window and reset */
+ bitcpy = 0;
+ bitbuf = 0;
+ mode = 1;
+ }
+ }
+
+ /* if bits remain then square/multiply */
+ if (mode == 2 && bitcpy > 0) {
+ /* square then multiply if the bit is set */
+ for (x = 0; x < bitcpy; x++) {
+ if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ bitbuf <<= 1;
+ if ((bitbuf & (1 << winsize)) != 0) {
+ /* then multiply */
+ if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+ }
+ }
+
+ mp_exch (&res, Y);
+ err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_MU:mp_clear (&mu);
+LBL_M:
+ mp_clear(&M[1]);
+ for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+ mp_clear (&M[x]);
+ }
+ return err;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_exptmod.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_digs.c b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_digs.c
new file mode 100644
index 0000000000..f5bbf39ce2
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_digs.c
@@ -0,0 +1,90 @@
+#include <tommath.h>
+#ifdef BN_S_MP_MUL_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* multiplies |a| * |b| and only computes upto digs digits of result
+ * HAC pp. 595, Algorithm 14.12 Modified so you can control how
+ * many digits of output are created.
+ */
+int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ mp_int t;
+ int res, pa, pb, ix, iy;
+ mp_digit u;
+ mp_word r;
+ mp_digit tmpx, *tmpt, *tmpy;
+
+ /* can we use the fast multiplier? */
+ if (((digs) < MP_WARRAY) &&
+ MIN (a->used, b->used) <
+ (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ return fast_s_mp_mul_digs (a, b, c, digs);
+ }
+
+ if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
+ return res;
+ }
+ t.used = digs;
+
+ /* compute the digits of the product directly */
+ pa = a->used;
+ for (ix = 0; ix < pa; ix++) {
+ /* set the carry to zero */
+ u = 0;
+
+ /* limit ourselves to making digs digits of output */
+ pb = MIN (b->used, digs - ix);
+
+ /* setup some aliases */
+ /* copy of the digit from a used within the nested loop */
+ tmpx = a->dp[ix];
+
+ /* an alias for the destination shifted ix places */
+ tmpt = t.dp + ix;
+
+ /* an alias for the digits of b */
+ tmpy = b->dp;
+
+ /* compute the columns of the output and propagate the carry */
+ for (iy = 0; iy < pb; iy++) {
+ /* compute the column as a mp_word */
+ r = ((mp_word)*tmpt) +
+ ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+ ((mp_word) u);
+
+ /* the new column is the lower part of the result */
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* get the carry word from the result */
+ u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+ }
+ /* set carry if it is placed below digs */
+ if (ix + iy < digs) {
+ *tmpt = u;
+ }
+ }
+
+ mp_clamp (&t);
+ mp_exch (&t, c);
+
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_digs.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_high_digs.c b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_high_digs.c
new file mode 100644
index 0000000000..2b718f23cc
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_high_digs.c
@@ -0,0 +1,81 @@
+#include <tommath.h>
+#ifdef BN_S_MP_MUL_HIGH_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* multiplies |a| * |b| and does not compute the lower digs digits
+ * [meant to get the higher part of the product]
+ */
+int
+s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ mp_int t;
+ int res, pa, pb, ix, iy;
+ mp_digit u;
+ mp_word r;
+ mp_digit tmpx, *tmpt, *tmpy;
+
+ /* can we use the fast multiplier? */
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ if (((a->used + b->used + 1) < MP_WARRAY)
+ && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ return fast_s_mp_mul_high_digs (a, b, c, digs);
+ }
+#endif
+
+ if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ t.used = a->used + b->used + 1;
+
+ pa = a->used;
+ pb = b->used;
+ for (ix = 0; ix < pa; ix++) {
+ /* clear the carry */
+ u = 0;
+
+ /* left hand side of A[ix] * B[iy] */
+ tmpx = a->dp[ix];
+
+ /* alias to the address of where the digits will be stored */
+ tmpt = &(t.dp[digs]);
+
+ /* alias for where to read the right hand side from */
+ tmpy = b->dp + (digs - ix);
+
+ for (iy = digs - ix; iy < pb; iy++) {
+ /* calculate the double precision result */
+ r = ((mp_word)*tmpt) +
+ ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+ ((mp_word) u);
+
+ /* get the lower part */
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* carry the carry */
+ u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+ }
+ *tmpt = u;
+ }
+ mp_clamp (&t);
+ mp_exch (&t, c);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_mul_high_digs.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_sqr.c b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_sqr.c
new file mode 100644
index 0000000000..d2531c2925
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_sqr.c
@@ -0,0 +1,84 @@
+#include <tommath.h>
+#ifdef BN_S_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
+int s_mp_sqr (mp_int * a, mp_int * b)
+{
+ mp_int t;
+ int res, ix, iy, pa;
+ mp_word r;
+ mp_digit u, tmpx, *tmpt;
+
+ pa = a->used;
+ if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
+ return res;
+ }
+
+ /* default used is maximum possible size */
+ t.used = 2*pa + 1;
+
+ for (ix = 0; ix < pa; ix++) {
+ /* first calculate the digit at 2*ix */
+ /* calculate double precision result */
+ r = ((mp_word) t.dp[2*ix]) +
+ ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
+
+ /* store lower part in result */
+ t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* get the carry */
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+ /* left hand side of A[ix] * A[iy] */
+ tmpx = a->dp[ix];
+
+ /* alias for where to store the results */
+ tmpt = t.dp + (2*ix + 1);
+
+ for (iy = ix + 1; iy < pa; iy++) {
+ /* first calculate the product */
+ r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
+
+ /* now calculate the double precision result, note we use
+ * addition instead of *2 since it's easier to optimize
+ */
+ r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
+
+ /* store lower part */
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* get carry */
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+ }
+ /* propagate upwards */
+ while (u != ((mp_digit) 0)) {
+ r = ((mp_word) *tmpt) + ((mp_word) u);
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+ }
+ }
+
+ mp_clamp (&t);
+ mp_exch (&t, b);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_sqr.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_sub.c b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_sub.c
new file mode 100644
index 0000000000..6a60c3932c
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bn_s_mp_sub.c
@@ -0,0 +1,89 @@
+#include <tommath.h>
+#ifdef BN_S_MP_SUB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
+int
+s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+ int olduse, res, min, max;
+
+ /* find sizes */
+ min = b->used;
+ max = a->used;
+
+ /* init result */
+ if (c->alloc < max) {
+ if ((res = mp_grow (c, max)) != MP_OKAY) {
+ return res;
+ }
+ }
+ olduse = c->used;
+ c->used = max;
+
+ {
+ register mp_digit u, *tmpa, *tmpb, *tmpc;
+ register int i;
+
+ /* alias for digit pointers */
+ tmpa = a->dp;
+ tmpb = b->dp;
+ tmpc = c->dp;
+
+ /* set carry to zero */
+ u = 0;
+ for (i = 0; i < min; i++) {
+ /* T[i] = A[i] - B[i] - U */
+ *tmpc = *tmpa++ - *tmpb++ - u;
+
+ /* U = carry bit of T[i]
+ * Note this saves performing an AND operation since
+ * if a carry does occur it will propagate all the way to the
+ * MSB. As a result a single shift is enough to get the carry
+ */
+ u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+ /* Clear carry from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+
+ /* now copy higher words if any, e.g. if A has more digits than B */
+ for (; i < max; i++) {
+ /* T[i] = A[i] - U */
+ *tmpc = *tmpa++ - u;
+
+ /* U = carry bit of T[i] */
+ u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+ /* Clear carry from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+
+ /* clear digits above used (since we may not have grown result above) */
+ for (i = c->used; i < olduse; i++) {
+ *tmpc++ = 0;
+ }
+ }
+
+ mp_clamp (c);
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bn_s_mp_sub.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/bncore.c b/source4/heimdal/lib/hcrypto/libtommath/bncore.c
new file mode 100644
index 0000000000..8fb1824c6f
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/bncore.c
@@ -0,0 +1,36 @@
+#include <tommath.h>
+#ifdef BNCORE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+ */
+
+/* Known optimal configurations
+
+ CPU /Compiler /MUL CUTOFF/SQR CUTOFF
+-------------------------------------------------------------
+ Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-)
+ AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35
+
+*/
+
+int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */
+ KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */
+
+ TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */
+ TOOM_SQR_CUTOFF = 400;
+#endif
+
+/* $Source: /cvs/libtom/libtommath/bncore.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2006/12/28 01:25:13 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/booker.pl b/source4/heimdal/lib/hcrypto/libtommath/booker.pl
new file mode 100644
index 0000000000..49f1889d1b
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/booker.pl
@@ -0,0 +1,265 @@
+#!/bin/perl
+#
+#Used to prepare the book "tommath.src" for LaTeX by pre-processing it into a .tex file
+#
+#Essentially you write the "tommath.src" as normal LaTex except where you want code snippets you put
+#
+#EXAM,file
+#
+#This preprocessor will then open "file" and insert it as a verbatim copy.
+#
+#Tom St Denis
+
+#get graphics type
+if (shift =~ /PDF/) {
+ $graph = "";
+} else {
+ $graph = ".ps";
+}
+
+open(IN,"<tommath.src") or die "Can't open source file";
+open(OUT,">tommath.tex") or die "Can't open destination file";
+
+print "Scanning for sections\n";
+$chapter = $section = $subsection = 0;
+$x = 0;
+while (<IN>) {
+ print ".";
+ if (!(++$x % 80)) { print "\n"; }
+ #update the headings
+ if (~($_ =~ /\*/)) {
+ if ($_ =~ /\\chapter{.+}/) {
+ ++$chapter;
+ $section = $subsection = 0;
+ } elsif ($_ =~ /\\section{.+}/) {
+ ++$section;
+ $subsection = 0;
+ } elsif ($_ =~ /\\subsection{.+}/) {
+ ++$subsection;
+ }
+ }
+
+ if ($_ =~ m/MARK/) {
+ @m = split(",",$_);
+ chomp(@m[1]);
+ $index1{@m[1]} = $chapter;
+ $index2{@m[1]} = $section;
+ $index3{@m[1]} = $subsection;
+ }
+}
+close(IN);
+
+open(IN,"<tommath.src") or die "Can't open source file";
+$readline = $wroteline = 0;
+$srcline = 0;
+
+while (<IN>) {
+ ++$readline;
+ ++$srcline;
+
+ if ($_ =~ m/MARK/) {
+ } elsif ($_ =~ m/EXAM/ || $_ =~ m/LIST/) {
+ if ($_ =~ m/EXAM/) {
+ $skipheader = 1;
+ } else {
+ $skipheader = 0;
+ }
+
+ # EXAM,file
+ chomp($_);
+ @m = split(",",$_);
+ open(SRC,"<$m[1]") or die "Error:$srcline:Can't open source file $m[1]";
+
+ print "$srcline:Inserting $m[1]:";
+
+ $line = 0;
+ $tmp = $m[1];
+ $tmp =~ s/_/"\\_"/ge;
+ print OUT "\\vspace{+3mm}\\begin{small}\n\\hspace{-5.1mm}{\\bf File}: $tmp\n\\vspace{-3mm}\n\\begin{alltt}\n";
+ $wroteline += 5;
+
+ if ($skipheader == 1) {
+ # scan till next end of comment, e.g. skip license
+ while (<SRC>) {
+ $text[$line++] = $_;
+ last if ($_ =~ /math\.libtomcrypt\.com/);
+ }
+ <SRC>;
+ }
+
+ $inline = 0;
+ while (<SRC>) {
+ next if ($_ =~ /\$Source/);
+ next if ($_ =~ /\$Revision/);
+ next if ($_ =~ /\$Date/);
+ $text[$line++] = $_;
+ ++$inline;
+ chomp($_);
+ $_ =~ s/\t/" "/ge;
+ $_ =~ s/{/"^{"/ge;
+ $_ =~ s/}/"^}"/ge;
+ $_ =~ s/\\/'\symbol{92}'/ge;
+ $_ =~ s/\^/"\\"/ge;
+
+ printf OUT ("%03d ", $line);
+ for ($x = 0; $x < length($_); $x++) {
+ print OUT chr(vec($_, $x, 8));
+ if ($x == 75) {
+ print OUT "\n ";
+ ++$wroteline;
+ }
+ }
+ print OUT "\n";
+ ++$wroteline;
+ }
+ $totlines = $line;
+ print OUT "\\end{alltt}\n\\end{small}\n";
+ close(SRC);
+ print "$inline lines\n";
+ $wroteline += 2;
+ } elsif ($_ =~ m/@\d+,.+@/) {
+ # line contains [number,text]
+ # e.g. @14,for (ix = 0)@
+ $txt = $_;
+ while ($txt =~ m/@\d+,.+@/) {
+ @m = split("@",$txt); # splits into text, one, two
+ @parms = split(",",$m[1]); # splits one,two into two elements
+
+ # now search from $parms[0] down for $parms[1]
+ $found1 = 0;
+ $found2 = 0;
+ for ($i = $parms[0]; $i < $totlines && $found1 == 0; $i++) {
+ if ($text[$i] =~ m/\Q$parms[1]\E/) {
+ $foundline1 = $i + 1;
+ $found1 = 1;
+ }
+ }
+
+ # now search backwards
+ for ($i = $parms[0] - 1; $i >= 0 && $found2 == 0; $i--) {
+ if ($text[$i] =~ m/\Q$parms[1]\E/) {
+ $foundline2 = $i + 1;
+ $found2 = 1;
+ }
+ }
+
+ # now use the closest match or the first if tied
+ if ($found1 == 1 && $found2 == 0) {
+ $found = 1;
+ $foundline = $foundline1;
+ } elsif ($found1 == 0 && $found2 == 1) {
+ $found = 1;
+ $foundline = $foundline2;
+ } elsif ($found1 == 1 && $found2 == 1) {
+ $found = 1;
+ if (($foundline1 - $parms[0]) <= ($parms[0] - $foundline2)) {
+ $foundline = $foundline1;
+ } else {
+ $foundline = $foundline2;
+ }
+ } else {
+ $found = 0;
+ }
+
+ # if found replace
+ if ($found == 1) {
+ $delta = $parms[0] - $foundline;
+ print "Found replacement tag for \"$parms[1]\" on line $srcline which refers to line $foundline (delta $delta)\n";
+ $_ =~ s/@\Q$m[1]\E@/$foundline/;
+ } else {
+ print "ERROR: The tag \"$parms[1]\" on line $srcline was not found in the most recently parsed source!\n";
+ }
+
+ # remake the rest of the line
+ $cnt = @m;
+ $txt = "";
+ for ($i = 2; $i < $cnt; $i++) {
+ $txt = $txt . $m[$i] . "@";
+ }
+ }
+ print OUT $_;
+ ++$wroteline;
+ } elsif ($_ =~ /~.+~/) {
+ # line contains a ~text~ pair used to refer to indexing :-)
+ $txt = $_;
+ while ($txt =~ /~.+~/) {
+ @m = split("~", $txt);
+
+ # word is the second position
+ $word = @m[1];
+ $a = $index1{$word};
+ $b = $index2{$word};
+ $c = $index3{$word};
+
+ # if chapter (a) is zero it wasn't found
+ if ($a == 0) {
+ print "ERROR: the tag \"$word\" on line $srcline was not found previously marked.\n";
+ } else {
+ # format the tag as x, x.y or x.y.z depending on the values
+ $str = $a;
+ $str = $str . ".$b" if ($b != 0);
+ $str = $str . ".$c" if ($c != 0);
+
+ if ($b == 0 && $c == 0) {
+ # its a chapter
+ if ($a <= 10) {
+ if ($a == 1) {
+ $str = "chapter one";
+ } elsif ($a == 2) {
+ $str = "chapter two";
+ } elsif ($a == 3) {
+ $str = "chapter three";
+ } elsif ($a == 4) {
+ $str = "chapter four";
+ } elsif ($a == 5) {
+ $str = "chapter five";
+ } elsif ($a == 6) {
+ $str = "chapter six";
+ } elsif ($a == 7) {
+ $str = "chapter seven";
+ } elsif ($a == 8) {
+ $str = "chapter eight";
+ } elsif ($a == 9) {
+ $str = "chapter nine";
+ } elsif ($a == 10) {
+ $str = "chapter ten";
+ }
+ } else {
+ $str = "chapter " . $str;
+ }
+ } else {
+ $str = "section " . $str if ($b != 0 && $c == 0);
+ $str = "sub-section " . $str if ($b != 0 && $c != 0);
+ }
+
+ #substitute
+ $_ =~ s/~\Q$word\E~/$str/;
+
+ print "Found replacement tag for marker \"$word\" on line $srcline which refers to $str\n";
+ }
+
+ # remake rest of the line
+ $cnt = @m;
+ $txt = "";
+ for ($i = 2; $i < $cnt; $i++) {
+ $txt = $txt . $m[$i] . "~";
+ }
+ }
+ print OUT $_;
+ ++$wroteline;
+ } elsif ($_ =~ m/FIGU/) {
+ # FIGU,file,caption
+ chomp($_);
+ @m = split(",", $_);
+ print OUT "\\begin{center}\n\\begin{figure}[here]\n\\includegraphics{pics/$m[1]$graph}\n";
+ print OUT "\\caption{$m[2]}\n\\label{pic:$m[1]}\n\\end{figure}\n\\end{center}\n";
+ $wroteline += 4;
+ } else {
+ print OUT $_;
+ ++$wroteline;
+ }
+}
+print "Read $readline lines, wrote $wroteline lines\n";
+
+close (OUT);
+close (IN);
diff --git a/source4/heimdal/lib/hcrypto/libtommath/callgraph.txt b/source4/heimdal/lib/hcrypto/libtommath/callgraph.txt
new file mode 100644
index 0000000000..2efcf245ba
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/callgraph.txt
@@ -0,0 +1,11913 @@
+BN_PRIME_TAB_C
+
+
+BN_MP_SQRT_C
++--->BN_MP_N_ROOT_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_SET_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_EXPT_D_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_SQR_C
+| | | +--->BN_MP_TOOM_SQR_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_FAST_S_MP_SQR_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MUL_C
+| | | +--->BN_MP_TOOM_MUL_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| +--->BN_MP_MUL_C
+| | +--->BN_MP_TOOM_MUL_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_KARATSUBA_MUL_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CMP_C
+| | +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_SUB_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_ZERO_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
++--->BN_MP_DIV_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_SET_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_ABS_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_CMP_D_C
+
+
+BN_MP_EXCH_C
+
+
+BN_MP_IS_SQUARE_C
++--->BN_MP_MOD_D_C
+| +--->BN_MP_DIV_D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_SET_INT_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_SET_INT_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_MOD_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_GET_INT_C
++--->BN_MP_SQRT_C
+| +--->BN_MP_N_ROOT_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_SET_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_EXPT_D_C
+| | | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_SQR_C
+| | | | +--->BN_MP_TOOM_SQR_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_FAST_S_MP_SQR_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_MUL_C
+| | | +--->BN_MP_TOOM_MUL_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_ABS_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_CMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_SUB_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_2_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_SQR_C
+| +--->BN_MP_TOOM_SQR_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_KARATSUBA_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_SQR_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_NEG_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
+
+
+BN_MP_EXPTMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_INVMOD_C
+| +--->BN_FAST_MP_INVMOD_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_MOD_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_COUNT_BITS_C
+| | | | +--->BN_MP_ABS_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2D_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_COPY_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_SET_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_CMP_D_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INVMOD_SLOW_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_COUNT_BITS_C
+| | | | +--->BN_MP_ABS_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2D_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_COPY_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_SET_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_CMP_D_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_ABS_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_MULTI_C
++--->BN_MP_REDUCE_IS_2K_L_C
++--->BN_S_MP_EXPTMOD_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_REDUCE_SETUP_C
+| | +--->BN_MP_2EXPT_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_DIV_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_SET_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_REDUCE_C
+| | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_C
+| | | +--->BN_MP_TOOM_MUL_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_S_MP_MUL_HIGH_DIGS_C
+| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_MUL_DIGS_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_D_C
+| | +--->BN_MP_SET_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_REDUCE_2K_SETUP_L_C
+| | +--->BN_MP_2EXPT_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_REDUCE_2K_L_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_MUL_C
+| | | +--->BN_MP_TOOM_MUL_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MOD_C
+| | +--->BN_MP_DIV_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_SET_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_SQR_C
+| | +--->BN_MP_TOOM_SQR_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_KARATSUBA_SQR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | +--->BN_FAST_S_MP_SQR_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SQR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_MUL_C
+| | +--->BN_MP_TOOM_MUL_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_KARATSUBA_MUL_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_SET_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_DR_IS_MODULUS_C
++--->BN_MP_REDUCE_IS_2K_C
+| +--->BN_MP_REDUCE_2K_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_COUNT_BITS_C
++--->BN_MP_EXPTMOD_FAST_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_MONTGOMERY_SETUP_C
+| +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| +--->BN_MP_MONTGOMERY_REDUCE_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| +--->BN_MP_DR_SETUP_C
+| +--->BN_MP_DR_REDUCE_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| +--->BN_MP_REDUCE_2K_SETUP_C
+| | +--->BN_MP_2EXPT_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_REDUCE_2K_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+| | +--->BN_MP_2EXPT_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_SET_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MULMOD_C
+| | +--->BN_MP_MUL_C
+| | | +--->BN_MP_TOOM_MUL_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_MOD_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2D_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_COPY_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_SET_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_MOD_C
+| | +--->BN_MP_DIV_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_SQR_C
+| | +--->BN_MP_TOOM_SQR_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_KARATSUBA_SQR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | +--->BN_FAST_S_MP_SQR_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SQR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_MUL_C
+| | +--->BN_MP_TOOM_MUL_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_KARATSUBA_MUL_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_EXCH_C
+
+
+BN_MP_OR_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_ZERO_C
+
+
+BN_MP_GROW_C
+
+
+BN_MP_COUNT_BITS_C
+
+
+BN_MP_PRIME_FERMAT_C
++--->BN_MP_CMP_D_C
++--->BN_MP_INIT_C
++--->BN_MP_EXPTMOD_C
+| +--->BN_MP_INVMOD_C
+| | +--->BN_FAST_MP_INVMOD_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_SET_C
+| | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | +--->BN_MP_ABS_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2D_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_INIT_COPY_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INVMOD_SLOW_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_SET_C
+| | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | +--->BN_MP_ABS_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2D_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_INIT_COPY_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_ABS_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_REDUCE_IS_2K_L_C
+| +--->BN_S_MP_EXPTMOD_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_REDUCE_SETUP_C
+| | | +--->BN_MP_2EXPT_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2D_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_COPY_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_REDUCE_C
+| | | +--->BN_MP_INIT_COPY_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_S_MP_MUL_HIGH_DIGS_C
+| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_REDUCE_2K_SETUP_L_C
+| | | +--->BN_MP_2EXPT_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_REDUCE_2K_L_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MOD_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2D_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_COPY_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_SQR_C
+| | | +--->BN_MP_TOOM_SQR_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | +--->BN_FAST_S_MP_SQR_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_MUL_C
+| | | +--->BN_MP_TOOM_MUL_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_SET_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_DR_IS_MODULUS_C
+| +--->BN_MP_REDUCE_IS_2K_C
+| | +--->BN_MP_REDUCE_2K_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_EXPTMOD_FAST_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_MONTGOMERY_SETUP_C
+| | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | +--->BN_MP_MONTGOMERY_REDUCE_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | +--->BN_MP_DR_SETUP_C
+| | +--->BN_MP_DR_REDUCE_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | +--->BN_MP_REDUCE_2K_SETUP_C
+| | | +--->BN_MP_2EXPT_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_REDUCE_2K_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+| | | +--->BN_MP_2EXPT_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MULMOD_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_SET_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2D_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_INIT_COPY_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_SET_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2D_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_COPY_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_SQR_C
+| | | +--->BN_MP_TOOM_SQR_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | +--->BN_FAST_S_MP_SQR_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_MUL_C
+| | | +--->BN_MP_TOOM_MUL_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
++--->BN_MP_CMP_C
+| +--->BN_MP_CMP_MAG_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_SUBMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+
+
+BN_MP_MOD_2D_C
++--->BN_MP_ZERO_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_TORADIX_N_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_DIV_D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_DIV_3_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_CMP_C
++--->BN_MP_CMP_MAG_C
+
+
+BNCORE_C
+
+
+BN_MP_TORADIX_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_DIV_D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_DIV_3_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_ADD_D_C
++--->BN_MP_GROW_C
++--->BN_MP_SUB_D_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_DIV_3_C
++--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_FAST_S_MP_MUL_DIGS_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_SQRMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_SQR_C
+| +--->BN_MP_TOOM_SQR_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_KARATSUBA_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_SQR_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+
+
+BN_MP_INVMOD_C
++--->BN_FAST_MP_INVMOD_C
+| +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_MOD_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_DIV_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_SET_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_ABS_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_SET_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_DIV_2_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_C
+| | +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_CMP_D_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_INVMOD_SLOW_C
+| +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_MOD_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_DIV_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_SET_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_ABS_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_SET_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_DIV_2_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_C
+| | +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_CMP_D_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
+
+
+BN_MP_AND_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_MUL_D_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_FAST_MP_INVMOD_C
++--->BN_MP_INIT_MULTI_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_MOD_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_DIV_2_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_C
+| +--->BN_MP_CMP_MAG_C
++--->BN_MP_CMP_D_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_FWRITE_C
++--->BN_MP_RADIX_SIZE_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_TORADIX_C
+| +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_S_MP_SQR_C
++--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_N_ROOT_C
++--->BN_MP_INIT_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_EXPT_D_C
+| +--->BN_MP_INIT_COPY_C
+| +--->BN_MP_SQR_C
+| | +--->BN_MP_TOOM_SQR_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_KARATSUBA_SQR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_FAST_S_MP_SQR_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SQR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_MUL_C
+| | +--->BN_MP_TOOM_MUL_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_KARATSUBA_MUL_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_ABS_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_COPY_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_CMP_C
+| +--->BN_MP_CMP_MAG_C
++--->BN_MP_SUB_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_ADD_D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+
+
+BN_MP_RADIX_SIZE_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_DIV_D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_DIV_3_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_READ_SIGNED_BIN_C
++--->BN_MP_READ_UNSIGNED_BIN_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
+
+
+BN_MP_PRIME_RANDOM_EX_C
++--->BN_MP_READ_UNSIGNED_BIN_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_PRIME_IS_PRIME_C
+| +--->BN_MP_CMP_D_C
+| +--->BN_MP_PRIME_IS_DIVISIBLE_C
+| | +--->BN_MP_MOD_D_C
+| | | +--->BN_MP_DIV_D_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_DIV_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_INIT_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_INIT_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_SET_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_PRIME_MILLER_RABIN_C
+| | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_SUB_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CNT_LSB_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXPTMOD_C
+| | | +--->BN_MP_INVMOD_C
+| | | | +--->BN_FAST_MP_INVMOD_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_MOD_C
+| | | | | | +--->BN_MP_DIV_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | | | +--->BN_MP_ABS_C
+| | | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_C
+| | | | | | | +--->BN_MP_SUB_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_ADD_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | | | +--->BN_MP_CLEAR_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_INVMOD_SLOW_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_MOD_C
+| | | | | | +--->BN_MP_DIV_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | | | +--->BN_MP_ABS_C
+| | | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_C
+| | | | | | | +--->BN_MP_SUB_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_ADD_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | | | +--->BN_MP_CLEAR_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_ABS_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_REDUCE_IS_2K_L_C
+| | | +--->BN_S_MP_EXPTMOD_C
+| | | | +--->BN_MP_COUNT_BITS_C
+| | | | +--->BN_MP_REDUCE_SETUP_C
+| | | | | +--->BN_MP_2EXPT_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_DIV_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_REDUCE_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_C
+| | | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_ADD_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_SUB_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_MP_EXCH_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_SUB_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_ADD_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_S_MP_MUL_HIGH_DIGS_C
+| | | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_REDUCE_2K_SETUP_L_C
+| | | | | +--->BN_MP_2EXPT_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_REDUCE_2K_L_C
+| | | | | +--->BN_MP_MUL_C
+| | | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_ADD_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_SUB_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_MP_EXCH_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_SUB_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_ADD_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MOD_C
+| | | | | +--->BN_MP_DIV_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_SQR_C
+| | | | | +--->BN_MP_TOOM_SQR_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_FAST_S_MP_SQR_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SQR_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_MUL_C
+| | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_DR_IS_MODULUS_C
+| | | +--->BN_MP_REDUCE_IS_2K_C
+| | | | +--->BN_MP_REDUCE_2K_C
+| | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_EXPTMOD_FAST_C
+| | | | +--->BN_MP_COUNT_BITS_C
+| | | | +--->BN_MP_MONTGOMERY_SETUP_C
+| | | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_MONTGOMERY_REDUCE_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_DR_SETUP_C
+| | | | +--->BN_MP_DR_REDUCE_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_REDUCE_2K_SETUP_C
+| | | | | +--->BN_MP_2EXPT_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_REDUCE_2K_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+| | | | | +--->BN_MP_2EXPT_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MULMOD_C
+| | | | | +--->BN_MP_MUL_C
+| | | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_ADD_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_SUB_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_MP_EXCH_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_SUB_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_ADD_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_MOD_C
+| | | | | | +--->BN_MP_DIV_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_C
+| | | | | | | +--->BN_MP_SUB_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_ADD_C
+| | | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_MOD_C
+| | | | | +--->BN_MP_DIV_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_SQR_C
+| | | | | +--->BN_MP_TOOM_SQR_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_FAST_S_MP_SQR_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SQR_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_MUL_C
+| | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_SQRMOD_C
+| | | +--->BN_MP_SQR_C
+| | | | +--->BN_MP_TOOM_SQR_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_FAST_S_MP_SQR_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | +--->BN_MP_ABS_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_ADD_D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_2_C
+| +--->BN_MP_GROW_C
++--->BN_MP_ADD_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
+
+
+BN_MP_KARATSUBA_SQR_C
++--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_SQR_C
+| +--->BN_MP_TOOM_SQR_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_SQR_C
+| | +--->BN_MP_GROW_C
+| +--->BN_S_MP_SQR_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
++--->BN_S_MP_ADD_C
+| +--->BN_MP_GROW_C
++--->BN_MP_LSHD_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
+| | +--->BN_MP_ZERO_C
++--->BN_MP_ADD_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_INIT_COPY_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
+
+
+BN_MP_CLAMP_C
+
+
+BN_MP_TOOM_SQR_C
++--->BN_MP_INIT_MULTI_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_MOD_2D_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_SQR_C
+| +--->BN_MP_KARATSUBA_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_SQR_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_MUL_2_C
+| +--->BN_MP_GROW_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_2D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_LSHD_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_3_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_LSHD_C
+| +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_MOD_C
++--->BN_MP_INIT_C
++--->BN_MP_DIV_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_SET_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_ABS_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_COPY_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
+
+
+BN_MP_INIT_C
+
+
+BN_MP_TOOM_MUL_C
++--->BN_MP_INIT_MULTI_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_MOD_2D_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_MUL_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_MUL_2_C
+| +--->BN_MP_GROW_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_2D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_LSHD_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_3_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_LSHD_C
+| +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_PRIME_IS_PRIME_C
++--->BN_MP_CMP_D_C
++--->BN_MP_PRIME_IS_DIVISIBLE_C
+| +--->BN_MP_MOD_D_C
+| | +--->BN_MP_DIV_D_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_INIT_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_PRIME_MILLER_RABIN_C
+| +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_SUB_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CNT_LSB_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_EXPTMOD_C
+| | +--->BN_MP_INVMOD_C
+| | | +--->BN_FAST_MP_INVMOD_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_MOD_C
+| | | | | +--->BN_MP_DIV_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | | +--->BN_MP_ABS_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_INVMOD_SLOW_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_MOD_C
+| | | | | +--->BN_MP_DIV_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | | +--->BN_MP_ABS_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_ABS_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_REDUCE_IS_2K_L_C
+| | +--->BN_S_MP_EXPTMOD_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_REDUCE_SETUP_C
+| | | | +--->BN_MP_2EXPT_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_REDUCE_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_C
+| | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_S_MP_MUL_HIGH_DIGS_C
+| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_REDUCE_2K_SETUP_L_C
+| | | | +--->BN_MP_2EXPT_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_REDUCE_2K_L_C
+| | | | +--->BN_MP_MUL_C
+| | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_SQR_C
+| | | | +--->BN_MP_TOOM_SQR_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_FAST_S_MP_SQR_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_DR_IS_MODULUS_C
+| | +--->BN_MP_REDUCE_IS_2K_C
+| | | +--->BN_MP_REDUCE_2K_C
+| | | | +--->BN_MP_COUNT_BITS_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_EXPTMOD_FAST_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_MONTGOMERY_SETUP_C
+| | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_MONTGOMERY_REDUCE_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_DR_SETUP_C
+| | | +--->BN_MP_DR_REDUCE_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_REDUCE_2K_SETUP_C
+| | | | +--->BN_MP_2EXPT_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_REDUCE_2K_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+| | | | +--->BN_MP_2EXPT_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MULMOD_C
+| | | | +--->BN_MP_MUL_C
+| | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_MOD_C
+| | | | | +--->BN_MP_DIV_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_SQR_C
+| | | | +--->BN_MP_TOOM_SQR_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_FAST_S_MP_SQR_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_CMP_C
+| | +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_SQRMOD_C
+| | +--->BN_MP_SQR_C
+| | | +--->BN_MP_TOOM_SQR_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_FAST_S_MP_SQR_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_COUNT_BITS_C
+| | | | +--->BN_MP_ABS_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_COPY_C
++--->BN_MP_GROW_C
+
+
+BN_S_MP_SUB_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_READ_UNSIGNED_BIN_C
++--->BN_MP_GROW_C
++--->BN_MP_ZERO_C
++--->BN_MP_MUL_2D_C
+| +--->BN_MP_COPY_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_EXPTMOD_FAST_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_INIT_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MONTGOMERY_SETUP_C
++--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
++--->BN_MP_MONTGOMERY_REDUCE_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_RSHD_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
++--->BN_MP_DR_SETUP_C
++--->BN_MP_DR_REDUCE_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
++--->BN_MP_REDUCE_2K_SETUP_C
+| +--->BN_MP_2EXPT_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_GROW_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_REDUCE_2K_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+| +--->BN_MP_2EXPT_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_SET_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_MUL_2_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_MULMOD_C
+| +--->BN_MP_MUL_C
+| | +--->BN_MP_TOOM_MUL_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_KARATSUBA_MUL_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_MOD_C
+| | +--->BN_MP_DIV_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_SET_C
+| | | +--->BN_MP_ABS_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2D_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_MOD_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_SQR_C
+| +--->BN_MP_TOOM_SQR_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_KARATSUBA_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| +--->BN_FAST_S_MP_SQR_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
++--->BN_MP_EXCH_C
+
+
+BN_MP_TO_UNSIGNED_BIN_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_DIV_2D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_SET_INT_C
++--->BN_MP_ZERO_C
++--->BN_MP_MUL_2D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_MOD_D_C
++--->BN_MP_DIV_D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_DIV_3_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_SQR_C
++--->BN_MP_TOOM_SQR_C
+| +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_MUL_2_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_2_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_3_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_KARATSUBA_SQR_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| +--->BN_MP_ADD_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_CLEAR_C
++--->BN_FAST_S_MP_SQR_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_S_MP_SQR_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_MULMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+
+
+BN_MP_DIV_2D_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_ZERO_C
++--->BN_MP_INIT_C
++--->BN_MP_MOD_2D_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
++--->BN_MP_RSHD_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
+
+
+BN_S_MP_ADD_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_FAST_S_MP_SQR_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_S_MP_MUL_DIGS_C
++--->BN_FAST_S_MP_MUL_DIGS_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_XOR_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_RADIX_SMAP_C
+
+
+BN_MP_DR_IS_MODULUS_C
+
+
+BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_2EXPT_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_GROW_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_MUL_2_C
+| +--->BN_MP_GROW_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
+
+
+BN_MP_SUB_C
++--->BN_S_MP_ADD_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
+
+
+BN_MP_INIT_MULTI_C
++--->BN_MP_INIT_C
++--->BN_MP_CLEAR_C
+
+
+BN_S_MP_MUL_HIGH_DIGS_C
++--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_PRIME_NEXT_PRIME_C
++--->BN_MP_CMP_D_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_SUB_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_ADD_D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_MOD_D_C
+| +--->BN_MP_DIV_D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_C
++--->BN_MP_ADD_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_PRIME_MILLER_RABIN_C
+| +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_CNT_LSB_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_EXPTMOD_C
+| | +--->BN_MP_INVMOD_C
+| | | +--->BN_FAST_MP_INVMOD_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_MOD_C
+| | | | | +--->BN_MP_DIV_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | | +--->BN_MP_ABS_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_INVMOD_SLOW_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_MOD_C
+| | | | | +--->BN_MP_DIV_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | | +--->BN_MP_ABS_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | | +--->BN_MP_CLEAR_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_ABS_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_REDUCE_IS_2K_L_C
+| | +--->BN_S_MP_EXPTMOD_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_REDUCE_SETUP_C
+| | | | +--->BN_MP_2EXPT_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_REDUCE_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_C
+| | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_S_MP_MUL_HIGH_DIGS_C
+| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_REDUCE_2K_SETUP_L_C
+| | | | +--->BN_MP_2EXPT_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_REDUCE_2K_L_C
+| | | | +--->BN_MP_MUL_C
+| | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_SQR_C
+| | | | +--->BN_MP_TOOM_SQR_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_FAST_S_MP_SQR_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_DR_IS_MODULUS_C
+| | +--->BN_MP_REDUCE_IS_2K_C
+| | | +--->BN_MP_REDUCE_2K_C
+| | | | +--->BN_MP_COUNT_BITS_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_EXPTMOD_FAST_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_MONTGOMERY_SETUP_C
+| | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_MONTGOMERY_REDUCE_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_DR_SETUP_C
+| | | +--->BN_MP_DR_REDUCE_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_REDUCE_2K_SETUP_C
+| | | | +--->BN_MP_2EXPT_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_REDUCE_2K_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+| | | | +--->BN_MP_2EXPT_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MULMOD_C
+| | | | +--->BN_MP_MUL_C
+| | | | | +--->BN_MP_TOOM_MUL_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MOD_2D_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | | +--->BN_MP_COPY_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_MUL_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_2_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_DIV_3_C
+| | | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_MOD_C
+| | | | | +--->BN_MP_DIV_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | | +--->BN_MP_MUL_2D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_LSHD_C
+| | | | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_C
+| | | | | | +--->BN_MP_SUB_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_ADD_C
+| | | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | | +--->BN_MP_GROW_C
+| | | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_MUL_D_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_SQR_C
+| | | | +--->BN_MP_TOOM_SQR_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_FAST_S_MP_SQR_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SQR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_CMP_C
+| | +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_SQRMOD_C
+| | +--->BN_MP_SQR_C
+| | | +--->BN_MP_TOOM_SQR_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_FAST_S_MP_SQR_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_COUNT_BITS_C
+| | | | +--->BN_MP_ABS_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_SIGNED_BIN_SIZE_C
++--->BN_MP_UNSIGNED_BIN_SIZE_C
+| +--->BN_MP_COUNT_BITS_C
+
+
+BN_MP_INVMOD_SLOW_C
++--->BN_MP_INIT_MULTI_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_DIV_2_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_C
+| +--->BN_MP_CMP_MAG_C
++--->BN_MP_CMP_D_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_LCM_C
++--->BN_MP_INIT_MULTI_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_GCD_C
+| +--->BN_MP_ABS_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_CNT_LSB_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_EXCH_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_DIV_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_SET_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_ABS_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_INIT_COPY_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_2K_L_C
++--->BN_MP_INIT_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_DIV_2D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_S_MP_ADD_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_REVERSE_C
+
+
+BN_MP_PRIME_IS_DIVISIBLE_C
++--->BN_MP_MOD_D_C
+| +--->BN_MP_DIV_D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+
+
+BN_MP_SET_C
++--->BN_MP_ZERO_C
+
+
+BN_MP_GCD_C
++--->BN_MP_ABS_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_ZERO_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_CNT_LSB_C
++--->BN_MP_DIV_2D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_EXCH_C
++--->BN_S_MP_SUB_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_2D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_2K_SETUP_L_C
++--->BN_MP_INIT_C
++--->BN_MP_2EXPT_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_GROW_C
++--->BN_MP_COUNT_BITS_C
++--->BN_S_MP_SUB_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_READ_RADIX_C
++--->BN_MP_ZERO_C
++--->BN_MP_MUL_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_ADD_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_SUB_D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
+
+
+BN_FAST_S_MP_MUL_HIGH_DIGS_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_FAST_MP_MONTGOMERY_REDUCE_C
++--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+
+
+BN_MP_DIV_D_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_DIV_2D_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_DIV_3_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_2K_SETUP_C
++--->BN_MP_INIT_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_2EXPT_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_C
++--->BN_S_MP_SUB_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
+
+
+BN_MP_INIT_SET_C
++--->BN_MP_INIT_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
+
+
+BN_MP_REDUCE_2K_C
++--->BN_MP_INIT_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_DIV_2D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_MUL_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_S_MP_ADD_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_ERROR_C
+
+
+BN_MP_EXPT_D_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_SQR_C
+| +--->BN_MP_TOOM_SQR_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_KARATSUBA_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_SQR_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+
+
+BN_S_MP_EXPTMOD_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_INIT_C
++--->BN_MP_CLEAR_C
++--->BN_MP_REDUCE_SETUP_C
+| +--->BN_MP_2EXPT_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_REDUCE_C
+| +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_MUL_C
+| | +--->BN_MP_TOOM_MUL_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_KARATSUBA_MUL_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_S_MP_MUL_HIGH_DIGS_C
+| | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_D_C
+| +--->BN_MP_SET_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_C
+| | +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_REDUCE_2K_SETUP_L_C
+| +--->BN_MP_2EXPT_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_GROW_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_REDUCE_2K_L_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_MUL_C
+| | +--->BN_MP_TOOM_MUL_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_KARATSUBA_MUL_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_MUL_DIGS_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_MOD_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_SQR_C
+| +--->BN_MP_TOOM_SQR_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_KARATSUBA_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| +--->BN_FAST_S_MP_SQR_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_SQR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_EXCH_C
+
+
+BN_MP_ABS_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
+
+
+BN_MP_INIT_SET_INT_C
++--->BN_MP_INIT_C
++--->BN_MP_SET_INT_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
+
+
+BN_MP_SUB_D_C
++--->BN_MP_GROW_C
++--->BN_MP_ADD_D_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_TO_SIGNED_BIN_C
++--->BN_MP_TO_UNSIGNED_BIN_C
+| +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_DIV_2_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_REDUCE_IS_2K_C
++--->BN_MP_REDUCE_2K_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_COUNT_BITS_C
+
+
+BN_MP_INIT_SIZE_C
++--->BN_MP_INIT_C
+
+
+BN_MP_DIV_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_ZERO_C
++--->BN_MP_INIT_MULTI_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_SET_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_ABS_C
++--->BN_MP_MUL_2D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2D_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_C
++--->BN_MP_INIT_C
++--->BN_MP_INIT_COPY_C
++--->BN_MP_LSHD_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
++--->BN_MP_RSHD_C
++--->BN_MP_MUL_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_CLEAR_C
+
+
+BN_MP_MONTGOMERY_REDUCE_C
++--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_RSHD_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+
+
+BN_MP_MUL_2_C
++--->BN_MP_GROW_C
+
+
+BN_MP_UNSIGNED_BIN_SIZE_C
++--->BN_MP_COUNT_BITS_C
+
+
+BN_MP_ADDMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+
+
+BN_MP_ADD_C
++--->BN_S_MP_ADD_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
+
+
+BN_MP_TO_SIGNED_BIN_N_C
++--->BN_MP_SIGNED_BIN_SIZE_C
+| +--->BN_MP_UNSIGNED_BIN_SIZE_C
+| | +--->BN_MP_COUNT_BITS_C
++--->BN_MP_TO_SIGNED_BIN_C
+| +--->BN_MP_TO_UNSIGNED_BIN_C
+| | +--->BN_MP_INIT_COPY_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_IS_2K_L_C
+
+
+BN_MP_RAND_C
++--->BN_MP_ZERO_C
++--->BN_MP_ADD_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_SUB_D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_LSHD_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
+
+
+BN_MP_CNT_LSB_C
+
+
+BN_MP_2EXPT_C
++--->BN_MP_ZERO_C
++--->BN_MP_GROW_C
+
+
+BN_MP_RSHD_C
++--->BN_MP_ZERO_C
+
+
+BN_MP_SHRINK_C
+
+
+BN_MP_TO_UNSIGNED_BIN_N_C
++--->BN_MP_UNSIGNED_BIN_SIZE_C
+| +--->BN_MP_COUNT_BITS_C
++--->BN_MP_TO_UNSIGNED_BIN_C
+| +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_C
++--->BN_MP_REDUCE_SETUP_C
+| +--->BN_MP_2EXPT_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2D_C
+| | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_INIT_COPY_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_S_MP_MUL_HIGH_DIGS_C
+| +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_MOD_2D_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_S_MP_MUL_DIGS_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_D_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_LSHD_C
+| +--->BN_MP_GROW_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_C
+| +--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_MUL_2D_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_GROW_C
++--->BN_MP_LSHD_C
+| +--->BN_MP_RSHD_C
+| | +--->BN_MP_ZERO_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_GET_INT_C
+
+
+BN_MP_JACOBI_C
++--->BN_MP_CMP_D_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_CNT_LSB_C
++--->BN_MP_DIV_2D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_MOD_C
+| +--->BN_MP_DIV_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_SET_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_ABS_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_CLEAR_MULTI_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_MUL_C
++--->BN_MP_TOOM_MUL_C
+| +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_ZERO_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
+| | +--->BN_MP_ZERO_C
+| +--->BN_MP_MUL_2_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_2_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_3_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_KARATSUBA_MUL_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CMP_MAG_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| +--->BN_MP_CLEAR_C
++--->BN_FAST_S_MP_MUL_DIGS_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_S_MP_MUL_DIGS_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_EXTEUCLID_C
++--->BN_MP_INIT_MULTI_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_SET_C
+| +--->BN_MP_ZERO_C
++--->BN_MP_COPY_C
+| +--->BN_MP_GROW_C
++--->BN_MP_DIV_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_ABS_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_INIT_COPY_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_KARATSUBA_MUL_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
++--->BN_MP_NEG_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_DR_REDUCE_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+
+
+BN_MP_FREAD_C
++--->BN_MP_ZERO_C
++--->BN_MP_MUL_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_ADD_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_SUB_D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_D_C
+
+
+BN_MP_REDUCE_SETUP_C
++--->BN_MP_2EXPT_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_GROW_C
++--->BN_MP_DIV_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_INIT_MULTI_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_SET_C
+| +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_ABS_C
+| +--->BN_MP_MUL_2D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CMP_C
+| +--->BN_MP_SUB_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_ADD_C
+| | +--->BN_S_MP_ADD_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SUB_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| +--->BN_MP_DIV_2D_C
+| | +--->BN_MP_INIT_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_RSHD_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_EXCH_C
+| +--->BN_MP_CLEAR_MULTI_C
+| | +--->BN_MP_CLEAR_C
+| +--->BN_MP_INIT_SIZE_C
+| | +--->BN_MP_INIT_C
+| +--->BN_MP_INIT_C
+| +--->BN_MP_INIT_COPY_C
+| +--->BN_MP_LSHD_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_MUL_D_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
+
+
+BN_MP_MONTGOMERY_SETUP_C
+
+
+BN_MP_KARATSUBA_MUL_C
++--->BN_MP_MUL_C
+| +--->BN_MP_TOOM_MUL_C
+| | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_MOD_2D_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MUL_2_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_SUB_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_2_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_2D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MUL_D_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_DIV_3_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_INIT_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_LSHD_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_FAST_S_MP_MUL_DIGS_C
+| | +--->BN_MP_GROW_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_S_MP_MUL_DIGS_C
+| | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_INIT_C
+| | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
+| | +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_SIZE_C
+| +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_ADD_C
+| +--->BN_S_MP_ADD_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_CMP_MAG_C
+| +--->BN_S_MP_SUB_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_LSHD_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_RSHD_C
+| | +--->BN_MP_ZERO_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_LSHD_C
++--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+| +--->BN_MP_ZERO_C
+
+
+BN_MP_PRIME_MILLER_RABIN_C
++--->BN_MP_CMP_D_C
++--->BN_MP_INIT_COPY_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
++--->BN_MP_SUB_D_C
+| +--->BN_MP_GROW_C
+| +--->BN_MP_ADD_D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLAMP_C
++--->BN_MP_CNT_LSB_C
++--->BN_MP_DIV_2D_C
+| +--->BN_MP_COPY_C
+| | +--->BN_MP_GROW_C
+| +--->BN_MP_ZERO_C
+| +--->BN_MP_MOD_2D_C
+| | +--->BN_MP_CLAMP_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_RSHD_C
+| +--->BN_MP_CLAMP_C
+| +--->BN_MP_EXCH_C
++--->BN_MP_EXPTMOD_C
+| +--->BN_MP_INVMOD_C
+| | +--->BN_FAST_MP_INVMOD_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_SET_C
+| | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | +--->BN_MP_ABS_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_INVMOD_SLOW_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_SET_C
+| | | | | +--->BN_MP_COUNT_BITS_C
+| | | | | +--->BN_MP_ABS_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_CLEAR_MULTI_C
+| | | | | | +--->BN_MP_CLEAR_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_CLEAR_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_ABS_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| +--->BN_MP_CLEAR_MULTI_C
+| +--->BN_MP_REDUCE_IS_2K_L_C
+| +--->BN_S_MP_EXPTMOD_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_REDUCE_SETUP_C
+| | | +--->BN_MP_2EXPT_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_REDUCE_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_S_MP_MUL_HIGH_DIGS_C
+| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_REDUCE_2K_SETUP_L_C
+| | | +--->BN_MP_2EXPT_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_REDUCE_2K_L_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MOD_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_SQR_C
+| | | +--->BN_MP_TOOM_SQR_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | +--->BN_FAST_S_MP_SQR_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_MUL_C
+| | | +--->BN_MP_TOOM_MUL_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_SET_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_EXCH_C
+| +--->BN_MP_DR_IS_MODULUS_C
+| +--->BN_MP_REDUCE_IS_2K_C
+| | +--->BN_MP_REDUCE_2K_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_COUNT_BITS_C
+| +--->BN_MP_EXPTMOD_FAST_C
+| | +--->BN_MP_COUNT_BITS_C
+| | +--->BN_MP_MONTGOMERY_SETUP_C
+| | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | +--->BN_MP_MONTGOMERY_REDUCE_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | +--->BN_MP_DR_SETUP_C
+| | +--->BN_MP_DR_REDUCE_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | +--->BN_MP_REDUCE_2K_SETUP_C
+| | | +--->BN_MP_2EXPT_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_REDUCE_2K_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+| | | +--->BN_MP_2EXPT_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_SET_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_MULMOD_C
+| | | +--->BN_MP_MUL_C
+| | | | +--->BN_MP_TOOM_MUL_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_MOD_2D_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | | +--->BN_MP_COPY_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_MUL_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_2_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_DIV_3_C
+| | | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CMP_MAG_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_MUL_DIGS_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_MOD_C
+| | | | +--->BN_MP_DIV_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_MP_COPY_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_INIT_MULTI_C
+| | | | | +--->BN_MP_SET_C
+| | | | | +--->BN_MP_MUL_2D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_LSHD_C
+| | | | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_C
+| | | | | +--->BN_MP_SUB_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_ADD_C
+| | | | | | +--->BN_S_MP_ADD_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | | +--->BN_S_MP_SUB_C
+| | | | | | | +--->BN_MP_GROW_C
+| | | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_MUL_D_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_SET_C
+| | | +--->BN_MP_ZERO_C
+| | +--->BN_MP_MOD_C
+| | | +--->BN_MP_DIV_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_COPY_C
+| | | +--->BN_MP_GROW_C
+| | +--->BN_MP_SQR_C
+| | | +--->BN_MP_TOOM_SQR_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | +--->BN_FAST_S_MP_SQR_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_SQR_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_MUL_C
+| | | +--->BN_MP_TOOM_MUL_C
+| | | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_MOD_2D_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_MUL_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_2_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_2D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_MUL_D_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_DIV_3_C
+| | | | | +--->BN_MP_INIT_SIZE_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_KARATSUBA_MUL_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_SUB_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_ADD_C
+| | | | | +--->BN_S_MP_ADD_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CMP_MAG_C
+| | | | | +--->BN_S_MP_SUB_C
+| | | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_FAST_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_S_MP_MUL_DIGS_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | +--->BN_MP_EXCH_C
++--->BN_MP_CMP_C
+| +--->BN_MP_CMP_MAG_C
++--->BN_MP_SQRMOD_C
+| +--->BN_MP_SQR_C
+| | +--->BN_MP_TOOM_SQR_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_MOD_2D_C
+| | | | +--->BN_MP_ZERO_C
+| | | | +--->BN_MP_COPY_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_MUL_2_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_2_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_DIV_3_C
+| | | | +--->BN_MP_INIT_SIZE_C
+| | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_MP_EXCH_C
+| | | | +--->BN_MP_CLEAR_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | | +--->BN_MP_CLEAR_C
+| | +--->BN_MP_KARATSUBA_SQR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_MP_CMP_MAG_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLEAR_C
+| | +--->BN_FAST_S_MP_SQR_C
+| | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_S_MP_SQR_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_C
+| +--->BN_MP_CLEAR_C
+| +--->BN_MP_MOD_C
+| | +--->BN_MP_DIV_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_MP_COPY_C
+| | | | +--->BN_MP_GROW_C
+| | | +--->BN_MP_ZERO_C
+| | | +--->BN_MP_INIT_MULTI_C
+| | | +--->BN_MP_SET_C
+| | | +--->BN_MP_COUNT_BITS_C
+| | | +--->BN_MP_ABS_C
+| | | +--->BN_MP_MUL_2D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_LSHD_C
+| | | | | +--->BN_MP_RSHD_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_SUB_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_ADD_C
+| | | | +--->BN_S_MP_ADD_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | | +--->BN_S_MP_SUB_C
+| | | | | +--->BN_MP_GROW_C
+| | | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_EXCH_C
+| | | +--->BN_MP_CLEAR_MULTI_C
+| | | +--->BN_MP_INIT_SIZE_C
+| | | +--->BN_MP_LSHD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_RSHD_C
+| | | +--->BN_MP_MUL_D_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_ADD_C
+| | | +--->BN_S_MP_ADD_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | | +--->BN_MP_CMP_MAG_C
+| | | +--->BN_S_MP_SUB_C
+| | | | +--->BN_MP_GROW_C
+| | | | +--->BN_MP_CLAMP_C
+| | +--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_DR_SETUP_C
+
+
+BN_MP_CMP_MAG_C
+
+
diff --git a/source4/heimdal/lib/hcrypto/libtommath/libtommath.dsp b/source4/heimdal/lib/hcrypto/libtommath/libtommath.dsp
new file mode 100644
index 0000000000..6b8908f07c
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/libtommath.dsp
@@ -0,0 +1,572 @@
+# Microsoft Developer Studio Project File - Name="libtommath" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=libtommath - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "libtommath.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "libtommath.mak" CFG="libtommath - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "libtommath - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "libtommath - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "libtommath"
+# PROP Scc_LocalPath "."
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "libtommath - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"Release\tommath.lib"
+
+!ELSEIF "$(CFG)" == "libtommath - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"Debug\tommath.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "libtommath - Win32 Release"
+# Name "libtommath - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\bn_error.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_fast_mp_invmod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_fast_mp_montgomery_reduce.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_fast_s_mp_mul_digs.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_fast_s_mp_mul_high_digs.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_fast_s_mp_sqr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_2expt.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_abs.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_add.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_add_d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_addmod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_and.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_clamp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_clear.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_clear_multi.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_cmp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_cmp_d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_cmp_mag.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_cnt_lsb.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_copy.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_count_bits.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_div.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_div_2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_div_2d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_div_3.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_div_d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_dr_is_modulus.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_dr_reduce.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_dr_setup.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_exch.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_expt_d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_exptmod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_exptmod_fast.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_exteuclid.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_fread.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_fwrite.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_gcd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_get_int.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_grow.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_init.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_init_copy.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_init_multi.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_init_set.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_init_set_int.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_init_size.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_invmod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_invmod_slow.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_is_square.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_jacobi.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_karatsuba_mul.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_karatsuba_sqr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_lcm.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_lshd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_mod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_mod_2d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_mod_d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_montgomery_calc_normalization.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_montgomery_reduce.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_montgomery_setup.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_mul.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_mul_2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_mul_2d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_mul_d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_mulmod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_n_root.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_neg.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_or.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_prime_fermat.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_prime_is_divisible.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_prime_is_prime.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_prime_miller_rabin.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_prime_next_prime.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_prime_rabin_miller_trials.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_prime_random_ex.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_radix_size.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_radix_smap.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_rand.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_read_radix.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_read_signed_bin.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_read_unsigned_bin.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_reduce.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_reduce_2k.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_reduce_2k_l.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_reduce_2k_setup.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_reduce_2k_setup_l.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_reduce_is_2k.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_reduce_is_2k_l.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_reduce_setup.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_rshd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_set.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_set_int.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_shrink.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_signed_bin_size.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_sqr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_sqrmod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_sqrt.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_sub.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_sub_d.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_submod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_to_signed_bin.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_to_signed_bin_n.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_to_unsigned_bin.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_to_unsigned_bin_n.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_toom_mul.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_toom_sqr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_toradix.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_toradix_n.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_unsigned_bin_size.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_xor.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_mp_zero.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_prime_tab.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_reverse.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_s_mp_add.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_s_mp_exptmod.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_s_mp_mul_digs.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_s_mp_mul_high_digs.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_s_mp_sqr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bn_s_mp_sub.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bncore.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\tommath.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\tommath_class.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\tommath_superclass.h
+# End Source File
+# End Target
+# End Project
diff --git a/source4/heimdal/lib/hcrypto/libtommath/mtest/logtab.h b/source4/heimdal/lib/hcrypto/libtommath/mtest/logtab.h
new file mode 100644
index 0000000000..bbefaefc04
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/mtest/logtab.h
@@ -0,0 +1,24 @@
+const float s_logv_2[] = {
+ 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0 1 2 3 */
+ 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */
+ 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */
+ 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */
+ 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */
+ 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */
+ 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */
+ 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */
+ 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */
+ 0.193426404, 0.191958720, 0.190551412, 0.189200360, /* 36 37 38 39 */
+ 0.187901825, 0.186652411, 0.185449023, 0.184288833, /* 40 41 42 43 */
+ 0.183169251, 0.182087900, 0.181042597, 0.180031327, /* 44 45 46 47 */
+ 0.179052232, 0.178103594, 0.177183820, 0.176291434, /* 48 49 50 51 */
+ 0.175425064, 0.174583430, 0.173765343, 0.172969690, /* 52 53 54 55 */
+ 0.172195434, 0.171441601, 0.170707280, 0.169991616, /* 56 57 58 59 */
+ 0.169293808, 0.168613099, 0.167948779, 0.167300179, /* 60 61 62 63 */
+ 0.166666667
+};
+
+
+/* $Source: /cvs/libtom/libtommath/mtest/logtab.h,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:38:47 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi-config.h b/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi-config.h
new file mode 100644
index 0000000000..6049c25ba7
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi-config.h
@@ -0,0 +1,90 @@
+/* Default configuration for MPI library */
+/* $Id: mpi-config.h,v 1.2 2005/05/05 14:38:47 tom Exp $ */
+
+#ifndef MPI_CONFIG_H_
+#define MPI_CONFIG_H_
+
+/*
+ For boolean options,
+ 0 = no
+ 1 = yes
+
+ Other options are documented individually.
+
+ */
+
+#ifndef MP_IOFUNC
+#define MP_IOFUNC 0 /* include mp_print() ? */
+#endif
+
+#ifndef MP_MODARITH
+#define MP_MODARITH 1 /* include modular arithmetic ? */
+#endif
+
+#ifndef MP_NUMTH
+#define MP_NUMTH 1 /* include number theoretic functions? */
+#endif
+
+#ifndef MP_LOGTAB
+#define MP_LOGTAB 1 /* use table of logs instead of log()? */
+#endif
+
+#ifndef MP_MEMSET
+#define MP_MEMSET 1 /* use memset() to zero buffers? */
+#endif
+
+#ifndef MP_MEMCPY
+#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */
+#endif
+
+#ifndef MP_CRYPTO
+#define MP_CRYPTO 1 /* erase memory on free? */
+#endif
+
+#ifndef MP_ARGCHK
+/*
+ 0 = no parameter checks
+ 1 = runtime checks, continue execution and return an error to caller
+ 2 = assertions; dump core on parameter errors
+ */
+#define MP_ARGCHK 2 /* how to check input arguments */
+#endif
+
+#ifndef MP_DEBUG
+#define MP_DEBUG 0 /* print diagnostic output? */
+#endif
+
+#ifndef MP_DEFPREC
+#define MP_DEFPREC 64 /* default precision, in digits */
+#endif
+
+#ifndef MP_MACRO
+#define MP_MACRO 1 /* use macros for frequent calls? */
+#endif
+
+#ifndef MP_SQUARE
+#define MP_SQUARE 1 /* use separate squaring code? */
+#endif
+
+#ifndef MP_PTAB_SIZE
+/*
+ When building mpprime.c, we build in a table of small prime
+ values to use for primality testing. The more you include,
+ the more space they take up. See primes.c for the possible
+ values (currently 16, 32, 64, 128, 256, and 6542)
+ */
+#define MP_PTAB_SIZE 128 /* how many built-in primes? */
+#endif
+
+#ifndef MP_COMPAT_MACROS
+#define MP_COMPAT_MACROS 1 /* define compatibility macros? */
+#endif
+
+#endif /* ifndef MPI_CONFIG_H_ */
+
+
+/* crc==3287762869, version==2, Sat Feb 02 06:43:53 2002 */
+
+/* $Source: /cvs/libtom/libtommath/mtest/mpi-config.h,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:38:47 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi-types.h b/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi-types.h
new file mode 100644
index 0000000000..026de589dd
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi-types.h
@@ -0,0 +1,20 @@
+/* Type definitions generated by 'types.pl' */
+typedef char mp_sign;
+typedef unsigned short mp_digit; /* 2 byte type */
+typedef unsigned int mp_word; /* 4 byte type */
+typedef unsigned int mp_size;
+typedef int mp_err;
+
+#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit))
+#define MP_DIGIT_MAX USHRT_MAX
+#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word))
+#define MP_WORD_MAX UINT_MAX
+
+#define MP_DIGIT_SIZE 2
+#define DIGIT_FMT "%04X"
+#define RADIX (MP_DIGIT_MAX+1)
+
+
+/* $Source: /cvs/libtom/libtommath/mtest/mpi-types.h,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:38:47 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi.c b/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi.c
new file mode 100644
index 0000000000..7c712dd62d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi.c
@@ -0,0 +1,3985 @@
+/*
+ mpi.c
+
+ by Michael J. Fromberger <sting@linguist.dartmouth.edu>
+ Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
+
+ Arbitrary precision integer arithmetic library
+
+ $Id: mpi.c,v 1.2 2005/05/05 14:38:47 tom Exp $
+ */
+
+#include "mpi.h"
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#if MP_DEBUG
+#include <stdio.h>
+
+#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
+#else
+#define DIAG(T,V)
+#endif
+
+/*
+ If MP_LOGTAB is not defined, use the math library to compute the
+ logarithms on the fly. Otherwise, use the static table below.
+ Pick which works best for your system.
+ */
+#if MP_LOGTAB
+
+/* {{{ s_logv_2[] - log table for 2 in various bases */
+
+/*
+ A table of the logs of 2 for various bases (the 0 and 1 entries of
+ this table are meaningless and should not be referenced).
+
+ This table is used to compute output lengths for the mp_toradix()
+ function. Since a number n in radix r takes up about log_r(n)
+ digits, we estimate the output size by taking the least integer
+ greater than log_r(n), where:
+
+ log_r(n) = log_2(n) * log_r(2)
+
+ This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
+ which are the output bases supported.
+ */
+
+#include "logtab.h"
+
+/* }}} */
+#define LOG_V_2(R) s_logv_2[(R)]
+
+#else
+
+#include <math.h>
+#define LOG_V_2(R) (log(2.0)/log(R))
+
+#endif
+
+/* Default precision for newly created mp_int's */
+static unsigned int s_mp_defprec = MP_DEFPREC;
+
+/* {{{ Digit arithmetic macros */
+
+/*
+ When adding and multiplying digits, the results can be larger than
+ can be contained in an mp_digit. Thus, an mp_word is used. These
+ macros mask off the upper and lower digits of the mp_word (the
+ mp_word may be more than 2 mp_digits wide, but we only concern
+ ourselves with the low-order 2 mp_digits)
+
+ If your mp_word DOES have more than 2 mp_digits, you need to
+ uncomment the first line, and comment out the second.
+ */
+
+/* #define CARRYOUT(W) (((W)>>DIGIT_BIT)&MP_DIGIT_MAX) */
+#define CARRYOUT(W) ((W)>>DIGIT_BIT)
+#define ACCUM(W) ((W)&MP_DIGIT_MAX)
+
+/* }}} */
+
+/* {{{ Comparison constants */
+
+#define MP_LT -1
+#define MP_EQ 0
+#define MP_GT 1
+
+/* }}} */
+
+/* {{{ Constant strings */
+
+/* Constant strings returned by mp_strerror() */
+static const char *mp_err_string[] = {
+ "unknown result code", /* say what? */
+ "boolean true", /* MP_OKAY, MP_YES */
+ "boolean false", /* MP_NO */
+ "out of memory", /* MP_MEM */
+ "argument out of range", /* MP_RANGE */
+ "invalid input parameter", /* MP_BADARG */
+ "result is undefined" /* MP_UNDEF */
+};
+
+/* Value to digit maps for radix conversion */
+
+/* s_dmap_1 - standard digits and letters */
+static const char *s_dmap_1 =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+
+#if 0
+/* s_dmap_2 - base64 ordering for digits */
+static const char *s_dmap_2 =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+#endif
+
+/* }}} */
+
+/* {{{ Static function declarations */
+
+/*
+ If MP_MACRO is false, these will be defined as actual functions;
+ otherwise, suitable macro definitions will be used. This works
+ around the fact that ANSI C89 doesn't support an 'inline' keyword
+ (although I hear C9x will ... about bloody time). At present, the
+ macro definitions are identical to the function bodies, but they'll
+ expand in place, instead of generating a function call.
+
+ I chose these particular functions to be made into macros because
+ some profiling showed they are called a lot on a typical workload,
+ and yet they are primarily housekeeping.
+ */
+#if MP_MACRO == 0
+ void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */
+ void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count); /* copy */
+ void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */
+ void s_mp_free(void *ptr); /* general free function */
+#else
+
+ /* Even if these are defined as macros, we need to respect the settings
+ of the MP_MEMSET and MP_MEMCPY configuration options...
+ */
+ #if MP_MEMSET == 0
+ #define s_mp_setz(dp, count) \
+ {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;}
+ #else
+ #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit))
+ #endif /* MP_MEMSET */
+
+ #if MP_MEMCPY == 0
+ #define s_mp_copy(sp, dp, count) \
+ {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];}
+ #else
+ #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit))
+ #endif /* MP_MEMCPY */
+
+ #define s_mp_alloc(nb, ni) calloc(nb, ni)
+ #define s_mp_free(ptr) {if(ptr) free(ptr);}
+#endif /* MP_MACRO */
+
+mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */
+mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */
+
+void s_mp_clamp(mp_int *mp); /* clip leading zeroes */
+
+void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */
+
+mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */
+void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */
+void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */
+void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */
+mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place*/
+void s_mp_div_2(mp_int *mp); /* divide by 2 in place */
+mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */
+mp_digit s_mp_norm(mp_int *a, mp_int *b); /* normalize for division */
+mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */
+mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */
+mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */
+mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r);
+ /* unsigned digit divide */
+mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu);
+ /* Barrett reduction */
+mp_err s_mp_add(mp_int *a, mp_int *b); /* magnitude addition */
+mp_err s_mp_sub(mp_int *a, mp_int *b); /* magnitude subtract */
+mp_err s_mp_mul(mp_int *a, mp_int *b); /* magnitude multiply */
+#if 0
+void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len);
+ /* multiply buffers in place */
+#endif
+#if MP_SQUARE
+mp_err s_mp_sqr(mp_int *a); /* magnitude square */
+#else
+#define s_mp_sqr(a) s_mp_mul(a, a)
+#endif
+mp_err s_mp_div(mp_int *a, mp_int *b); /* magnitude divide */
+mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */
+int s_mp_cmp(mp_int *a, mp_int *b); /* magnitude comparison */
+int s_mp_cmp_d(mp_int *a, mp_digit d); /* magnitude digit compare */
+int s_mp_ispow2(mp_int *v); /* is v a power of 2? */
+int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */
+
+int s_mp_tovalue(char ch, int r); /* convert ch to value */
+char s_mp_todigit(int val, int r, int low); /* convert val to digit */
+int s_mp_outlen(int bits, int r); /* output length in bytes */
+
+/* }}} */
+
+/* {{{ Default precision manipulation */
+
+unsigned int mp_get_prec(void)
+{
+ return s_mp_defprec;
+
+} /* end mp_get_prec() */
+
+void mp_set_prec(unsigned int prec)
+{
+ if(prec == 0)
+ s_mp_defprec = MP_DEFPREC;
+ else
+ s_mp_defprec = prec;
+
+} /* end mp_set_prec() */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ mp_init(mp) */
+
+/*
+ mp_init(mp)
+
+ Initialize a new zero-valued mp_int. Returns MP_OKAY if successful,
+ MP_MEM if memory could not be allocated for the structure.
+ */
+
+mp_err mp_init(mp_int *mp)
+{
+ return mp_init_size(mp, s_mp_defprec);
+
+} /* end mp_init() */
+
+/* }}} */
+
+/* {{{ mp_init_array(mp[], count) */
+
+mp_err mp_init_array(mp_int mp[], int count)
+{
+ mp_err res;
+ int pos;
+
+ ARGCHK(mp !=NULL && count > 0, MP_BADARG);
+
+ for(pos = 0; pos < count; ++pos) {
+ if((res = mp_init(&mp[pos])) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ return MP_OKAY;
+
+ CLEANUP:
+ while(--pos >= 0)
+ mp_clear(&mp[pos]);
+
+ return res;
+
+} /* end mp_init_array() */
+
+/* }}} */
+
+/* {{{ mp_init_size(mp, prec) */
+
+/*
+ mp_init_size(mp, prec)
+
+ Initialize a new zero-valued mp_int with at least the given
+ precision; returns MP_OKAY if successful, or MP_MEM if memory could
+ not be allocated for the structure.
+ */
+
+mp_err mp_init_size(mp_int *mp, mp_size prec)
+{
+ ARGCHK(mp != NULL && prec > 0, MP_BADARG);
+
+ if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL)
+ return MP_MEM;
+
+ SIGN(mp) = MP_ZPOS;
+ USED(mp) = 1;
+ ALLOC(mp) = prec;
+
+ return MP_OKAY;
+
+} /* end mp_init_size() */
+
+/* }}} */
+
+/* {{{ mp_init_copy(mp, from) */
+
+/*
+ mp_init_copy(mp, from)
+
+ Initialize mp as an exact copy of from. Returns MP_OKAY if
+ successful, MP_MEM if memory could not be allocated for the new
+ structure.
+ */
+
+mp_err mp_init_copy(mp_int *mp, mp_int *from)
+{
+ ARGCHK(mp != NULL && from != NULL, MP_BADARG);
+
+ if(mp == from)
+ return MP_OKAY;
+
+ if((DIGITS(mp) = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL)
+ return MP_MEM;
+
+ s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
+ USED(mp) = USED(from);
+ ALLOC(mp) = USED(from);
+ SIGN(mp) = SIGN(from);
+
+ return MP_OKAY;
+
+} /* end mp_init_copy() */
+
+/* }}} */
+
+/* {{{ mp_copy(from, to) */
+
+/*
+ mp_copy(from, to)
+
+ Copies the mp_int 'from' to the mp_int 'to'. It is presumed that
+ 'to' has already been initialized (if not, use mp_init_copy()
+ instead). If 'from' and 'to' are identical, nothing happens.
+ */
+
+mp_err mp_copy(mp_int *from, mp_int *to)
+{
+ ARGCHK(from != NULL && to != NULL, MP_BADARG);
+
+ if(from == to)
+ return MP_OKAY;
+
+ { /* copy */
+ mp_digit *tmp;
+
+ /*
+ If the allocated buffer in 'to' already has enough space to hold
+ all the used digits of 'from', we'll re-use it to avoid hitting
+ the memory allocater more than necessary; otherwise, we'd have
+ to grow anyway, so we just allocate a hunk and make the copy as
+ usual
+ */
+ if(ALLOC(to) >= USED(from)) {
+ s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
+ s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
+
+ } else {
+ if((tmp = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL)
+ return MP_MEM;
+
+ s_mp_copy(DIGITS(from), tmp, USED(from));
+
+ if(DIGITS(to) != NULL) {
+#if MP_CRYPTO
+ s_mp_setz(DIGITS(to), ALLOC(to));
+#endif
+ s_mp_free(DIGITS(to));
+ }
+
+ DIGITS(to) = tmp;
+ ALLOC(to) = USED(from);
+ }
+
+ /* Copy the precision and sign from the original */
+ USED(to) = USED(from);
+ SIGN(to) = SIGN(from);
+ } /* end copy */
+
+ return MP_OKAY;
+
+} /* end mp_copy() */
+
+/* }}} */
+
+/* {{{ mp_exch(mp1, mp2) */
+
+/*
+ mp_exch(mp1, mp2)
+
+ Exchange mp1 and mp2 without allocating any intermediate memory
+ (well, unless you count the stack space needed for this call and the
+ locals it creates...). This cannot fail.
+ */
+
+void mp_exch(mp_int *mp1, mp_int *mp2)
+{
+#if MP_ARGCHK == 2
+ assert(mp1 != NULL && mp2 != NULL);
+#else
+ if(mp1 == NULL || mp2 == NULL)
+ return;
+#endif
+
+ s_mp_exch(mp1, mp2);
+
+} /* end mp_exch() */
+
+/* }}} */
+
+/* {{{ mp_clear(mp) */
+
+/*
+ mp_clear(mp)
+
+ Release the storage used by an mp_int, and void its fields so that
+ if someone calls mp_clear() again for the same int later, we won't
+ get tollchocked.
+ */
+
+void mp_clear(mp_int *mp)
+{
+ if(mp == NULL)
+ return;
+
+ if(DIGITS(mp) != NULL) {
+#if MP_CRYPTO
+ s_mp_setz(DIGITS(mp), ALLOC(mp));
+#endif
+ s_mp_free(DIGITS(mp));
+ DIGITS(mp) = NULL;
+ }
+
+ USED(mp) = 0;
+ ALLOC(mp) = 0;
+
+} /* end mp_clear() */
+
+/* }}} */
+
+/* {{{ mp_clear_array(mp[], count) */
+
+void mp_clear_array(mp_int mp[], int count)
+{
+ ARGCHK(mp != NULL && count > 0, MP_BADARG);
+
+ while(--count >= 0)
+ mp_clear(&mp[count]);
+
+} /* end mp_clear_array() */
+
+/* }}} */
+
+/* {{{ mp_zero(mp) */
+
+/*
+ mp_zero(mp)
+
+ Set mp to zero. Does not change the allocated size of the structure,
+ and therefore cannot fail (except on a bad argument, which we ignore)
+ */
+void mp_zero(mp_int *mp)
+{
+ if(mp == NULL)
+ return;
+
+ s_mp_setz(DIGITS(mp), ALLOC(mp));
+ USED(mp) = 1;
+ SIGN(mp) = MP_ZPOS;
+
+} /* end mp_zero() */
+
+/* }}} */
+
+/* {{{ mp_set(mp, d) */
+
+void mp_set(mp_int *mp, mp_digit d)
+{
+ if(mp == NULL)
+ return;
+
+ mp_zero(mp);
+ DIGIT(mp, 0) = d;
+
+} /* end mp_set() */
+
+/* }}} */
+
+/* {{{ mp_set_int(mp, z) */
+
+mp_err mp_set_int(mp_int *mp, long z)
+{
+ int ix;
+ unsigned long v = abs(z);
+ mp_err res;
+
+ ARGCHK(mp != NULL, MP_BADARG);
+
+ mp_zero(mp);
+ if(z == 0)
+ return MP_OKAY; /* shortcut for zero */
+
+ for(ix = sizeof(long) - 1; ix >= 0; ix--) {
+
+ if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY)
+ return res;
+
+ res = s_mp_add_d(mp,
+ (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
+ if(res != MP_OKAY)
+ return res;
+
+ }
+
+ if(z < 0)
+ SIGN(mp) = MP_NEG;
+
+ return MP_OKAY;
+
+} /* end mp_set_int() */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Digit arithmetic */
+
+/* {{{ mp_add_d(a, d, b) */
+
+/*
+ mp_add_d(a, d, b)
+
+ Compute the sum b = a + d, for a single digit d. Respects the sign of
+ its primary addend (single digits are unsigned anyway).
+ */
+
+mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b)
+{
+ mp_err res = MP_OKAY;
+
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+ if((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
+
+ if(SIGN(b) == MP_ZPOS) {
+ res = s_mp_add_d(b, d);
+ } else if(s_mp_cmp_d(b, d) >= 0) {
+ res = s_mp_sub_d(b, d);
+ } else {
+ SIGN(b) = MP_ZPOS;
+
+ DIGIT(b, 0) = d - DIGIT(b, 0);
+ }
+
+ return res;
+
+} /* end mp_add_d() */
+
+/* }}} */
+
+/* {{{ mp_sub_d(a, d, b) */
+
+/*
+ mp_sub_d(a, d, b)
+
+ Compute the difference b = a - d, for a single digit d. Respects the
+ sign of its subtrahend (single digits are unsigned anyway).
+ */
+
+mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+ if((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
+
+ if(SIGN(b) == MP_NEG) {
+ if((res = s_mp_add_d(b, d)) != MP_OKAY)
+ return res;
+
+ } else if(s_mp_cmp_d(b, d) >= 0) {
+ if((res = s_mp_sub_d(b, d)) != MP_OKAY)
+ return res;
+
+ } else {
+ mp_neg(b, b);
+
+ DIGIT(b, 0) = d - DIGIT(b, 0);
+ SIGN(b) = MP_NEG;
+ }
+
+ if(s_mp_cmp_d(b, 0) == 0)
+ SIGN(b) = MP_ZPOS;
+
+ return MP_OKAY;
+
+} /* end mp_sub_d() */
+
+/* }}} */
+
+/* {{{ mp_mul_d(a, d, b) */
+
+/*
+ mp_mul_d(a, d, b)
+
+ Compute the product b = a * d, for a single digit d. Respects the sign
+ of its multiplicand (single digits are unsigned anyway)
+ */
+
+mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+ if(d == 0) {
+ mp_zero(b);
+ return MP_OKAY;
+ }
+
+ if((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
+
+ res = s_mp_mul_d(b, d);
+
+ return res;
+
+} /* end mp_mul_d() */
+
+/* }}} */
+
+/* {{{ mp_mul_2(a, c) */
+
+mp_err mp_mul_2(mp_int *a, mp_int *c)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+ if((res = mp_copy(a, c)) != MP_OKAY)
+ return res;
+
+ return s_mp_mul_2(c);
+
+} /* end mp_mul_2() */
+
+/* }}} */
+
+/* {{{ mp_div_d(a, d, q, r) */
+
+/*
+ mp_div_d(a, d, q, r)
+
+ Compute the quotient q = a / d and remainder r = a mod d, for a
+ single digit d. Respects the sign of its divisor (single digits are
+ unsigned anyway).
+ */
+
+mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
+{
+ mp_err res;
+ mp_digit rem;
+ int pow;
+
+ ARGCHK(a != NULL, MP_BADARG);
+
+ if(d == 0)
+ return MP_RANGE;
+
+ /* Shortcut for powers of two ... */
+ if((pow = s_mp_ispow2d(d)) >= 0) {
+ mp_digit mask;
+
+ mask = (1 << pow) - 1;
+ rem = DIGIT(a, 0) & mask;
+
+ if(q) {
+ mp_copy(a, q);
+ s_mp_div_2d(q, pow);
+ }
+
+ if(r)
+ *r = rem;
+
+ return MP_OKAY;
+ }
+
+ /*
+ If the quotient is actually going to be returned, we'll try to
+ avoid hitting the memory allocator by copying the dividend into it
+ and doing the division there. This can't be any _worse_ than
+ always copying, and will sometimes be better (since it won't make
+ another copy)
+
+ If it's not going to be returned, we need to allocate a temporary
+ to hold the quotient, which will just be discarded.
+ */
+ if(q) {
+ if((res = mp_copy(a, q)) != MP_OKAY)
+ return res;
+
+ res = s_mp_div_d(q, d, &rem);
+ if(s_mp_cmp_d(q, 0) == MP_EQ)
+ SIGN(q) = MP_ZPOS;
+
+ } else {
+ mp_int qp;
+
+ if((res = mp_init_copy(&qp, a)) != MP_OKAY)
+ return res;
+
+ res = s_mp_div_d(&qp, d, &rem);
+ if(s_mp_cmp_d(&qp, 0) == 0)
+ SIGN(&qp) = MP_ZPOS;
+
+ mp_clear(&qp);
+ }
+
+ if(r)
+ *r = rem;
+
+ return res;
+
+} /* end mp_div_d() */
+
+/* }}} */
+
+/* {{{ mp_div_2(a, c) */
+
+/*
+ mp_div_2(a, c)
+
+ Compute c = a / 2, disregarding the remainder.
+ */
+
+mp_err mp_div_2(mp_int *a, mp_int *c)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+ if((res = mp_copy(a, c)) != MP_OKAY)
+ return res;
+
+ s_mp_div_2(c);
+
+ return MP_OKAY;
+
+} /* end mp_div_2() */
+
+/* }}} */
+
+/* {{{ mp_expt_d(a, d, b) */
+
+mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c)
+{
+ mp_int s, x;
+ mp_err res;
+
+ ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+ if((res = mp_init(&s)) != MP_OKAY)
+ return res;
+ if((res = mp_init_copy(&x, a)) != MP_OKAY)
+ goto X;
+
+ DIGIT(&s, 0) = 1;
+
+ while(d != 0) {
+ if(d & 1) {
+ if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ d >>= 1;
+
+ if((res = s_mp_sqr(&x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ s_mp_exch(&s, c);
+
+CLEANUP:
+ mp_clear(&x);
+X:
+ mp_clear(&s);
+
+ return res;
+
+} /* end mp_expt_d() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Full arithmetic */
+
+/* {{{ mp_abs(a, b) */
+
+/*
+ mp_abs(a, b)
+
+ Compute b = |a|. 'a' and 'b' may be identical.
+ */
+
+mp_err mp_abs(mp_int *a, mp_int *b)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+ if((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
+
+ SIGN(b) = MP_ZPOS;
+
+ return MP_OKAY;
+
+} /* end mp_abs() */
+
+/* }}} */
+
+/* {{{ mp_neg(a, b) */
+
+/*
+ mp_neg(a, b)
+
+ Compute b = -a. 'a' and 'b' may be identical.
+ */
+
+mp_err mp_neg(mp_int *a, mp_int *b)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+ if((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
+
+ if(s_mp_cmp_d(b, 0) == MP_EQ)
+ SIGN(b) = MP_ZPOS;
+ else
+ SIGN(b) = (SIGN(b) == MP_NEG) ? MP_ZPOS : MP_NEG;
+
+ return MP_OKAY;
+
+} /* end mp_neg() */
+
+/* }}} */
+
+/* {{{ mp_add(a, b, c) */
+
+/*
+ mp_add(a, b, c)
+
+ Compute c = a + b. All parameters may be identical.
+ */
+
+mp_err mp_add(mp_int *a, mp_int *b, mp_int *c)
+{
+ mp_err res;
+ int cmp;
+
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+ if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */
+
+ /* Commutativity of addition lets us do this in either order,
+ so we avoid having to use a temporary even if the result
+ is supposed to replace the output
+ */
+ if(c == b) {
+ if((res = s_mp_add(c, a)) != MP_OKAY)
+ return res;
+ } else {
+ if(c != a && (res = mp_copy(a, c)) != MP_OKAY)
+ return res;
+
+ if((res = s_mp_add(c, b)) != MP_OKAY)
+ return res;
+ }
+
+ } else if((cmp = s_mp_cmp(a, b)) > 0) { /* different sign: a > b */
+
+ /* If the output is going to be clobbered, we will use a temporary
+ variable; otherwise, we'll do it without touching the memory
+ allocator at all, if possible
+ */
+ if(c == b) {
+ mp_int tmp;
+
+ if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
+ return res;
+ if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {
+ mp_clear(&tmp);
+ return res;
+ }
+
+ s_mp_exch(&tmp, c);
+ mp_clear(&tmp);
+
+ } else {
+
+ if(c != a && (res = mp_copy(a, c)) != MP_OKAY)
+ return res;
+ if((res = s_mp_sub(c, b)) != MP_OKAY)
+ return res;
+
+ }
+
+ } else if(cmp == 0) { /* different sign, a == b */
+
+ mp_zero(c);
+ return MP_OKAY;
+
+ } else { /* different sign: a < b */
+
+ /* See above... */
+ if(c == a) {
+ mp_int tmp;
+
+ if((res = mp_init_copy(&tmp, b)) != MP_OKAY)
+ return res;
+ if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {
+ mp_clear(&tmp);
+ return res;
+ }
+
+ s_mp_exch(&tmp, c);
+ mp_clear(&tmp);
+
+ } else {
+
+ if(c != b && (res = mp_copy(b, c)) != MP_OKAY)
+ return res;
+ if((res = s_mp_sub(c, a)) != MP_OKAY)
+ return res;
+
+ }
+ }
+
+ if(USED(c) == 1 && DIGIT(c, 0) == 0)
+ SIGN(c) = MP_ZPOS;
+
+ return MP_OKAY;
+
+} /* end mp_add() */
+
+/* }}} */
+
+/* {{{ mp_sub(a, b, c) */
+
+/*
+ mp_sub(a, b, c)
+
+ Compute c = a - b. All parameters may be identical.
+ */
+
+mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c)
+{
+ mp_err res;
+ int cmp;
+
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+ if(SIGN(a) != SIGN(b)) {
+ if(c == a) {
+ if((res = s_mp_add(c, b)) != MP_OKAY)
+ return res;
+ } else {
+ if(c != b && ((res = mp_copy(b, c)) != MP_OKAY))
+ return res;
+ if((res = s_mp_add(c, a)) != MP_OKAY)
+ return res;
+ SIGN(c) = SIGN(a);
+ }
+
+ } else if((cmp = s_mp_cmp(a, b)) > 0) { /* Same sign, a > b */
+ if(c == b) {
+ mp_int tmp;
+
+ if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
+ return res;
+ if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {
+ mp_clear(&tmp);
+ return res;
+ }
+ s_mp_exch(&tmp, c);
+ mp_clear(&tmp);
+
+ } else {
+ if(c != a && ((res = mp_copy(a, c)) != MP_OKAY))
+ return res;
+
+ if((res = s_mp_sub(c, b)) != MP_OKAY)
+ return res;
+ }
+
+ } else if(cmp == 0) { /* Same sign, equal magnitude */
+ mp_zero(c);
+ return MP_OKAY;
+
+ } else { /* Same sign, b > a */
+ if(c == a) {
+ mp_int tmp;
+
+ if((res = mp_init_copy(&tmp, b)) != MP_OKAY)
+ return res;
+
+ if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {
+ mp_clear(&tmp);
+ return res;
+ }
+ s_mp_exch(&tmp, c);
+ mp_clear(&tmp);
+
+ } else {
+ if(c != b && ((res = mp_copy(b, c)) != MP_OKAY))
+ return res;
+
+ if((res = s_mp_sub(c, a)) != MP_OKAY)
+ return res;
+ }
+
+ SIGN(c) = !SIGN(b);
+ }
+
+ if(USED(c) == 1 && DIGIT(c, 0) == 0)
+ SIGN(c) = MP_ZPOS;
+
+ return MP_OKAY;
+
+} /* end mp_sub() */
+
+/* }}} */
+
+/* {{{ mp_mul(a, b, c) */
+
+/*
+ mp_mul(a, b, c)
+
+ Compute c = a * b. All parameters may be identical.
+ */
+
+mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c)
+{
+ mp_err res;
+ mp_sign sgn;
+
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+ sgn = (SIGN(a) == SIGN(b)) ? MP_ZPOS : MP_NEG;
+
+ if(c == b) {
+ if((res = s_mp_mul(c, a)) != MP_OKAY)
+ return res;
+
+ } else {
+ if((res = mp_copy(a, c)) != MP_OKAY)
+ return res;
+
+ if((res = s_mp_mul(c, b)) != MP_OKAY)
+ return res;
+ }
+
+ if(sgn == MP_ZPOS || s_mp_cmp_d(c, 0) == MP_EQ)
+ SIGN(c) = MP_ZPOS;
+ else
+ SIGN(c) = sgn;
+
+ return MP_OKAY;
+
+} /* end mp_mul() */
+
+/* }}} */
+
+/* {{{ mp_mul_2d(a, d, c) */
+
+/*
+ mp_mul_2d(a, d, c)
+
+ Compute c = a * 2^d. a may be the same as c.
+ */
+
+mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+ if((res = mp_copy(a, c)) != MP_OKAY)
+ return res;
+
+ if(d == 0)
+ return MP_OKAY;
+
+ return s_mp_mul_2d(c, d);
+
+} /* end mp_mul() */
+
+/* }}} */
+
+/* {{{ mp_sqr(a, b) */
+
+#if MP_SQUARE
+mp_err mp_sqr(mp_int *a, mp_int *b)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+ if((res = mp_copy(a, b)) != MP_OKAY)
+ return res;
+
+ if((res = s_mp_sqr(b)) != MP_OKAY)
+ return res;
+
+ SIGN(b) = MP_ZPOS;
+
+ return MP_OKAY;
+
+} /* end mp_sqr() */
+#endif
+
+/* }}} */
+
+/* {{{ mp_div(a, b, q, r) */
+
+/*
+ mp_div(a, b, q, r)
+
+ Compute q = a / b and r = a mod b. Input parameters may be re-used
+ as output parameters. If q or r is NULL, that portion of the
+ computation will be discarded (although it will still be computed)
+
+ Pay no attention to the hacker behind the curtain.
+ */
+
+mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r)
+{
+ mp_err res;
+ mp_int qtmp, rtmp;
+ int cmp;
+
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+ if(mp_cmp_z(b) == MP_EQ)
+ return MP_RANGE;
+
+ /* If a <= b, we can compute the solution without division, and
+ avoid any memory allocation
+ */
+ if((cmp = s_mp_cmp(a, b)) < 0) {
+ if(r) {
+ if((res = mp_copy(a, r)) != MP_OKAY)
+ return res;
+ }
+
+ if(q)
+ mp_zero(q);
+
+ return MP_OKAY;
+
+ } else if(cmp == 0) {
+
+ /* Set quotient to 1, with appropriate sign */
+ if(q) {
+ int qneg = (SIGN(a) != SIGN(b));
+
+ mp_set(q, 1);
+ if(qneg)
+ SIGN(q) = MP_NEG;
+ }
+
+ if(r)
+ mp_zero(r);
+
+ return MP_OKAY;
+ }
+
+ /* If we get here, it means we actually have to do some division */
+
+ /* Set up some temporaries... */
+ if((res = mp_init_copy(&qtmp, a)) != MP_OKAY)
+ return res;
+ if((res = mp_init_copy(&rtmp, b)) != MP_OKAY)
+ goto CLEANUP;
+
+ if((res = s_mp_div(&qtmp, &rtmp)) != MP_OKAY)
+ goto CLEANUP;
+
+ /* Compute the signs for the output */
+ SIGN(&rtmp) = SIGN(a); /* Sr = Sa */
+ if(SIGN(a) == SIGN(b))
+ SIGN(&qtmp) = MP_ZPOS; /* Sq = MP_ZPOS if Sa = Sb */
+ else
+ SIGN(&qtmp) = MP_NEG; /* Sq = MP_NEG if Sa != Sb */
+
+ if(s_mp_cmp_d(&qtmp, 0) == MP_EQ)
+ SIGN(&qtmp) = MP_ZPOS;
+ if(s_mp_cmp_d(&rtmp, 0) == MP_EQ)
+ SIGN(&rtmp) = MP_ZPOS;
+
+ /* Copy output, if it is needed */
+ if(q)
+ s_mp_exch(&qtmp, q);
+
+ if(r)
+ s_mp_exch(&rtmp, r);
+
+CLEANUP:
+ mp_clear(&rtmp);
+ mp_clear(&qtmp);
+
+ return res;
+
+} /* end mp_div() */
+
+/* }}} */
+
+/* {{{ mp_div_2d(a, d, q, r) */
+
+mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL, MP_BADARG);
+
+ if(q) {
+ if((res = mp_copy(a, q)) != MP_OKAY)
+ return res;
+
+ s_mp_div_2d(q, d);
+ }
+
+ if(r) {
+ if((res = mp_copy(a, r)) != MP_OKAY)
+ return res;
+
+ s_mp_mod_2d(r, d);
+ }
+
+ return MP_OKAY;
+
+} /* end mp_div_2d() */
+
+/* }}} */
+
+/* {{{ mp_expt(a, b, c) */
+
+/*
+ mp_expt(a, b, c)
+
+ Compute c = a ** b, that is, raise a to the b power. Uses a
+ standard iterative square-and-multiply technique.
+ */
+
+mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
+{
+ mp_int s, x;
+ mp_err res;
+ mp_digit d;
+ int dig, bit;
+
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+ if(mp_cmp_z(b) < 0)
+ return MP_RANGE;
+
+ if((res = mp_init(&s)) != MP_OKAY)
+ return res;
+
+ mp_set(&s, 1);
+
+ if((res = mp_init_copy(&x, a)) != MP_OKAY)
+ goto X;
+
+ /* Loop over low-order digits in ascending order */
+ for(dig = 0; dig < (USED(b) - 1); dig++) {
+ d = DIGIT(b, dig);
+
+ /* Loop over bits of each non-maximal digit */
+ for(bit = 0; bit < DIGIT_BIT; bit++) {
+ if(d & 1) {
+ if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ d >>= 1;
+
+ if((res = s_mp_sqr(&x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+ }
+
+ /* Consider now the last digit... */
+ d = DIGIT(b, dig);
+
+ while(d) {
+ if(d & 1) {
+ if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ d >>= 1;
+
+ if((res = s_mp_sqr(&x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ if(mp_iseven(b))
+ SIGN(&s) = SIGN(a);
+
+ res = mp_copy(&s, c);
+
+CLEANUP:
+ mp_clear(&x);
+X:
+ mp_clear(&s);
+
+ return res;
+
+} /* end mp_expt() */
+
+/* }}} */
+
+/* {{{ mp_2expt(a, k) */
+
+/* Compute a = 2^k */
+
+mp_err mp_2expt(mp_int *a, mp_digit k)
+{
+ ARGCHK(a != NULL, MP_BADARG);
+
+ return s_mp_2expt(a, k);
+
+} /* end mp_2expt() */
+
+/* }}} */
+
+/* {{{ mp_mod(a, m, c) */
+
+/*
+ mp_mod(a, m, c)
+
+ Compute c = a (mod m). Result will always be 0 <= c < m.
+ */
+
+mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c)
+{
+ mp_err res;
+ int mag;
+
+ ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
+
+ if(SIGN(m) == MP_NEG)
+ return MP_RANGE;
+
+ /*
+ If |a| > m, we need to divide to get the remainder and take the
+ absolute value.
+
+ If |a| < m, we don't need to do any division, just copy and adjust
+ the sign (if a is negative).
+
+ If |a| == m, we can simply set the result to zero.
+
+ This order is intended to minimize the average path length of the
+ comparison chain on common workloads -- the most frequent cases are
+ that |a| != m, so we do those first.
+ */
+ if((mag = s_mp_cmp(a, m)) > 0) {
+ if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
+ return res;
+
+ if(SIGN(c) == MP_NEG) {
+ if((res = mp_add(c, m, c)) != MP_OKAY)
+ return res;
+ }
+
+ } else if(mag < 0) {
+ if((res = mp_copy(a, c)) != MP_OKAY)
+ return res;
+
+ if(mp_cmp_z(a) < 0) {
+ if((res = mp_add(c, m, c)) != MP_OKAY)
+ return res;
+
+ }
+
+ } else {
+ mp_zero(c);
+
+ }
+
+ return MP_OKAY;
+
+} /* end mp_mod() */
+
+/* }}} */
+
+/* {{{ mp_mod_d(a, d, c) */
+
+/*
+ mp_mod_d(a, d, c)
+
+ Compute c = a (mod d). Result will always be 0 <= c < d
+ */
+mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c)
+{
+ mp_err res;
+ mp_digit rem;
+
+ ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+ if(s_mp_cmp_d(a, d) > 0) {
+ if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
+ return res;
+
+ } else {
+ if(SIGN(a) == MP_NEG)
+ rem = d - DIGIT(a, 0);
+ else
+ rem = DIGIT(a, 0);
+ }
+
+ if(c)
+ *c = rem;
+
+ return MP_OKAY;
+
+} /* end mp_mod_d() */
+
+/* }}} */
+
+/* {{{ mp_sqrt(a, b) */
+
+/*
+ mp_sqrt(a, b)
+
+ Compute the integer square root of a, and store the result in b.
+ Uses an integer-arithmetic version of Newton's iterative linear
+ approximation technique to determine this value; the result has the
+ following two properties:
+
+ b^2 <= a
+ (b+1)^2 >= a
+
+ It is a range error to pass a negative value.
+ */
+mp_err mp_sqrt(mp_int *a, mp_int *b)
+{
+ mp_int x, t;
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+ /* Cannot take square root of a negative value */
+ if(SIGN(a) == MP_NEG)
+ return MP_RANGE;
+
+ /* Special cases for zero and one, trivial */
+ if(mp_cmp_d(a, 0) == MP_EQ || mp_cmp_d(a, 1) == MP_EQ)
+ return mp_copy(a, b);
+
+ /* Initialize the temporaries we'll use below */
+ if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
+ return res;
+
+ /* Compute an initial guess for the iteration as a itself */
+ if((res = mp_init_copy(&x, a)) != MP_OKAY)
+ goto X;
+
+s_mp_rshd(&x, (USED(&x)/2)+1);
+mp_add_d(&x, 1, &x);
+
+ for(;;) {
+ /* t = (x * x) - a */
+ mp_copy(&x, &t); /* can't fail, t is big enough for original x */
+ if((res = mp_sqr(&t, &t)) != MP_OKAY ||
+ (res = mp_sub(&t, a, &t)) != MP_OKAY)
+ goto CLEANUP;
+
+ /* t = t / 2x */
+ s_mp_mul_2(&x);
+ if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
+ goto CLEANUP;
+ s_mp_div_2(&x);
+
+ /* Terminate the loop, if the quotient is zero */
+ if(mp_cmp_z(&t) == MP_EQ)
+ break;
+
+ /* x = x - t */
+ if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
+ goto CLEANUP;
+
+ }
+
+ /* Copy result to output parameter */
+ mp_sub_d(&x, 1, &x);
+ s_mp_exch(&x, b);
+
+ CLEANUP:
+ mp_clear(&x);
+ X:
+ mp_clear(&t);
+
+ return res;
+
+} /* end mp_sqrt() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Modular arithmetic */
+
+#if MP_MODARITH
+/* {{{ mp_addmod(a, b, m, c) */
+
+/*
+ mp_addmod(a, b, m, c)
+
+ Compute c = (a + b) mod m
+ */
+
+mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+
+ if((res = mp_add(a, b, c)) != MP_OKAY)
+ return res;
+ if((res = mp_mod(c, m, c)) != MP_OKAY)
+ return res;
+
+ return MP_OKAY;
+
+}
+
+/* }}} */
+
+/* {{{ mp_submod(a, b, m, c) */
+
+/*
+ mp_submod(a, b, m, c)
+
+ Compute c = (a - b) mod m
+ */
+
+mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+
+ if((res = mp_sub(a, b, c)) != MP_OKAY)
+ return res;
+ if((res = mp_mod(c, m, c)) != MP_OKAY)
+ return res;
+
+ return MP_OKAY;
+
+}
+
+/* }}} */
+
+/* {{{ mp_mulmod(a, b, m, c) */
+
+/*
+ mp_mulmod(a, b, m, c)
+
+ Compute c = (a * b) mod m
+ */
+
+mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+
+ if((res = mp_mul(a, b, c)) != MP_OKAY)
+ return res;
+ if((res = mp_mod(c, m, c)) != MP_OKAY)
+ return res;
+
+ return MP_OKAY;
+
+}
+
+/* }}} */
+
+/* {{{ mp_sqrmod(a, m, c) */
+
+#if MP_SQUARE
+mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c)
+{
+ mp_err res;
+
+ ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
+
+ if((res = mp_sqr(a, c)) != MP_OKAY)
+ return res;
+ if((res = mp_mod(c, m, c)) != MP_OKAY)
+ return res;
+
+ return MP_OKAY;
+
+} /* end mp_sqrmod() */
+#endif
+
+/* }}} */
+
+/* {{{ mp_exptmod(a, b, m, c) */
+
+/*
+ mp_exptmod(a, b, m, c)
+
+ Compute c = (a ** b) mod m. Uses a standard square-and-multiply
+ method with modular reductions at each step. (This is basically the
+ same code as mp_expt(), except for the addition of the reductions)
+
+ The modular reductions are done using Barrett's algorithm (see
+ s_mp_reduce() below for details)
+ */
+
+mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
+{
+ mp_int s, x, mu;
+ mp_err res;
+ mp_digit d, *db = DIGITS(b);
+ mp_size ub = USED(b);
+ int dig, bit;
+
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+ if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
+ return MP_RANGE;
+
+ if((res = mp_init(&s)) != MP_OKAY)
+ return res;
+ if((res = mp_init_copy(&x, a)) != MP_OKAY)
+ goto X;
+ if((res = mp_mod(&x, m, &x)) != MP_OKAY ||
+ (res = mp_init(&mu)) != MP_OKAY)
+ goto MU;
+
+ mp_set(&s, 1);
+
+ /* mu = b^2k / m */
+ s_mp_add_d(&mu, 1);
+ s_mp_lshd(&mu, 2 * USED(m));
+ if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
+ goto CLEANUP;
+
+ /* Loop over digits of b in ascending order, except highest order */
+ for(dig = 0; dig < (ub - 1); dig++) {
+ d = *db++;
+
+ /* Loop over the bits of the lower-order digits */
+ for(bit = 0; bit < DIGIT_BIT; bit++) {
+ if(d & 1) {
+ if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+ goto CLEANUP;
+ if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ d >>= 1;
+
+ if((res = s_mp_sqr(&x)) != MP_OKAY)
+ goto CLEANUP;
+ if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
+ goto CLEANUP;
+ }
+ }
+
+ /* Now do the last digit... */
+ d = *db;
+
+ while(d) {
+ if(d & 1) {
+ if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+ goto CLEANUP;
+ if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ d >>= 1;
+
+ if((res = s_mp_sqr(&x)) != MP_OKAY)
+ goto CLEANUP;
+ if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ s_mp_exch(&s, c);
+
+ CLEANUP:
+ mp_clear(&mu);
+ MU:
+ mp_clear(&x);
+ X:
+ mp_clear(&s);
+
+ return res;
+
+} /* end mp_exptmod() */
+
+/* }}} */
+
+/* {{{ mp_exptmod_d(a, d, m, c) */
+
+mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c)
+{
+ mp_int s, x;
+ mp_err res;
+
+ ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+ if((res = mp_init(&s)) != MP_OKAY)
+ return res;
+ if((res = mp_init_copy(&x, a)) != MP_OKAY)
+ goto X;
+
+ mp_set(&s, 1);
+
+ while(d != 0) {
+ if(d & 1) {
+ if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
+ (res = mp_mod(&s, m, &s)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ d /= 2;
+
+ if((res = s_mp_sqr(&x)) != MP_OKAY ||
+ (res = mp_mod(&x, m, &x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ s_mp_exch(&s, c);
+
+CLEANUP:
+ mp_clear(&x);
+X:
+ mp_clear(&s);
+
+ return res;
+
+} /* end mp_exptmod_d() */
+
+/* }}} */
+#endif /* if MP_MODARITH */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Comparison functions */
+
+/* {{{ mp_cmp_z(a) */
+
+/*
+ mp_cmp_z(a)
+
+ Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0.
+ */
+
+int mp_cmp_z(mp_int *a)
+{
+ if(SIGN(a) == MP_NEG)
+ return MP_LT;
+ else if(USED(a) == 1 && DIGIT(a, 0) == 0)
+ return MP_EQ;
+ else
+ return MP_GT;
+
+} /* end mp_cmp_z() */
+
+/* }}} */
+
+/* {{{ mp_cmp_d(a, d) */
+
+/*
+ mp_cmp_d(a, d)
+
+ Compare a <=> d. Returns <0 if a<d, 0 if a=d, >0 if a>d
+ */
+
+int mp_cmp_d(mp_int *a, mp_digit d)
+{
+ ARGCHK(a != NULL, MP_EQ);
+
+ if(SIGN(a) == MP_NEG)
+ return MP_LT;
+
+ return s_mp_cmp_d(a, d);
+
+} /* end mp_cmp_d() */
+
+/* }}} */
+
+/* {{{ mp_cmp(a, b) */
+
+int mp_cmp(mp_int *a, mp_int *b)
+{
+ ARGCHK(a != NULL && b != NULL, MP_EQ);
+
+ if(SIGN(a) == SIGN(b)) {
+ int mag;
+
+ if((mag = s_mp_cmp(a, b)) == MP_EQ)
+ return MP_EQ;
+
+ if(SIGN(a) == MP_ZPOS)
+ return mag;
+ else
+ return -mag;
+
+ } else if(SIGN(a) == MP_ZPOS) {
+ return MP_GT;
+ } else {
+ return MP_LT;
+ }
+
+} /* end mp_cmp() */
+
+/* }}} */
+
+/* {{{ mp_cmp_mag(a, b) */
+
+/*
+ mp_cmp_mag(a, b)
+
+ Compares |a| <=> |b|, and returns an appropriate comparison result
+ */
+
+int mp_cmp_mag(mp_int *a, mp_int *b)
+{
+ ARGCHK(a != NULL && b != NULL, MP_EQ);
+
+ return s_mp_cmp(a, b);
+
+} /* end mp_cmp_mag() */
+
+/* }}} */
+
+/* {{{ mp_cmp_int(a, z) */
+
+/*
+ This just converts z to an mp_int, and uses the existing comparison
+ routines. This is sort of inefficient, but it's not clear to me how
+ frequently this wil get used anyway. For small positive constants,
+ you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
+ */
+int mp_cmp_int(mp_int *a, long z)
+{
+ mp_int tmp;
+ int out;
+
+ ARGCHK(a != NULL, MP_EQ);
+
+ mp_init(&tmp); mp_set_int(&tmp, z);
+ out = mp_cmp(a, &tmp);
+ mp_clear(&tmp);
+
+ return out;
+
+} /* end mp_cmp_int() */
+
+/* }}} */
+
+/* {{{ mp_isodd(a) */
+
+/*
+ mp_isodd(a)
+
+ Returns a true (non-zero) value if a is odd, false (zero) otherwise.
+ */
+int mp_isodd(mp_int *a)
+{
+ ARGCHK(a != NULL, 0);
+
+ return (DIGIT(a, 0) & 1);
+
+} /* end mp_isodd() */
+
+/* }}} */
+
+/* {{{ mp_iseven(a) */
+
+int mp_iseven(mp_int *a)
+{
+ return !mp_isodd(a);
+
+} /* end mp_iseven() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Number theoretic functions */
+
+#if MP_NUMTH
+/* {{{ mp_gcd(a, b, c) */
+
+/*
+ Like the old mp_gcd() function, except computes the GCD using the
+ binary algorithm due to Josef Stein in 1961 (via Knuth).
+ */
+mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
+{
+ mp_err res;
+ mp_int u, v, t;
+ mp_size k = 0;
+
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+ if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
+ return MP_RANGE;
+ if(mp_cmp_z(a) == MP_EQ) {
+ return mp_copy(b, c);
+ } else if(mp_cmp_z(b) == MP_EQ) {
+ return mp_copy(a, c);
+ }
+
+ if((res = mp_init(&t)) != MP_OKAY)
+ return res;
+ if((res = mp_init_copy(&u, a)) != MP_OKAY)
+ goto U;
+ if((res = mp_init_copy(&v, b)) != MP_OKAY)
+ goto V;
+
+ SIGN(&u) = MP_ZPOS;
+ SIGN(&v) = MP_ZPOS;
+
+ /* Divide out common factors of 2 until at least 1 of a, b is even */
+ while(mp_iseven(&u) && mp_iseven(&v)) {
+ s_mp_div_2(&u);
+ s_mp_div_2(&v);
+ ++k;
+ }
+
+ /* Initialize t */
+ if(mp_isodd(&u)) {
+ if((res = mp_copy(&v, &t)) != MP_OKAY)
+ goto CLEANUP;
+
+ /* t = -v */
+ if(SIGN(&v) == MP_ZPOS)
+ SIGN(&t) = MP_NEG;
+ else
+ SIGN(&t) = MP_ZPOS;
+
+ } else {
+ if((res = mp_copy(&u, &t)) != MP_OKAY)
+ goto CLEANUP;
+
+ }
+
+ for(;;) {
+ while(mp_iseven(&t)) {
+ s_mp_div_2(&t);
+ }
+
+ if(mp_cmp_z(&t) == MP_GT) {
+ if((res = mp_copy(&t, &u)) != MP_OKAY)
+ goto CLEANUP;
+
+ } else {
+ if((res = mp_copy(&t, &v)) != MP_OKAY)
+ goto CLEANUP;
+
+ /* v = -t */
+ if(SIGN(&t) == MP_ZPOS)
+ SIGN(&v) = MP_NEG;
+ else
+ SIGN(&v) = MP_ZPOS;
+ }
+
+ if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
+ goto CLEANUP;
+
+ if(s_mp_cmp_d(&t, 0) == MP_EQ)
+ break;
+ }
+
+ s_mp_2expt(&v, k); /* v = 2^k */
+ res = mp_mul(&u, &v, c); /* c = u * v */
+
+ CLEANUP:
+ mp_clear(&v);
+ V:
+ mp_clear(&u);
+ U:
+ mp_clear(&t);
+
+ return res;
+
+} /* end mp_bgcd() */
+
+/* }}} */
+
+/* {{{ mp_lcm(a, b, c) */
+
+/* We compute the least common multiple using the rule:
+
+ ab = [a, b](a, b)
+
+ ... by computing the product, and dividing out the gcd.
+ */
+
+mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
+{
+ mp_int gcd, prod;
+ mp_err res;
+
+ ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+ /* Set up temporaries */
+ if((res = mp_init(&gcd)) != MP_OKAY)
+ return res;
+ if((res = mp_init(&prod)) != MP_OKAY)
+ goto GCD;
+
+ if((res = mp_mul(a, b, &prod)) != MP_OKAY)
+ goto CLEANUP;
+ if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
+ goto CLEANUP;
+
+ res = mp_div(&prod, &gcd, c, NULL);
+
+ CLEANUP:
+ mp_clear(&prod);
+ GCD:
+ mp_clear(&gcd);
+
+ return res;
+
+} /* end mp_lcm() */
+
+/* }}} */
+
+/* {{{ mp_xgcd(a, b, g, x, y) */
+
+/*
+ mp_xgcd(a, b, g, x, y)
+
+ Compute g = (a, b) and values x and y satisfying Bezout's identity
+ (that is, ax + by = g). This uses the extended binary GCD algorithm
+ based on the Stein algorithm used for mp_gcd()
+ */
+
+mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y)
+{
+ mp_int gx, xc, yc, u, v, A, B, C, D;
+ mp_int *clean[9];
+ mp_err res;
+ int last = -1;
+
+ if(mp_cmp_z(b) == 0)
+ return MP_RANGE;
+
+ /* Initialize all these variables we need */
+ if((res = mp_init(&u)) != MP_OKAY) goto CLEANUP;
+ clean[++last] = &u;
+ if((res = mp_init(&v)) != MP_OKAY) goto CLEANUP;
+ clean[++last] = &v;
+ if((res = mp_init(&gx)) != MP_OKAY) goto CLEANUP;
+ clean[++last] = &gx;
+ if((res = mp_init(&A)) != MP_OKAY) goto CLEANUP;
+ clean[++last] = &A;
+ if((res = mp_init(&B)) != MP_OKAY) goto CLEANUP;
+ clean[++last] = &B;
+ if((res = mp_init(&C)) != MP_OKAY) goto CLEANUP;
+ clean[++last] = &C;
+ if((res = mp_init(&D)) != MP_OKAY) goto CLEANUP;
+ clean[++last] = &D;
+ if((res = mp_init_copy(&xc, a)) != MP_OKAY) goto CLEANUP;
+ clean[++last] = &xc;
+ mp_abs(&xc, &xc);
+ if((res = mp_init_copy(&yc, b)) != MP_OKAY) goto CLEANUP;
+ clean[++last] = &yc;
+ mp_abs(&yc, &yc);
+
+ mp_set(&gx, 1);
+
+ /* Divide by two until at least one of them is even */
+ while(mp_iseven(&xc) && mp_iseven(&yc)) {
+ s_mp_div_2(&xc);
+ s_mp_div_2(&yc);
+ if((res = s_mp_mul_2(&gx)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ mp_copy(&xc, &u);
+ mp_copy(&yc, &v);
+ mp_set(&A, 1); mp_set(&D, 1);
+
+ /* Loop through binary GCD algorithm */
+ for(;;) {
+ while(mp_iseven(&u)) {
+ s_mp_div_2(&u);
+
+ if(mp_iseven(&A) && mp_iseven(&B)) {
+ s_mp_div_2(&A); s_mp_div_2(&B);
+ } else {
+ if((res = mp_add(&A, &yc, &A)) != MP_OKAY) goto CLEANUP;
+ s_mp_div_2(&A);
+ if((res = mp_sub(&B, &xc, &B)) != MP_OKAY) goto CLEANUP;
+ s_mp_div_2(&B);
+ }
+ }
+
+ while(mp_iseven(&v)) {
+ s_mp_div_2(&v);
+
+ if(mp_iseven(&C) && mp_iseven(&D)) {
+ s_mp_div_2(&C); s_mp_div_2(&D);
+ } else {
+ if((res = mp_add(&C, &yc, &C)) != MP_OKAY) goto CLEANUP;
+ s_mp_div_2(&C);
+ if((res = mp_sub(&D, &xc, &D)) != MP_OKAY) goto CLEANUP;
+ s_mp_div_2(&D);
+ }
+ }
+
+ if(mp_cmp(&u, &v) >= 0) {
+ if((res = mp_sub(&u, &v, &u)) != MP_OKAY) goto CLEANUP;
+ if((res = mp_sub(&A, &C, &A)) != MP_OKAY) goto CLEANUP;
+ if((res = mp_sub(&B, &D, &B)) != MP_OKAY) goto CLEANUP;
+
+ } else {
+ if((res = mp_sub(&v, &u, &v)) != MP_OKAY) goto CLEANUP;
+ if((res = mp_sub(&C, &A, &C)) != MP_OKAY) goto CLEANUP;
+ if((res = mp_sub(&D, &B, &D)) != MP_OKAY) goto CLEANUP;
+
+ }
+
+ /* If we're done, copy results to output */
+ if(mp_cmp_z(&u) == 0) {
+ if(x)
+ if((res = mp_copy(&C, x)) != MP_OKAY) goto CLEANUP;
+
+ if(y)
+ if((res = mp_copy(&D, y)) != MP_OKAY) goto CLEANUP;
+
+ if(g)
+ if((res = mp_mul(&gx, &v, g)) != MP_OKAY) goto CLEANUP;
+
+ break;
+ }
+ }
+
+ CLEANUP:
+ while(last >= 0)
+ mp_clear(clean[last--]);
+
+ return res;
+
+} /* end mp_xgcd() */
+
+/* }}} */
+
+/* {{{ mp_invmod(a, m, c) */
+
+/*
+ mp_invmod(a, m, c)
+
+ Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
+ This is equivalent to the question of whether (a, m) = 1. If not,
+ MP_UNDEF is returned, and there is no inverse.
+ */
+
+mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c)
+{
+ mp_int g, x;
+ mp_err res;
+
+ ARGCHK(a && m && c, MP_BADARG);
+
+ if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
+ return MP_RANGE;
+
+ if((res = mp_init(&g)) != MP_OKAY)
+ return res;
+ if((res = mp_init(&x)) != MP_OKAY)
+ goto X;
+
+ if((res = mp_xgcd(a, m, &g, &x, NULL)) != MP_OKAY)
+ goto CLEANUP;
+
+ if(mp_cmp_d(&g, 1) != MP_EQ) {
+ res = MP_UNDEF;
+ goto CLEANUP;
+ }
+
+ res = mp_mod(&x, m, c);
+ SIGN(c) = SIGN(a);
+
+CLEANUP:
+ mp_clear(&x);
+X:
+ mp_clear(&g);
+
+ return res;
+
+} /* end mp_invmod() */
+
+/* }}} */
+#endif /* if MP_NUMTH */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ mp_print(mp, ofp) */
+
+#if MP_IOFUNC
+/*
+ mp_print(mp, ofp)
+
+ Print a textual representation of the given mp_int on the output
+ stream 'ofp'. Output is generated using the internal radix.
+ */
+
+void mp_print(mp_int *mp, FILE *ofp)
+{
+ int ix;
+
+ if(mp == NULL || ofp == NULL)
+ return;
+
+ fputc((SIGN(mp) == MP_NEG) ? '-' : '+', ofp);
+
+ for(ix = USED(mp) - 1; ix >= 0; ix--) {
+ fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
+ }
+
+} /* end mp_print() */
+
+#endif /* if MP_IOFUNC */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ More I/O Functions */
+
+/* {{{ mp_read_signed_bin(mp, str, len) */
+
+/*
+ mp_read_signed_bin(mp, str, len)
+
+ Read in a raw value (base 256) into the given mp_int
+ */
+
+mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len)
+{
+ mp_err res;
+
+ ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
+
+ if((res = mp_read_unsigned_bin(mp, str + 1, len - 1)) == MP_OKAY) {
+ /* Get sign from first byte */
+ if(str[0])
+ SIGN(mp) = MP_NEG;
+ else
+ SIGN(mp) = MP_ZPOS;
+ }
+
+ return res;
+
+} /* end mp_read_signed_bin() */
+
+/* }}} */
+
+/* {{{ mp_signed_bin_size(mp) */
+
+int mp_signed_bin_size(mp_int *mp)
+{
+ ARGCHK(mp != NULL, 0);
+
+ return mp_unsigned_bin_size(mp) + 1;
+
+} /* end mp_signed_bin_size() */
+
+/* }}} */
+
+/* {{{ mp_to_signed_bin(mp, str) */
+
+mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str)
+{
+ ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+
+ /* Caller responsible for allocating enough memory (use mp_raw_size(mp)) */
+ str[0] = (char)SIGN(mp);
+
+ return mp_to_unsigned_bin(mp, str + 1);
+
+} /* end mp_to_signed_bin() */
+
+/* }}} */
+
+/* {{{ mp_read_unsigned_bin(mp, str, len) */
+
+/*
+ mp_read_unsigned_bin(mp, str, len)
+
+ Read in an unsigned value (base 256) into the given mp_int
+ */
+
+mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len)
+{
+ int ix;
+ mp_err res;
+
+ ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
+
+ mp_zero(mp);
+
+ for(ix = 0; ix < len; ix++) {
+ if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY)
+ return res;
+
+ if((res = mp_add_d(mp, str[ix], mp)) != MP_OKAY)
+ return res;
+ }
+
+ return MP_OKAY;
+
+} /* end mp_read_unsigned_bin() */
+
+/* }}} */
+
+/* {{{ mp_unsigned_bin_size(mp) */
+
+int mp_unsigned_bin_size(mp_int *mp)
+{
+ mp_digit topdig;
+ int count;
+
+ ARGCHK(mp != NULL, 0);
+
+ /* Special case for the value zero */
+ if(USED(mp) == 1 && DIGIT(mp, 0) == 0)
+ return 1;
+
+ count = (USED(mp) - 1) * sizeof(mp_digit);
+ topdig = DIGIT(mp, USED(mp) - 1);
+
+ while(topdig != 0) {
+ ++count;
+ topdig >>= CHAR_BIT;
+ }
+
+ return count;
+
+} /* end mp_unsigned_bin_size() */
+
+/* }}} */
+
+/* {{{ mp_to_unsigned_bin(mp, str) */
+
+mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str)
+{
+ mp_digit *dp, *end, d;
+ unsigned char *spos;
+
+ ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+
+ dp = DIGITS(mp);
+ end = dp + USED(mp) - 1;
+ spos = str;
+
+ /* Special case for zero, quick test */
+ if(dp == end && *dp == 0) {
+ *str = '\0';
+ return MP_OKAY;
+ }
+
+ /* Generate digits in reverse order */
+ while(dp < end) {
+ int ix;
+
+ d = *dp;
+ for(ix = 0; ix < sizeof(mp_digit); ++ix) {
+ *spos = d & UCHAR_MAX;
+ d >>= CHAR_BIT;
+ ++spos;
+ }
+
+ ++dp;
+ }
+
+ /* Now handle last digit specially, high order zeroes are not written */
+ d = *end;
+ while(d != 0) {
+ *spos = d & UCHAR_MAX;
+ d >>= CHAR_BIT;
+ ++spos;
+ }
+
+ /* Reverse everything to get digits in the correct order */
+ while(--spos > str) {
+ unsigned char t = *str;
+ *str = *spos;
+ *spos = t;
+
+ ++str;
+ }
+
+ return MP_OKAY;
+
+} /* end mp_to_unsigned_bin() */
+
+/* }}} */
+
+/* {{{ mp_count_bits(mp) */
+
+int mp_count_bits(mp_int *mp)
+{
+ int len;
+ mp_digit d;
+
+ ARGCHK(mp != NULL, MP_BADARG);
+
+ len = DIGIT_BIT * (USED(mp) - 1);
+ d = DIGIT(mp, USED(mp) - 1);
+
+ while(d != 0) {
+ ++len;
+ d >>= 1;
+ }
+
+ return len;
+
+} /* end mp_count_bits() */
+
+/* }}} */
+
+/* {{{ mp_read_radix(mp, str, radix) */
+
+/*
+ mp_read_radix(mp, str, radix)
+
+ Read an integer from the given string, and set mp to the resulting
+ value. The input is presumed to be in base 10. Leading non-digit
+ characters are ignored, and the function reads until a non-digit
+ character or the end of the string.
+ */
+
+mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix)
+{
+ int ix = 0, val = 0;
+ mp_err res;
+ mp_sign sig = MP_ZPOS;
+
+ ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
+ MP_BADARG);
+
+ mp_zero(mp);
+
+ /* Skip leading non-digit characters until a digit or '-' or '+' */
+ while(str[ix] &&
+ (s_mp_tovalue(str[ix], radix) < 0) &&
+ str[ix] != '-' &&
+ str[ix] != '+') {
+ ++ix;
+ }
+
+ if(str[ix] == '-') {
+ sig = MP_NEG;
+ ++ix;
+ } else if(str[ix] == '+') {
+ sig = MP_ZPOS; /* this is the default anyway... */
+ ++ix;
+ }
+
+ while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
+ if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
+ return res;
+ if((res = s_mp_add_d(mp, val)) != MP_OKAY)
+ return res;
+ ++ix;
+ }
+
+ if(s_mp_cmp_d(mp, 0) == MP_EQ)
+ SIGN(mp) = MP_ZPOS;
+ else
+ SIGN(mp) = sig;
+
+ return MP_OKAY;
+
+} /* end mp_read_radix() */
+
+/* }}} */
+
+/* {{{ mp_radix_size(mp, radix) */
+
+int mp_radix_size(mp_int *mp, int radix)
+{
+ int len;
+ ARGCHK(mp != NULL, 0);
+
+ len = s_mp_outlen(mp_count_bits(mp), radix) + 1; /* for NUL terminator */
+
+ if(mp_cmp_z(mp) < 0)
+ ++len; /* for sign */
+
+ return len;
+
+} /* end mp_radix_size() */
+
+/* }}} */
+
+/* {{{ mp_value_radix_size(num, qty, radix) */
+
+/* num = number of digits
+ qty = number of bits per digit
+ radix = target base
+
+ Return the number of digits in the specified radix that would be
+ needed to express 'num' digits of 'qty' bits each.
+ */
+int mp_value_radix_size(int num, int qty, int radix)
+{
+ ARGCHK(num >= 0 && qty > 0 && radix >= 2 && radix <= MAX_RADIX, 0);
+
+ return s_mp_outlen(num * qty, radix);
+
+} /* end mp_value_radix_size() */
+
+/* }}} */
+
+/* {{{ mp_toradix(mp, str, radix) */
+
+mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix)
+{
+ int ix, pos = 0;
+
+ ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+ ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
+
+ if(mp_cmp_z(mp) == MP_EQ) {
+ str[0] = '0';
+ str[1] = '\0';
+ } else {
+ mp_err res;
+ mp_int tmp;
+ mp_sign sgn;
+ mp_digit rem, rdx = (mp_digit)radix;
+ char ch;
+
+ if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
+ return res;
+
+ /* Save sign for later, and take absolute value */
+ sgn = SIGN(&tmp); SIGN(&tmp) = MP_ZPOS;
+
+ /* Generate output digits in reverse order */
+ while(mp_cmp_z(&tmp) != 0) {
+ if((res = s_mp_div_d(&tmp, rdx, &rem)) != MP_OKAY) {
+ mp_clear(&tmp);
+ return res;
+ }
+
+ /* Generate digits, use capital letters */
+ ch = s_mp_todigit(rem, radix, 0);
+
+ str[pos++] = ch;
+ }
+
+ /* Add - sign if original value was negative */
+ if(sgn == MP_NEG)
+ str[pos++] = '-';
+
+ /* Add trailing NUL to end the string */
+ str[pos--] = '\0';
+
+ /* Reverse the digits and sign indicator */
+ ix = 0;
+ while(ix < pos) {
+ char tmp = str[ix];
+
+ str[ix] = str[pos];
+ str[pos] = tmp;
+ ++ix;
+ --pos;
+ }
+
+ mp_clear(&tmp);
+ }
+
+ return MP_OKAY;
+
+} /* end mp_toradix() */
+
+/* }}} */
+
+/* {{{ mp_char2value(ch, r) */
+
+int mp_char2value(char ch, int r)
+{
+ return s_mp_tovalue(ch, r);
+
+} /* end mp_tovalue() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ mp_strerror(ec) */
+
+/*
+ mp_strerror(ec)
+
+ Return a string describing the meaning of error code 'ec'. The
+ string returned is allocated in static memory, so the caller should
+ not attempt to modify or free the memory associated with this
+ string.
+ */
+const char *mp_strerror(mp_err ec)
+{
+ int aec = (ec < 0) ? -ec : ec;
+
+ /* Code values are negative, so the senses of these comparisons
+ are accurate */
+ if(ec < MP_LAST_CODE || ec > MP_OKAY) {
+ return mp_err_string[0]; /* unknown error code */
+ } else {
+ return mp_err_string[aec + 1];
+ }
+
+} /* end mp_strerror() */
+
+/* }}} */
+
+/*========================================================================*/
+/*------------------------------------------------------------------------*/
+/* Static function definitions (internal use only) */
+
+/* {{{ Memory management */
+
+/* {{{ s_mp_grow(mp, min) */
+
+/* Make sure there are at least 'min' digits allocated to mp */
+mp_err s_mp_grow(mp_int *mp, mp_size min)
+{
+ if(min > ALLOC(mp)) {
+ mp_digit *tmp;
+
+ /* Set min to next nearest default precision block size */
+ min = ((min + (s_mp_defprec - 1)) / s_mp_defprec) * s_mp_defprec;
+
+ if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL)
+ return MP_MEM;
+
+ s_mp_copy(DIGITS(mp), tmp, USED(mp));
+
+#if MP_CRYPTO
+ s_mp_setz(DIGITS(mp), ALLOC(mp));
+#endif
+ s_mp_free(DIGITS(mp));
+ DIGITS(mp) = tmp;
+ ALLOC(mp) = min;
+ }
+
+ return MP_OKAY;
+
+} /* end s_mp_grow() */
+
+/* }}} */
+
+/* {{{ s_mp_pad(mp, min) */
+
+/* Make sure the used size of mp is at least 'min', growing if needed */
+mp_err s_mp_pad(mp_int *mp, mp_size min)
+{
+ if(min > USED(mp)) {
+ mp_err res;
+
+ /* Make sure there is room to increase precision */
+ if(min > ALLOC(mp) && (res = s_mp_grow(mp, min)) != MP_OKAY)
+ return res;
+
+ /* Increase precision; should already be 0-filled */
+ USED(mp) = min;
+ }
+
+ return MP_OKAY;
+
+} /* end s_mp_pad() */
+
+/* }}} */
+
+/* {{{ s_mp_setz(dp, count) */
+
+#if MP_MACRO == 0
+/* Set 'count' digits pointed to by dp to be zeroes */
+void s_mp_setz(mp_digit *dp, mp_size count)
+{
+#if MP_MEMSET == 0
+ int ix;
+
+ for(ix = 0; ix < count; ix++)
+ dp[ix] = 0;
+#else
+ memset(dp, 0, count * sizeof(mp_digit));
+#endif
+
+} /* end s_mp_setz() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_copy(sp, dp, count) */
+
+#if MP_MACRO == 0
+/* Copy 'count' digits from sp to dp */
+void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count)
+{
+#if MP_MEMCPY == 0
+ int ix;
+
+ for(ix = 0; ix < count; ix++)
+ dp[ix] = sp[ix];
+#else
+ memcpy(dp, sp, count * sizeof(mp_digit));
+#endif
+
+} /* end s_mp_copy() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_alloc(nb, ni) */
+
+#if MP_MACRO == 0
+/* Allocate ni records of nb bytes each, and return a pointer to that */
+void *s_mp_alloc(size_t nb, size_t ni)
+{
+ return calloc(nb, ni);
+
+} /* end s_mp_alloc() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_free(ptr) */
+
+#if MP_MACRO == 0
+/* Free the memory pointed to by ptr */
+void s_mp_free(void *ptr)
+{
+ if(ptr)
+ free(ptr);
+
+} /* end s_mp_free() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_clamp(mp) */
+
+/* Remove leading zeroes from the given value */
+void s_mp_clamp(mp_int *mp)
+{
+ mp_size du = USED(mp);
+ mp_digit *zp = DIGITS(mp) + du - 1;
+
+ while(du > 1 && !*zp--)
+ --du;
+
+ USED(mp) = du;
+
+} /* end s_mp_clamp() */
+
+
+/* }}} */
+
+/* {{{ s_mp_exch(a, b) */
+
+/* Exchange the data for a and b; (b, a) = (a, b) */
+void s_mp_exch(mp_int *a, mp_int *b)
+{
+ mp_int tmp;
+
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+
+} /* end s_mp_exch() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Arithmetic helpers */
+
+/* {{{ s_mp_lshd(mp, p) */
+
+/*
+ Shift mp leftward by p digits, growing if needed, and zero-filling
+ the in-shifted digits at the right end. This is a convenient
+ alternative to multiplication by powers of the radix
+ */
+
+mp_err s_mp_lshd(mp_int *mp, mp_size p)
+{
+ mp_err res;
+ mp_size pos;
+ mp_digit *dp;
+ int ix;
+
+ if(p == 0)
+ return MP_OKAY;
+
+ if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
+ return res;
+
+ pos = USED(mp) - 1;
+ dp = DIGITS(mp);
+
+ /* Shift all the significant figures over as needed */
+ for(ix = pos - p; ix >= 0; ix--)
+ dp[ix + p] = dp[ix];
+
+ /* Fill the bottom digits with zeroes */
+ for(ix = 0; ix < p; ix++)
+ dp[ix] = 0;
+
+ return MP_OKAY;
+
+} /* end s_mp_lshd() */
+
+/* }}} */
+
+/* {{{ s_mp_rshd(mp, p) */
+
+/*
+ Shift mp rightward by p digits. Maintains the invariant that
+ digits above the precision are all zero. Digits shifted off the
+ end are lost. Cannot fail.
+ */
+
+void s_mp_rshd(mp_int *mp, mp_size p)
+{
+ mp_size ix;
+ mp_digit *dp;
+
+ if(p == 0)
+ return;
+
+ /* Shortcut when all digits are to be shifted off */
+ if(p >= USED(mp)) {
+ s_mp_setz(DIGITS(mp), ALLOC(mp));
+ USED(mp) = 1;
+ SIGN(mp) = MP_ZPOS;
+ return;
+ }
+
+ /* Shift all the significant figures over as needed */
+ dp = DIGITS(mp);
+ for(ix = p; ix < USED(mp); ix++)
+ dp[ix - p] = dp[ix];
+
+ /* Fill the top digits with zeroes */
+ ix -= p;
+ while(ix < USED(mp))
+ dp[ix++] = 0;
+
+ /* Strip off any leading zeroes */
+ s_mp_clamp(mp);
+
+} /* end s_mp_rshd() */
+
+/* }}} */
+
+/* {{{ s_mp_div_2(mp) */
+
+/* Divide by two -- take advantage of radix properties to do it fast */
+void s_mp_div_2(mp_int *mp)
+{
+ s_mp_div_2d(mp, 1);
+
+} /* end s_mp_div_2() */
+
+/* }}} */
+
+/* {{{ s_mp_mul_2(mp) */
+
+mp_err s_mp_mul_2(mp_int *mp)
+{
+ int ix;
+ mp_digit kin = 0, kout, *dp = DIGITS(mp);
+ mp_err res;
+
+ /* Shift digits leftward by 1 bit */
+ for(ix = 0; ix < USED(mp); ix++) {
+ kout = (dp[ix] >> (DIGIT_BIT - 1)) & 1;
+ dp[ix] = (dp[ix] << 1) | kin;
+
+ kin = kout;
+ }
+
+ /* Deal with rollover from last digit */
+ if(kin) {
+ if(ix >= ALLOC(mp)) {
+ if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
+ return res;
+ dp = DIGITS(mp);
+ }
+
+ dp[ix] = kin;
+ USED(mp) += 1;
+ }
+
+ return MP_OKAY;
+
+} /* end s_mp_mul_2() */
+
+/* }}} */
+
+/* {{{ s_mp_mod_2d(mp, d) */
+
+/*
+ Remainder the integer by 2^d, where d is a number of bits. This
+ amounts to a bitwise AND of the value, and does not require the full
+ division code
+ */
+void s_mp_mod_2d(mp_int *mp, mp_digit d)
+{
+ unsigned int ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
+ unsigned int ix;
+ mp_digit dmask, *dp = DIGITS(mp);
+
+ if(ndig >= USED(mp))
+ return;
+
+ /* Flush all the bits above 2^d in its digit */
+ dmask = (1 << nbit) - 1;
+ dp[ndig] &= dmask;
+
+ /* Flush all digits above the one with 2^d in it */
+ for(ix = ndig + 1; ix < USED(mp); ix++)
+ dp[ix] = 0;
+
+ s_mp_clamp(mp);
+
+} /* end s_mp_mod_2d() */
+
+/* }}} */
+
+/* {{{ s_mp_mul_2d(mp, d) */
+
+/*
+ Multiply by the integer 2^d, where d is a number of bits. This
+ amounts to a bitwise shift of the value, and does not require the
+ full multiplication code.
+ */
+mp_err s_mp_mul_2d(mp_int *mp, mp_digit d)
+{
+ mp_err res;
+ mp_digit save, next, mask, *dp;
+ mp_size used;
+ int ix;
+
+ if((res = s_mp_lshd(mp, d / DIGIT_BIT)) != MP_OKAY)
+ return res;
+
+ dp = DIGITS(mp); used = USED(mp);
+ d %= DIGIT_BIT;
+
+ mask = (1 << d) - 1;
+
+ /* If the shift requires another digit, make sure we've got one to
+ work with */
+ if((dp[used - 1] >> (DIGIT_BIT - d)) & mask) {
+ if((res = s_mp_grow(mp, used + 1)) != MP_OKAY)
+ return res;
+ dp = DIGITS(mp);
+ }
+
+ /* Do the shifting... */
+ save = 0;
+ for(ix = 0; ix < used; ix++) {
+ next = (dp[ix] >> (DIGIT_BIT - d)) & mask;
+ dp[ix] = (dp[ix] << d) | save;
+ save = next;
+ }
+
+ /* If, at this point, we have a nonzero carryout into the next
+ digit, we'll increase the size by one digit, and store it...
+ */
+ if(save) {
+ dp[used] = save;
+ USED(mp) += 1;
+ }
+
+ s_mp_clamp(mp);
+ return MP_OKAY;
+
+} /* end s_mp_mul_2d() */
+
+/* }}} */
+
+/* {{{ s_mp_div_2d(mp, d) */
+
+/*
+ Divide the integer by 2^d, where d is a number of bits. This
+ amounts to a bitwise shift of the value, and does not require the
+ full division code (used in Barrett reduction, see below)
+ */
+void s_mp_div_2d(mp_int *mp, mp_digit d)
+{
+ int ix;
+ mp_digit save, next, mask, *dp = DIGITS(mp);
+
+ s_mp_rshd(mp, d / DIGIT_BIT);
+ d %= DIGIT_BIT;
+
+ mask = (1 << d) - 1;
+
+ save = 0;
+ for(ix = USED(mp) - 1; ix >= 0; ix--) {
+ next = dp[ix] & mask;
+ dp[ix] = (dp[ix] >> d) | (save << (DIGIT_BIT - d));
+ save = next;
+ }
+
+ s_mp_clamp(mp);
+
+} /* end s_mp_div_2d() */
+
+/* }}} */
+
+/* {{{ s_mp_norm(a, b) */
+
+/*
+ s_mp_norm(a, b)
+
+ Normalize a and b for division, where b is the divisor. In order
+ that we might make good guesses for quotient digits, we want the
+ leading digit of b to be at least half the radix, which we
+ accomplish by multiplying a and b by a constant. This constant is
+ returned (so that it can be divided back out of the remainder at the
+ end of the division process).
+
+ We multiply by the smallest power of 2 that gives us a leading digit
+ at least half the radix. By choosing a power of 2, we simplify the
+ multiplication and division steps to simple shifts.
+ */
+mp_digit s_mp_norm(mp_int *a, mp_int *b)
+{
+ mp_digit t, d = 0;
+
+ t = DIGIT(b, USED(b) - 1);
+ while(t < (RADIX / 2)) {
+ t <<= 1;
+ ++d;
+ }
+
+ if(d != 0) {
+ s_mp_mul_2d(a, d);
+ s_mp_mul_2d(b, d);
+ }
+
+ return d;
+
+} /* end s_mp_norm() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive digit arithmetic */
+
+/* {{{ s_mp_add_d(mp, d) */
+
+/* Add d to |mp| in place */
+mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */
+{
+ mp_word w, k = 0;
+ mp_size ix = 1, used = USED(mp);
+ mp_digit *dp = DIGITS(mp);
+
+ w = dp[0] + d;
+ dp[0] = ACCUM(w);
+ k = CARRYOUT(w);
+
+ while(ix < used && k) {
+ w = dp[ix] + k;
+ dp[ix] = ACCUM(w);
+ k = CARRYOUT(w);
+ ++ix;
+ }
+
+ if(k != 0) {
+ mp_err res;
+
+ if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
+ return res;
+
+ DIGIT(mp, ix) = k;
+ }
+
+ return MP_OKAY;
+
+} /* end s_mp_add_d() */
+
+/* }}} */
+
+/* {{{ s_mp_sub_d(mp, d) */
+
+/* Subtract d from |mp| in place, assumes |mp| > d */
+mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */
+{
+ mp_word w, b = 0;
+ mp_size ix = 1, used = USED(mp);
+ mp_digit *dp = DIGITS(mp);
+
+ /* Compute initial subtraction */
+ w = (RADIX + dp[0]) - d;
+ b = CARRYOUT(w) ? 0 : 1;
+ dp[0] = ACCUM(w);
+
+ /* Propagate borrows leftward */
+ while(b && ix < used) {
+ w = (RADIX + dp[ix]) - b;
+ b = CARRYOUT(w) ? 0 : 1;
+ dp[ix] = ACCUM(w);
+ ++ix;
+ }
+
+ /* Remove leading zeroes */
+ s_mp_clamp(mp);
+
+ /* If we have a borrow out, it's a violation of the input invariant */
+ if(b)
+ return MP_RANGE;
+ else
+ return MP_OKAY;
+
+} /* end s_mp_sub_d() */
+
+/* }}} */
+
+/* {{{ s_mp_mul_d(a, d) */
+
+/* Compute a = a * d, single digit multiplication */
+mp_err s_mp_mul_d(mp_int *a, mp_digit d)
+{
+ mp_word w, k = 0;
+ mp_size ix, max;
+ mp_err res;
+ mp_digit *dp = DIGITS(a);
+
+ /*
+ Single-digit multiplication will increase the precision of the
+ output by at most one digit. However, we can detect when this
+ will happen -- if the high-order digit of a, times d, gives a
+ two-digit result, then the precision of the result will increase;
+ otherwise it won't. We use this fact to avoid calling s_mp_pad()
+ unless absolutely necessary.
+ */
+ max = USED(a);
+ w = dp[max - 1] * d;
+ if(CARRYOUT(w) != 0) {
+ if((res = s_mp_pad(a, max + 1)) != MP_OKAY)
+ return res;
+ dp = DIGITS(a);
+ }
+
+ for(ix = 0; ix < max; ix++) {
+ w = (dp[ix] * d) + k;
+ dp[ix] = ACCUM(w);
+ k = CARRYOUT(w);
+ }
+
+ /* If there is a precision increase, take care of it here; the above
+ test guarantees we have enough storage to do this safely.
+ */
+ if(k) {
+ dp[max] = k;
+ USED(a) = max + 1;
+ }
+
+ s_mp_clamp(a);
+
+ return MP_OKAY;
+
+} /* end s_mp_mul_d() */
+
+/* }}} */
+
+/* {{{ s_mp_div_d(mp, d, r) */
+
+/*
+ s_mp_div_d(mp, d, r)
+
+ Compute the quotient mp = mp / d and remainder r = mp mod d, for a
+ single digit d. If r is null, the remainder will be discarded.
+ */
+
+mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
+{
+ mp_word w = 0, t;
+ mp_int quot;
+ mp_err res;
+ mp_digit *dp = DIGITS(mp), *qp;
+ int ix;
+
+ if(d == 0)
+ return MP_RANGE;
+
+ /* Make room for the quotient */
+ if((res = mp_init_size(&quot, USED(mp))) != MP_OKAY)
+ return res;
+
+ USED(&quot) = USED(mp); /* so clamping will work below */
+ qp = DIGITS(&quot);
+
+ /* Divide without subtraction */
+ for(ix = USED(mp) - 1; ix >= 0; ix--) {
+ w = (w << DIGIT_BIT) | dp[ix];
+
+ if(w >= d) {
+ t = w / d;
+ w = w % d;
+ } else {
+ t = 0;
+ }
+
+ qp[ix] = t;
+ }
+
+ /* Deliver the remainder, if desired */
+ if(r)
+ *r = w;
+
+ s_mp_clamp(&quot);
+ mp_exch(&quot, mp);
+ mp_clear(&quot);
+
+ return MP_OKAY;
+
+} /* end s_mp_div_d() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive full arithmetic */
+
+/* {{{ s_mp_add(a, b) */
+
+/* Compute a = |a| + |b| */
+mp_err s_mp_add(mp_int *a, mp_int *b) /* magnitude addition */
+{
+ mp_word w = 0;
+ mp_digit *pa, *pb;
+ mp_size ix, used = USED(b);
+ mp_err res;
+
+ /* Make sure a has enough precision for the output value */
+ if((used > USED(a)) && (res = s_mp_pad(a, used)) != MP_OKAY)
+ return res;
+
+ /*
+ Add up all digits up to the precision of b. If b had initially
+ the same precision as a, or greater, we took care of it by the
+ padding step above, so there is no problem. If b had initially
+ less precision, we'll have to make sure the carry out is duly
+ propagated upward among the higher-order digits of the sum.
+ */
+ pa = DIGITS(a);
+ pb = DIGITS(b);
+ for(ix = 0; ix < used; ++ix) {
+ w += *pa + *pb++;
+ *pa++ = ACCUM(w);
+ w = CARRYOUT(w);
+ }
+
+ /* If we run out of 'b' digits before we're actually done, make
+ sure the carries get propagated upward...
+ */
+ used = USED(a);
+ while(w && ix < used) {
+ w += *pa;
+ *pa++ = ACCUM(w);
+ w = CARRYOUT(w);
+ ++ix;
+ }
+
+ /* If there's an overall carry out, increase precision and include
+ it. We could have done this initially, but why touch the memory
+ allocator unless we're sure we have to?
+ */
+ if(w) {
+ if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
+ return res;
+
+ DIGIT(a, ix) = w; /* pa may not be valid after s_mp_pad() call */
+ }
+
+ return MP_OKAY;
+
+} /* end s_mp_add() */
+
+/* }}} */
+
+/* {{{ s_mp_sub(a, b) */
+
+/* Compute a = |a| - |b|, assumes |a| >= |b| */
+mp_err s_mp_sub(mp_int *a, mp_int *b) /* magnitude subtract */
+{
+ mp_word w = 0;
+ mp_digit *pa, *pb;
+ mp_size ix, used = USED(b);
+
+ /*
+ Subtract and propagate borrow. Up to the precision of b, this
+ accounts for the digits of b; after that, we just make sure the
+ carries get to the right place. This saves having to pad b out to
+ the precision of a just to make the loops work right...
+ */
+ pa = DIGITS(a);
+ pb = DIGITS(b);
+
+ for(ix = 0; ix < used; ++ix) {
+ w = (RADIX + *pa) - w - *pb++;
+ *pa++ = ACCUM(w);
+ w = CARRYOUT(w) ? 0 : 1;
+ }
+
+ used = USED(a);
+ while(ix < used) {
+ w = RADIX + *pa - w;
+ *pa++ = ACCUM(w);
+ w = CARRYOUT(w) ? 0 : 1;
+ ++ix;
+ }
+
+ /* Clobber any leading zeroes we created */
+ s_mp_clamp(a);
+
+ /*
+ If there was a borrow out, then |b| > |a| in violation
+ of our input invariant. We've already done the work,
+ but we'll at least complain about it...
+ */
+ if(w)
+ return MP_RANGE;
+ else
+ return MP_OKAY;
+
+} /* end s_mp_sub() */
+
+/* }}} */
+
+mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu)
+{
+ mp_int q;
+ mp_err res;
+ mp_size um = USED(m);
+
+ if((res = mp_init_copy(&q, x)) != MP_OKAY)
+ return res;
+
+ s_mp_rshd(&q, um - 1); /* q1 = x / b^(k-1) */
+ s_mp_mul(&q, mu); /* q2 = q1 * mu */
+ s_mp_rshd(&q, um + 1); /* q3 = q2 / b^(k+1) */
+
+ /* x = x mod b^(k+1), quick (no division) */
+ s_mp_mod_2d(x, (mp_digit)(DIGIT_BIT * (um + 1)));
+
+ /* q = q * m mod b^(k+1), quick (no division), uses the short multiplier */
+#ifndef SHRT_MUL
+ s_mp_mul(&q, m);
+ s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1)));
+#else
+ s_mp_mul_dig(&q, m, um + 1);
+#endif
+
+ /* x = x - q */
+ if((res = mp_sub(x, &q, x)) != MP_OKAY)
+ goto CLEANUP;
+
+ /* If x < 0, add b^(k+1) to it */
+ if(mp_cmp_z(x) < 0) {
+ mp_set(&q, 1);
+ if((res = s_mp_lshd(&q, um + 1)) != MP_OKAY)
+ goto CLEANUP;
+ if((res = mp_add(x, &q, x)) != MP_OKAY)
+ goto CLEANUP;
+ }
+
+ /* Back off if it's too big */
+ while(mp_cmp(x, m) >= 0) {
+ if((res = s_mp_sub(x, m)) != MP_OKAY)
+ break;
+ }
+
+ CLEANUP:
+ mp_clear(&q);
+
+ return res;
+
+} /* end s_mp_reduce() */
+
+
+
+/* {{{ s_mp_mul(a, b) */
+
+/* Compute a = |a| * |b| */
+mp_err s_mp_mul(mp_int *a, mp_int *b)
+{
+ mp_word w, k = 0;
+ mp_int tmp;
+ mp_err res;
+ mp_size ix, jx, ua = USED(a), ub = USED(b);
+ mp_digit *pa, *pb, *pt, *pbt;
+
+ if((res = mp_init_size(&tmp, ua + ub)) != MP_OKAY)
+ return res;
+
+ /* This has the effect of left-padding with zeroes... */
+ USED(&tmp) = ua + ub;
+
+ /* We're going to need the base value each iteration */
+ pbt = DIGITS(&tmp);
+
+ /* Outer loop: Digits of b */
+
+ pb = DIGITS(b);
+ for(ix = 0; ix < ub; ++ix, ++pb) {
+ if(*pb == 0)
+ continue;
+
+ /* Inner product: Digits of a */
+ pa = DIGITS(a);
+ for(jx = 0; jx < ua; ++jx, ++pa) {
+ pt = pbt + ix + jx;
+ w = *pb * *pa + k + *pt;
+ *pt = ACCUM(w);
+ k = CARRYOUT(w);
+ }
+
+ pbt[ix + jx] = k;
+ k = 0;
+ }
+
+ s_mp_clamp(&tmp);
+ s_mp_exch(&tmp, a);
+
+ mp_clear(&tmp);
+
+ return MP_OKAY;
+
+} /* end s_mp_mul() */
+
+/* }}} */
+
+/* {{{ s_mp_kmul(a, b, out, len) */
+
+#if 0
+void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len)
+{
+ mp_word w, k = 0;
+ mp_size ix, jx;
+ mp_digit *pa, *pt;
+
+ for(ix = 0; ix < len; ++ix, ++b) {
+ if(*b == 0)
+ continue;
+
+ pa = a;
+ for(jx = 0; jx < len; ++jx, ++pa) {
+ pt = out + ix + jx;
+ w = *b * *pa + k + *pt;
+ *pt = ACCUM(w);
+ k = CARRYOUT(w);
+ }
+
+ out[ix + jx] = k;
+ k = 0;
+ }
+
+} /* end s_mp_kmul() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_sqr(a) */
+
+/*
+ Computes the square of a, in place. This can be done more
+ efficiently than a general multiplication, because many of the
+ computation steps are redundant when squaring. The inner product
+ step is a bit more complicated, but we save a fair number of
+ iterations of the multiplication loop.
+ */
+#if MP_SQUARE
+mp_err s_mp_sqr(mp_int *a)
+{
+ mp_word w, k = 0;
+ mp_int tmp;
+ mp_err res;
+ mp_size ix, jx, kx, used = USED(a);
+ mp_digit *pa1, *pa2, *pt, *pbt;
+
+ if((res = mp_init_size(&tmp, 2 * used)) != MP_OKAY)
+ return res;
+
+ /* Left-pad with zeroes */
+ USED(&tmp) = 2 * used;
+
+ /* We need the base value each time through the loop */
+ pbt = DIGITS(&tmp);
+
+ pa1 = DIGITS(a);
+ for(ix = 0; ix < used; ++ix, ++pa1) {
+ if(*pa1 == 0)
+ continue;
+
+ w = DIGIT(&tmp, ix + ix) + (*pa1 * *pa1);
+
+ pbt[ix + ix] = ACCUM(w);
+ k = CARRYOUT(w);
+
+ /*
+ The inner product is computed as:
+
+ (C, S) = t[i,j] + 2 a[i] a[j] + C
+
+ This can overflow what can be represented in an mp_word, and
+ since C arithmetic does not provide any way to check for
+ overflow, we have to check explicitly for overflow conditions
+ before they happen.
+ */
+ for(jx = ix + 1, pa2 = DIGITS(a) + jx; jx < used; ++jx, ++pa2) {
+ mp_word u = 0, v;
+
+ /* Store this in a temporary to avoid indirections later */
+ pt = pbt + ix + jx;
+
+ /* Compute the multiplicative step */
+ w = *pa1 * *pa2;
+
+ /* If w is more than half MP_WORD_MAX, the doubling will
+ overflow, and we need to record a carry out into the next
+ word */
+ u = (w >> (MP_WORD_BIT - 1)) & 1;
+
+ /* Double what we've got, overflow will be ignored as defined
+ for C arithmetic (we've already noted if it is to occur)
+ */
+ w *= 2;
+
+ /* Compute the additive step */
+ v = *pt + k;
+
+ /* If we do not already have an overflow carry, check to see
+ if the addition will cause one, and set the carry out if so
+ */
+ u |= ((MP_WORD_MAX - v) < w);
+
+ /* Add in the rest, again ignoring overflow */
+ w += v;
+
+ /* Set the i,j digit of the output */
+ *pt = ACCUM(w);
+
+ /* Save carry information for the next iteration of the loop.
+ This is why k must be an mp_word, instead of an mp_digit */
+ k = CARRYOUT(w) | (u << DIGIT_BIT);
+
+ } /* for(jx ...) */
+
+ /* Set the last digit in the cycle and reset the carry */
+ k = DIGIT(&tmp, ix + jx) + k;
+ pbt[ix + jx] = ACCUM(k);
+ k = CARRYOUT(k);
+
+ /* If we are carrying out, propagate the carry to the next digit
+ in the output. This may cascade, so we have to be somewhat
+ circumspect -- but we will have enough precision in the output
+ that we won't overflow
+ */
+ kx = 1;
+ while(k) {
+ k = pbt[ix + jx + kx] + 1;
+ pbt[ix + jx + kx] = ACCUM(k);
+ k = CARRYOUT(k);
+ ++kx;
+ }
+ } /* for(ix ...) */
+
+ s_mp_clamp(&tmp);
+ s_mp_exch(&tmp, a);
+
+ mp_clear(&tmp);
+
+ return MP_OKAY;
+
+} /* end s_mp_sqr() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_div(a, b) */
+
+/*
+ s_mp_div(a, b)
+
+ Compute a = a / b and b = a mod b. Assumes b > a.
+ */
+
+mp_err s_mp_div(mp_int *a, mp_int *b)
+{
+ mp_int quot, rem, t;
+ mp_word q;
+ mp_err res;
+ mp_digit d;
+ int ix;
+
+ if(mp_cmp_z(b) == 0)
+ return MP_RANGE;
+
+ /* Shortcut if b is power of two */
+ if((ix = s_mp_ispow2(b)) >= 0) {
+ mp_copy(a, b); /* need this for remainder */
+ s_mp_div_2d(a, (mp_digit)ix);
+ s_mp_mod_2d(b, (mp_digit)ix);
+
+ return MP_OKAY;
+ }
+
+ /* Allocate space to store the quotient */
+ if((res = mp_init_size(&quot, USED(a))) != MP_OKAY)
+ return res;
+
+ /* A working temporary for division */
+ if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
+ goto T;
+
+ /* Allocate space for the remainder */
+ if((res = mp_init_size(&rem, USED(a))) != MP_OKAY)
+ goto REM;
+
+ /* Normalize to optimize guessing */
+ d = s_mp_norm(a, b);
+
+ /* Perform the division itself...woo! */
+ ix = USED(a) - 1;
+
+ while(ix >= 0) {
+ /* Find a partial substring of a which is at least b */
+ while(s_mp_cmp(&rem, b) < 0 && ix >= 0) {
+ if((res = s_mp_lshd(&rem, 1)) != MP_OKAY)
+ goto CLEANUP;
+
+ if((res = s_mp_lshd(&quot, 1)) != MP_OKAY)
+ goto CLEANUP;
+
+ DIGIT(&rem, 0) = DIGIT(a, ix);
+ s_mp_clamp(&rem);
+ --ix;
+ }
+
+ /* If we didn't find one, we're finished dividing */
+ if(s_mp_cmp(&rem, b) < 0)
+ break;
+
+ /* Compute a guess for the next quotient digit */
+ q = DIGIT(&rem, USED(&rem) - 1);
+ if(q <= DIGIT(b, USED(b) - 1) && USED(&rem) > 1)
+ q = (q << DIGIT_BIT) | DIGIT(&rem, USED(&rem) - 2);
+
+ q /= DIGIT(b, USED(b) - 1);
+
+ /* The guess can be as much as RADIX + 1 */
+ if(q >= RADIX)
+ q = RADIX - 1;
+
+ /* See what that multiplies out to */
+ mp_copy(b, &t);
+ if((res = s_mp_mul_d(&t, q)) != MP_OKAY)
+ goto CLEANUP;
+
+ /*
+ If it's too big, back it off. We should not have to do this
+ more than once, or, in rare cases, twice. Knuth describes a
+ method by which this could be reduced to a maximum of once, but
+ I didn't implement that here.
+ */
+ while(s_mp_cmp(&t, &rem) > 0) {
+ --q;
+ s_mp_sub(&t, b);
+ }
+
+ /* At this point, q should be the right next digit */
+ if((res = s_mp_sub(&rem, &t)) != MP_OKAY)
+ goto CLEANUP;
+
+ /*
+ Include the digit in the quotient. We allocated enough memory
+ for any quotient we could ever possibly get, so we should not
+ have to check for failures here
+ */
+ DIGIT(&quot, 0) = q;
+ }
+
+ /* Denormalize remainder */
+ if(d != 0)
+ s_mp_div_2d(&rem, d);
+
+ s_mp_clamp(&quot);
+ s_mp_clamp(&rem);
+
+ /* Copy quotient back to output */
+ s_mp_exch(&quot, a);
+
+ /* Copy remainder back to output */
+ s_mp_exch(&rem, b);
+
+CLEANUP:
+ mp_clear(&rem);
+REM:
+ mp_clear(&t);
+T:
+ mp_clear(&quot);
+
+ return res;
+
+} /* end s_mp_div() */
+
+/* }}} */
+
+/* {{{ s_mp_2expt(a, k) */
+
+mp_err s_mp_2expt(mp_int *a, mp_digit k)
+{
+ mp_err res;
+ mp_size dig, bit;
+
+ dig = k / DIGIT_BIT;
+ bit = k % DIGIT_BIT;
+
+ mp_zero(a);
+ if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
+ return res;
+
+ DIGIT(a, dig) |= (1 << bit);
+
+ return MP_OKAY;
+
+} /* end s_mp_2expt() */
+
+/* }}} */
+
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive comparisons */
+
+/* {{{ s_mp_cmp(a, b) */
+
+/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b */
+int s_mp_cmp(mp_int *a, mp_int *b)
+{
+ mp_size ua = USED(a), ub = USED(b);
+
+ if(ua > ub)
+ return MP_GT;
+ else if(ua < ub)
+ return MP_LT;
+ else {
+ int ix = ua - 1;
+ mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix;
+
+ while(ix >= 0) {
+ if(*ap > *bp)
+ return MP_GT;
+ else if(*ap < *bp)
+ return MP_LT;
+
+ --ap; --bp; --ix;
+ }
+
+ return MP_EQ;
+ }
+
+} /* end s_mp_cmp() */
+
+/* }}} */
+
+/* {{{ s_mp_cmp_d(a, d) */
+
+/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d */
+int s_mp_cmp_d(mp_int *a, mp_digit d)
+{
+ mp_size ua = USED(a);
+ mp_digit *ap = DIGITS(a);
+
+ if(ua > 1)
+ return MP_GT;
+
+ if(*ap < d)
+ return MP_LT;
+ else if(*ap > d)
+ return MP_GT;
+ else
+ return MP_EQ;
+
+} /* end s_mp_cmp_d() */
+
+/* }}} */
+
+/* {{{ s_mp_ispow2(v) */
+
+/*
+ Returns -1 if the value is not a power of two; otherwise, it returns
+ k such that v = 2^k, i.e. lg(v).
+ */
+int s_mp_ispow2(mp_int *v)
+{
+ mp_digit d, *dp;
+ mp_size uv = USED(v);
+ int extra = 0, ix;
+
+ d = DIGIT(v, uv - 1); /* most significant digit of v */
+
+ while(d && ((d & 1) == 0)) {
+ d >>= 1;
+ ++extra;
+ }
+
+ if(d == 1) {
+ ix = uv - 2;
+ dp = DIGITS(v) + ix;
+
+ while(ix >= 0) {
+ if(*dp)
+ return -1; /* not a power of two */
+
+ --dp; --ix;
+ }
+
+ return ((uv - 1) * DIGIT_BIT) + extra;
+ }
+
+ return -1;
+
+} /* end s_mp_ispow2() */
+
+/* }}} */
+
+/* {{{ s_mp_ispow2d(d) */
+
+int s_mp_ispow2d(mp_digit d)
+{
+ int pow = 0;
+
+ while((d & 1) == 0) {
+ ++pow; d >>= 1;
+ }
+
+ if(d == 1)
+ return pow;
+
+ return -1;
+
+} /* end s_mp_ispow2d() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive I/O helpers */
+
+/* {{{ s_mp_tovalue(ch, r) */
+
+/*
+ Convert the given character to its digit value, in the given radix.
+ If the given character is not understood in the given radix, -1 is
+ returned. Otherwise the digit's numeric value is returned.
+
+ The results will be odd if you use a radix < 2 or > 62, you are
+ expected to know what you're up to.
+ */
+int s_mp_tovalue(char ch, int r)
+{
+ int val, xch;
+
+ if(r > 36)
+ xch = ch;
+ else
+ xch = toupper(ch);
+
+ if(isdigit(xch))
+ val = xch - '0';
+ else if(isupper(xch))
+ val = xch - 'A' + 10;
+ else if(islower(xch))
+ val = xch - 'a' + 36;
+ else if(xch == '+')
+ val = 62;
+ else if(xch == '/')
+ val = 63;
+ else
+ return -1;
+
+ if(val < 0 || val >= r)
+ return -1;
+
+ return val;
+
+} /* end s_mp_tovalue() */
+
+/* }}} */
+
+/* {{{ s_mp_todigit(val, r, low) */
+
+/*
+ Convert val to a radix-r digit, if possible. If val is out of range
+ for r, returns zero. Otherwise, returns an ASCII character denoting
+ the value in the given radix.
+
+ The results may be odd if you use a radix < 2 or > 64, you are
+ expected to know what you're doing.
+ */
+
+char s_mp_todigit(int val, int r, int low)
+{
+ char ch;
+
+ if(val < 0 || val >= r)
+ return 0;
+
+ ch = s_dmap_1[val];
+
+ if(r <= 36 && low)
+ ch = tolower(ch);
+
+ return ch;
+
+} /* end s_mp_todigit() */
+
+/* }}} */
+
+/* {{{ s_mp_outlen(bits, radix) */
+
+/*
+ Return an estimate for how long a string is needed to hold a radix
+ r representation of a number with 'bits' significant bits.
+
+ Does not include space for a sign or a NUL terminator.
+ */
+int s_mp_outlen(int bits, int r)
+{
+ return (int)((double)bits * LOG_V_2(r));
+
+} /* end s_mp_outlen() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* HERE THERE BE DRAGONS */
+/* crc==4242132123, version==2, Sat Feb 02 06:43:52 2002 */
+
+/* $Source: /cvs/libtom/libtommath/mtest/mpi.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:38:47 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi.h b/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi.h
new file mode 100644
index 0000000000..66ae873111
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/mtest/mpi.h
@@ -0,0 +1,231 @@
+/*
+ mpi.h
+
+ by Michael J. Fromberger <sting@linguist.dartmouth.edu>
+ Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
+
+ Arbitrary precision integer arithmetic library
+
+ $Id: mpi.h,v 1.2 2005/05/05 14:38:47 tom Exp $
+ */
+
+#ifndef _H_MPI_
+#define _H_MPI_
+
+#include "mpi-config.h"
+
+#define MP_LT -1
+#define MP_EQ 0
+#define MP_GT 1
+
+#if MP_DEBUG
+#undef MP_IOFUNC
+#define MP_IOFUNC 1
+#endif
+
+#if MP_IOFUNC
+#include <stdio.h>
+#include <ctype.h>
+#endif
+
+#include <limits.h>
+
+#define MP_NEG 1
+#define MP_ZPOS 0
+
+/* Included for compatibility... */
+#define NEG MP_NEG
+#define ZPOS MP_ZPOS
+
+#define MP_OKAY 0 /* no error, all is well */
+#define MP_YES 0 /* yes (boolean result) */
+#define MP_NO -1 /* no (boolean result) */
+#define MP_MEM -2 /* out of memory */
+#define MP_RANGE -3 /* argument out of range */
+#define MP_BADARG -4 /* invalid parameter */
+#define MP_UNDEF -5 /* answer is undefined */
+#define MP_LAST_CODE MP_UNDEF
+
+#include "mpi-types.h"
+
+/* Included for compatibility... */
+#define DIGIT_BIT MP_DIGIT_BIT
+#define DIGIT_MAX MP_DIGIT_MAX
+
+/* Macros for accessing the mp_int internals */
+#define SIGN(MP) ((MP)->sign)
+#define USED(MP) ((MP)->used)
+#define ALLOC(MP) ((MP)->alloc)
+#define DIGITS(MP) ((MP)->dp)
+#define DIGIT(MP,N) (MP)->dp[(N)]
+
+#if MP_ARGCHK == 1
+#define ARGCHK(X,Y) {if(!(X)){return (Y);}}
+#elif MP_ARGCHK == 2
+#include <assert.h>
+#define ARGCHK(X,Y) assert(X)
+#else
+#define ARGCHK(X,Y) /* */
+#endif
+
+/* This defines the maximum I/O base (minimum is 2) */
+#define MAX_RADIX 64
+
+typedef struct {
+ mp_sign sign; /* sign of this quantity */
+ mp_size alloc; /* how many digits allocated */
+ mp_size used; /* how many digits used */
+ mp_digit *dp; /* the digits themselves */
+} mp_int;
+
+/*------------------------------------------------------------------------*/
+/* Default precision */
+
+unsigned int mp_get_prec(void);
+void mp_set_prec(unsigned int prec);
+
+/*------------------------------------------------------------------------*/
+/* Memory management */
+
+mp_err mp_init(mp_int *mp);
+mp_err mp_init_array(mp_int mp[], int count);
+mp_err mp_init_size(mp_int *mp, mp_size prec);
+mp_err mp_init_copy(mp_int *mp, mp_int *from);
+mp_err mp_copy(mp_int *from, mp_int *to);
+void mp_exch(mp_int *mp1, mp_int *mp2);
+void mp_clear(mp_int *mp);
+void mp_clear_array(mp_int mp[], int count);
+void mp_zero(mp_int *mp);
+void mp_set(mp_int *mp, mp_digit d);
+mp_err mp_set_int(mp_int *mp, long z);
+mp_err mp_shrink(mp_int *a);
+
+
+/*------------------------------------------------------------------------*/
+/* Single digit arithmetic */
+
+mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b);
+mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b);
+mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b);
+mp_err mp_mul_2(mp_int *a, mp_int *c);
+mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r);
+mp_err mp_div_2(mp_int *a, mp_int *c);
+mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c);
+
+/*------------------------------------------------------------------------*/
+/* Sign manipulations */
+
+mp_err mp_abs(mp_int *a, mp_int *b);
+mp_err mp_neg(mp_int *a, mp_int *b);
+
+/*------------------------------------------------------------------------*/
+/* Full arithmetic */
+
+mp_err mp_add(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c);
+#if MP_SQUARE
+mp_err mp_sqr(mp_int *a, mp_int *b);
+#else
+#define mp_sqr(a, b) mp_mul(a, a, b)
+#endif
+mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r);
+mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r);
+mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_2expt(mp_int *a, mp_digit k);
+mp_err mp_sqrt(mp_int *a, mp_int *b);
+
+/*------------------------------------------------------------------------*/
+/* Modular arithmetic */
+
+#if MP_MODARITH
+mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c);
+mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c);
+mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
+mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
+mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
+#if MP_SQUARE
+mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c);
+#else
+#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
+#endif
+mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
+mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c);
+#endif /* MP_MODARITH */
+
+/*------------------------------------------------------------------------*/
+/* Comparisons */
+
+int mp_cmp_z(mp_int *a);
+int mp_cmp_d(mp_int *a, mp_digit d);
+int mp_cmp(mp_int *a, mp_int *b);
+int mp_cmp_mag(mp_int *a, mp_int *b);
+int mp_cmp_int(mp_int *a, long z);
+int mp_isodd(mp_int *a);
+int mp_iseven(mp_int *a);
+
+/*------------------------------------------------------------------------*/
+/* Number theoretic */
+
+#if MP_NUMTH
+mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y);
+mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c);
+#endif /* end MP_NUMTH */
+
+/*------------------------------------------------------------------------*/
+/* Input and output */
+
+#if MP_IOFUNC
+void mp_print(mp_int *mp, FILE *ofp);
+#endif /* end MP_IOFUNC */
+
+/*------------------------------------------------------------------------*/
+/* Base conversion */
+
+#define BITS 1
+#define BYTES CHAR_BIT
+
+mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len);
+int mp_signed_bin_size(mp_int *mp);
+mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str);
+
+mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len);
+int mp_unsigned_bin_size(mp_int *mp);
+mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str);
+
+int mp_count_bits(mp_int *mp);
+
+#if MP_COMPAT_MACROS
+#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
+#define mp_raw_size(mp) mp_signed_bin_size(mp)
+#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
+#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
+#define mp_mag_size(mp) mp_unsigned_bin_size(mp)
+#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
+#endif
+
+mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix);
+int mp_radix_size(mp_int *mp, int radix);
+int mp_value_radix_size(int num, int qty, int radix);
+mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix);
+
+int mp_char2value(char ch, int r);
+
+#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
+#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
+#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
+#define mp_tohex(M, S) mp_toradix((M), (S), 16)
+
+/*------------------------------------------------------------------------*/
+/* Error strings */
+
+const char *mp_strerror(mp_err ec);
+
+#endif /* end _H_MPI_ */
+
+/* $Source: /cvs/libtom/libtommath/mtest/mpi.h,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:38:47 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/mtest/mtest.c b/source4/heimdal/lib/hcrypto/libtommath/mtest/mtest.c
new file mode 100644
index 0000000000..bdfe6127af
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/mtest/mtest.c
@@ -0,0 +1,308 @@
+/* makes a bignum test harness with NUM tests per operation
+ *
+ * the output is made in the following format [one parameter per line]
+
+operation
+operand1
+operand2
+[... operandN]
+result1
+result2
+[... resultN]
+
+So for example "a * b mod n" would be
+
+mulmod
+a
+b
+n
+a*b mod n
+
+e.g. if a=3, b=4 n=11 then
+
+mulmod
+3
+4
+11
+1
+
+ */
+
+#ifdef MP_8BIT
+#define THE_MASK 127
+#else
+#define THE_MASK 32767
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "mpi.c"
+
+FILE *rng;
+
+void rand_num(mp_int *a)
+{
+ int n, size;
+ unsigned char buf[2048];
+
+ size = 1 + ((fgetc(rng)<<8) + fgetc(rng)) % 101;
+ buf[0] = (fgetc(rng)&1)?1:0;
+ fread(buf+1, 1, size, rng);
+ while (buf[1] == 0) buf[1] = fgetc(rng);
+ mp_read_raw(a, buf, 1+size);
+}
+
+void rand_num2(mp_int *a)
+{
+ int n, size;
+ unsigned char buf[2048];
+
+ size = 10 + ((fgetc(rng)<<8) + fgetc(rng)) % 101;
+ buf[0] = (fgetc(rng)&1)?1:0;
+ fread(buf+1, 1, size, rng);
+ while (buf[1] == 0) buf[1] = fgetc(rng);
+ mp_read_raw(a, buf, 1+size);
+}
+
+#define mp_to64(a, b) mp_toradix(a, b, 64)
+
+int main(void)
+{
+ int n, tmp;
+ mp_int a, b, c, d, e;
+ clock_t t1;
+ char buf[4096];
+
+ mp_init(&a);
+ mp_init(&b);
+ mp_init(&c);
+ mp_init(&d);
+ mp_init(&e);
+
+
+ /* initial (2^n - 1)^2 testing, makes sure the comba multiplier works [it has the new carry code] */
+/*
+ mp_set(&a, 1);
+ for (n = 1; n < 8192; n++) {
+ mp_mul(&a, &a, &c);
+ printf("mul\n");
+ mp_to64(&a, buf);
+ printf("%s\n%s\n", buf, buf);
+ mp_to64(&c, buf);
+ printf("%s\n", buf);
+
+ mp_add_d(&a, 1, &a);
+ mp_mul_2(&a, &a);
+ mp_sub_d(&a, 1, &a);
+ }
+*/
+
+ rng = fopen("/dev/urandom", "rb");
+ if (rng == NULL) {
+ rng = fopen("/dev/random", "rb");
+ if (rng == NULL) {
+ fprintf(stderr, "\nWarning: stdin used as random source\n\n");
+ rng = stdin;
+ }
+ }
+
+ t1 = clock();
+ for (;;) {
+#if 0
+ if (clock() - t1 > CLOCKS_PER_SEC) {
+ sleep(2);
+ t1 = clock();
+ }
+#endif
+ n = fgetc(rng) % 15;
+
+ if (n == 0) {
+ /* add tests */
+ rand_num(&a);
+ rand_num(&b);
+ mp_add(&a, &b, &c);
+ printf("add\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ mp_to64(&c, buf);
+ printf("%s\n", buf);
+ } else if (n == 1) {
+ /* sub tests */
+ rand_num(&a);
+ rand_num(&b);
+ mp_sub(&a, &b, &c);
+ printf("sub\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ mp_to64(&c, buf);
+ printf("%s\n", buf);
+ } else if (n == 2) {
+ /* mul tests */
+ rand_num(&a);
+ rand_num(&b);
+ mp_mul(&a, &b, &c);
+ printf("mul\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ mp_to64(&c, buf);
+ printf("%s\n", buf);
+ } else if (n == 3) {
+ /* div tests */
+ rand_num(&a);
+ rand_num(&b);
+ mp_div(&a, &b, &c, &d);
+ printf("div\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ mp_to64(&c, buf);
+ printf("%s\n", buf);
+ mp_to64(&d, buf);
+ printf("%s\n", buf);
+ } else if (n == 4) {
+ /* sqr tests */
+ rand_num(&a);
+ mp_sqr(&a, &b);
+ printf("sqr\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ } else if (n == 5) {
+ /* mul_2d test */
+ rand_num(&a);
+ mp_copy(&a, &b);
+ n = fgetc(rng) & 63;
+ mp_mul_2d(&b, n, &b);
+ mp_to64(&a, buf);
+ printf("mul2d\n");
+ printf("%s\n", buf);
+ printf("%d\n", n);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ } else if (n == 6) {
+ /* div_2d test */
+ rand_num(&a);
+ mp_copy(&a, &b);
+ n = fgetc(rng) & 63;
+ mp_div_2d(&b, n, &b, NULL);
+ mp_to64(&a, buf);
+ printf("div2d\n");
+ printf("%s\n", buf);
+ printf("%d\n", n);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ } else if (n == 7) {
+ /* gcd test */
+ rand_num(&a);
+ rand_num(&b);
+ a.sign = MP_ZPOS;
+ b.sign = MP_ZPOS;
+ mp_gcd(&a, &b, &c);
+ printf("gcd\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ mp_to64(&c, buf);
+ printf("%s\n", buf);
+ } else if (n == 8) {
+ /* lcm test */
+ rand_num(&a);
+ rand_num(&b);
+ a.sign = MP_ZPOS;
+ b.sign = MP_ZPOS;
+ mp_lcm(&a, &b, &c);
+ printf("lcm\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ mp_to64(&c, buf);
+ printf("%s\n", buf);
+ } else if (n == 9) {
+ /* exptmod test */
+ rand_num2(&a);
+ rand_num2(&b);
+ rand_num2(&c);
+// if (c.dp[0]&1) mp_add_d(&c, 1, &c);
+ a.sign = b.sign = c.sign = 0;
+ mp_exptmod(&a, &b, &c, &d);
+ printf("expt\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ mp_to64(&c, buf);
+ printf("%s\n", buf);
+ mp_to64(&d, buf);
+ printf("%s\n", buf);
+ } else if (n == 10) {
+ /* invmod test */
+ rand_num2(&a);
+ rand_num2(&b);
+ b.sign = MP_ZPOS;
+ a.sign = MP_ZPOS;
+ mp_gcd(&a, &b, &c);
+ if (mp_cmp_d(&c, 1) != 0) continue;
+ if (mp_cmp_d(&b, 1) == 0) continue;
+ mp_invmod(&a, &b, &c);
+ printf("invmod\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ mp_to64(&c, buf);
+ printf("%s\n", buf);
+ } else if (n == 11) {
+ rand_num(&a);
+ mp_mul_2(&a, &a);
+ mp_div_2(&a, &b);
+ printf("div2\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ } else if (n == 12) {
+ rand_num2(&a);
+ mp_mul_2(&a, &b);
+ printf("mul2\n");
+ mp_to64(&a, buf);
+ printf("%s\n", buf);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ } else if (n == 13) {
+ rand_num2(&a);
+ tmp = abs(rand()) & THE_MASK;
+ mp_add_d(&a, tmp, &b);
+ printf("add_d\n");
+ mp_to64(&a, buf);
+ printf("%s\n%d\n", buf, tmp);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ } else if (n == 14) {
+ rand_num2(&a);
+ tmp = abs(rand()) & THE_MASK;
+ mp_sub_d(&a, tmp, &b);
+ printf("sub_d\n");
+ mp_to64(&a, buf);
+ printf("%s\n%d\n", buf, tmp);
+ mp_to64(&b, buf);
+ printf("%s\n", buf);
+ }
+ }
+ fclose(rng);
+ return 0;
+}
+
+/* $Source: /cvs/libtom/libtommath/mtest/mtest.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:38:47 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.sxd b/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.sxd
new file mode 100644
index 0000000000..7414dbb276
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.sxd
Binary files differ
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.tif b/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.tif
new file mode 100644
index 0000000000..4a0c012d56
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.tif
Binary files differ
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.sxd b/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.sxd
new file mode 100644
index 0000000000..6518404d5f
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.sxd
Binary files differ
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.tif b/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.tif
new file mode 100644
index 0000000000..cb06e8edf1
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.tif
Binary files differ
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/makefile b/source4/heimdal/lib/hcrypto/libtommath/pics/makefile
new file mode 100644
index 0000000000..3ecb02ff73
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pics/makefile
@@ -0,0 +1,35 @@
+# makes the images... yeah
+
+default: pses
+
+design_process.ps: design_process.tif
+ tiff2ps -s -e design_process.tif > design_process.ps
+
+sliding_window.ps: sliding_window.tif
+ tiff2ps -s -e sliding_window.tif > sliding_window.ps
+
+expt_state.ps: expt_state.tif
+ tiff2ps -s -e expt_state.tif > expt_state.ps
+
+primality.ps: primality.tif
+ tiff2ps -s -e primality.tif > primality.ps
+
+design_process.pdf: design_process.ps
+ epstopdf design_process.ps
+
+sliding_window.pdf: sliding_window.ps
+ epstopdf sliding_window.ps
+
+expt_state.pdf: expt_state.ps
+ epstopdf expt_state.ps
+
+primality.pdf: primality.ps
+ epstopdf primality.ps
+
+
+pses: sliding_window.ps expt_state.ps primality.ps design_process.ps
+pdfes: sliding_window.pdf expt_state.pdf primality.pdf design_process.pdf
+
+clean:
+ rm -rf *.ps *.pdf .xvpics
+ \ No newline at end of file
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/primality.tif b/source4/heimdal/lib/hcrypto/libtommath/pics/primality.tif
new file mode 100644
index 0000000000..76d6be3fac
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pics/primality.tif
Binary files differ
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/radix.sxd b/source4/heimdal/lib/hcrypto/libtommath/pics/radix.sxd
new file mode 100644
index 0000000000..b9eb9a032d
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pics/radix.sxd
Binary files differ
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.sxd b/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.sxd
new file mode 100644
index 0000000000..91e7c0d9f4
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.sxd
Binary files differ
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.tif b/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.tif
new file mode 100644
index 0000000000..bb4cb96ebf
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.tif
Binary files differ
diff --git a/source4/heimdal/lib/hcrypto/libtommath/pretty.build b/source4/heimdal/lib/hcrypto/libtommath/pretty.build
new file mode 100644
index 0000000000..a708b8af22
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/pretty.build
@@ -0,0 +1,66 @@
+#!/bin/perl -w
+#
+# Cute little builder for perl
+# Total waste of development time...
+#
+# This will build all the object files and then the archive .a file
+# requires GCC, GNU make and a sense of humour.
+#
+# Tom St Denis
+use strict;
+
+my $count = 0;
+my $starttime = time;
+my $rate = 0;
+print "Scanning for source files...\n";
+foreach my $filename (glob "*.c") {
+ ++$count;
+}
+print "Source files to build: $count\nBuilding...\n";
+my $i = 0;
+my $lines = 0;
+my $filesbuilt = 0;
+foreach my $filename (glob "*.c") {
+ printf("Building %3.2f%%, ", (++$i/$count)*100.0);
+ if ($i % 4 == 0) { print "/, "; }
+ if ($i % 4 == 1) { print "-, "; }
+ if ($i % 4 == 2) { print "\\, "; }
+ if ($i % 4 == 3) { print "|, "; }
+ if ($rate > 0) {
+ my $tleft = ($count - $i) / $rate;
+ my $tsec = $tleft%60;
+ my $tmin = ($tleft/60)%60;
+ my $thour = ($tleft/3600)%60;
+ printf("%2d:%02d:%02d left, ", $thour, $tmin, $tsec);
+ }
+ my $cnt = ($i/$count)*30.0;
+ my $x = 0;
+ print "[";
+ for (; $x < $cnt; $x++) { print "#"; }
+ for (; $x < 30; $x++) { print " "; }
+ print "]\r";
+ my $tmp = $filename;
+ $tmp =~ s/\.c/".o"/ge;
+ if (open(SRC, "<$tmp")) {
+ close SRC;
+ } else {
+ !system("make $tmp > /dev/null 2>/dev/null") or die "\nERROR: Failed to make $tmp!!!\n";
+ open( SRC, "<$filename" ) or die "Couldn't open $filename for reading: $!";
+ ++$lines while (<SRC>);
+ close SRC or die "Error closing $filename after reading: $!";
+ ++$filesbuilt;
+ }
+
+ # update timer
+ if (time != $starttime) {
+ my $delay = time - $starttime;
+ $rate = $i/$delay;
+ }
+}
+
+# finish building the library
+printf("\nFinished building source (%d seconds, %3.2f files per second).\n", time - $starttime, $rate);
+print "Compiled approximately $filesbuilt files and $lines lines of code.\n";
+print "Doing final make (building archive...)\n";
+!system("make > /dev/null 2>/dev/null") or die "\nERROR: Failed to perform last make command!!!\n";
+print "done.\n"; \ No newline at end of file
diff --git a/source4/heimdal/lib/hcrypto/libtommath/tombc/grammar.txt b/source4/heimdal/lib/hcrypto/libtommath/tombc/grammar.txt
new file mode 100644
index 0000000000..a780e759d6
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/tombc/grammar.txt
@@ -0,0 +1,35 @@
+program := program statement | statement | empty
+statement := { statement } |
+ identifier = numexpression; |
+ identifier[numexpression] = numexpression; |
+ function(expressionlist); |
+ for (identifer = numexpression; numexpression; identifier = numexpression) { statement } |
+ while (numexpression) { statement } |
+ if (numexpresion) { statement } elif |
+ break; |
+ continue;
+
+elif := else statement | empty
+function := abs | countbits | exptmod | jacobi | print | isprime | nextprime | issquare | readinteger | exit
+expressionlist := expressionlist, expression | expression
+
+// LR(1) !!!?
+expression := string | numexpression
+numexpression := cmpexpr && cmpexpr | cmpexpr \|\| cmpexpr | cmpexpr
+cmpexpr := boolexpr < boolexpr | boolexpr > boolexpr | boolexpr == boolexpr |
+ boolexpr <= boolexpr | boolexpr >= boolexpr | boolexpr
+boolexpr := shiftexpr & shiftexpr | shiftexpr ^ shiftexpr | shiftexpr \| shiftexpr | shiftexpr
+shiftexpr := addsubexpr << addsubexpr | addsubexpr >> addsubexpr | addsubexpr
+addsubexpr := mulexpr + mulexpr | mulexpr - mulexpr | mulexpr
+mulexpr := expr * expr | expr / expr | expr % expr | expr
+expr := -nexpr | nexpr
+nexpr := integer | identifier | ( numexpression ) | identifier[numexpression]
+
+identifier := identifer digits | identifier alpha | alpha
+alpha := a ... z | A ... Z
+integer := hexnumber | digits
+hexnumber := 0xhexdigits
+hexdigits := hexdigits hexdigit | hexdigit
+hexdigit := 0 ... 9 | a ... f | A ... F
+digits := digits digit | digit
+digit := 0 ... 9
diff --git a/source4/heimdal/lib/hcrypto/libtommath/tommath.h b/source4/heimdal/lib/hcrypto/libtommath/tommath.h
new file mode 100644
index 0000000000..426207a298
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/tommath.h
@@ -0,0 +1,592 @@
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+#ifndef BN_H_
+#define BN_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <limits.h>
+
+#include <tommath_class.h>
+
+#ifndef MIN
+ #define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+#ifndef MAX
+ #define MAX(x,y) ((x)>(y)?(x):(y))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+
+/* C++ compilers don't like assigning void * to mp_digit * */
+#define OPT_CAST(x) (x *)
+
+#else
+
+/* C on the other hand doesn't care */
+#define OPT_CAST(x)
+
+#endif
+
+
+/* detect 64-bit mode if possible */
+#if defined(__x86_64__)
+ #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
+ #define MP_64BIT
+ #endif
+#endif
+
+/* some default configurations.
+ *
+ * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
+ * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
+ *
+ * At the very least a mp_digit must be able to hold 7 bits
+ * [any size beyond that is ok provided it doesn't overflow the data type]
+ */
+#ifdef MP_8BIT
+ typedef unsigned char mp_digit;
+ typedef unsigned short mp_word;
+#elif defined(MP_16BIT)
+ typedef unsigned short mp_digit;
+ typedef unsigned long mp_word;
+#elif defined(MP_64BIT)
+ /* for GCC only on supported platforms */
+#ifndef CRYPT
+ typedef unsigned long long ulong64;
+ typedef signed long long long64;
+#endif
+
+ typedef unsigned long mp_digit;
+ typedef unsigned long mp_word __attribute__ ((mode(TI)));
+
+ #define DIGIT_BIT 60
+#else
+ /* this is the default case, 28-bit digits */
+
+ /* this is to make porting into LibTomCrypt easier :-) */
+#ifndef CRYPT
+ #if defined(_MSC_VER) || defined(__BORLANDC__)
+ typedef unsigned __int64 ulong64;
+ typedef signed __int64 long64;
+ #else
+ typedef unsigned long long ulong64;
+ typedef signed long long long64;
+ #endif
+#endif
+
+ typedef unsigned long mp_digit;
+ typedef ulong64 mp_word;
+
+#ifdef MP_31BIT
+ /* this is an extension that uses 31-bit digits */
+ #define DIGIT_BIT 31
+#else
+ /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
+ #define DIGIT_BIT 28
+ #define MP_28BIT
+#endif
+#endif
+
+/* define heap macros */
+#ifndef CRYPT
+ /* default to libc stuff */
+ #ifndef XMALLOC
+ #define XMALLOC malloc
+ #define XFREE free
+ #define XREALLOC realloc
+ #define XCALLOC calloc
+ #else
+ /* prototypes for our heap functions */
+ extern void *XMALLOC(size_t n);
+ extern void *XREALLOC(void *p, size_t n);
+ extern void *XCALLOC(size_t n, size_t s);
+ extern void XFREE(void *p);
+ #endif
+#endif
+
+
+/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
+#ifndef DIGIT_BIT
+ #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */
+#endif
+
+#define MP_DIGIT_BIT DIGIT_BIT
+#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
+#define MP_DIGIT_MAX MP_MASK
+
+/* equalities */
+#define MP_LT -1 /* less than */
+#define MP_EQ 0 /* equal to */
+#define MP_GT 1 /* greater than */
+
+#define MP_ZPOS 0 /* positive integer */
+#define MP_NEG 1 /* negative */
+
+#define MP_OKAY 0 /* ok result */
+#define MP_MEM -2 /* out of mem */
+#define MP_VAL -3 /* invalid input */
+#define MP_RANGE MP_VAL
+
+#define MP_YES 1 /* yes response */
+#define MP_NO 0 /* no response */
+
+/* Primality generation flags */
+#define LTM_PRIME_BBS 0x0001 /* BBS style prime */
+#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
+#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
+
+typedef int mp_err;
+
+/* you'll have to tune these... */
+extern int KARATSUBA_MUL_CUTOFF,
+ KARATSUBA_SQR_CUTOFF,
+ TOOM_MUL_CUTOFF,
+ TOOM_SQR_CUTOFF;
+
+/* define this to use lower memory usage routines (exptmods mostly) */
+/* #define MP_LOW_MEM */
+
+/* default precision */
+#ifndef MP_PREC
+ #ifndef MP_LOW_MEM
+ #define MP_PREC 32 /* default digits of precision */
+ #else
+ #define MP_PREC 8 /* default digits of precision */
+ #endif
+#endif
+
+/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
+#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
+
+/* the infamous mp_int structure */
+typedef struct {
+ int used, alloc, sign;
+ mp_digit *dp;
+} mp_int;
+
+/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
+typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
+
+
+#define USED(m) ((m)->used)
+#define DIGIT(m,k) ((m)->dp[(k)])
+#define SIGN(m) ((m)->sign)
+
+/* error code to char* string */
+char *mp_error_to_string(int code);
+
+/* ---> init and deinit bignum functions <--- */
+/* init a bignum */
+int mp_init(mp_int *a);
+
+/* free a bignum */
+void mp_clear(mp_int *a);
+
+/* init a null terminated series of arguments */
+int mp_init_multi(mp_int *mp, ...);
+
+/* clear a null terminated series of arguments */
+void mp_clear_multi(mp_int *mp, ...);
+
+/* exchange two ints */
+void mp_exch(mp_int *a, mp_int *b);
+
+/* shrink ram required for a bignum */
+int mp_shrink(mp_int *a);
+
+/* grow an int to a given size */
+int mp_grow(mp_int *a, int size);
+
+/* init to a given number of digits */
+int mp_init_size(mp_int *a, int size);
+
+/* ---> Basic Manipulations <--- */
+#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
+#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
+#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
+#define mp_isneg(a) (((a)->sign) ? MP_YES : MP_NO)
+
+/* set to zero */
+void mp_zero(mp_int *a);
+
+/* set to zero, multi */
+void mp_zero_multi(mp_int *a, ...);
+
+/* set to a digit */
+void mp_set(mp_int *a, mp_digit b);
+
+/* set a 32-bit const */
+int mp_set_int(mp_int *a, unsigned long b);
+
+/* get a 32-bit value */
+unsigned long mp_get_int(mp_int * a);
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b);
+
+/* initialize and set 32-bit value */
+int mp_init_set_int (mp_int * a, unsigned long b);
+
+/* copy, b = a */
+int mp_copy(mp_int *a, mp_int *b);
+
+/* inits and copies, a = b */
+int mp_init_copy(mp_int *a, mp_int *b);
+
+/* trim unused digits */
+void mp_clamp(mp_int *a);
+
+/* ---> digit manipulation <--- */
+
+/* right shift by "b" digits */
+void mp_rshd(mp_int *a, int b);
+
+/* left shift by "b" digits */
+int mp_lshd(mp_int *a, int b);
+
+/* c = a / 2**b */
+int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
+
+/* b = a/2 */
+int mp_div_2(mp_int *a, mp_int *b);
+
+/* c = a * 2**b */
+int mp_mul_2d(mp_int *a, int b, mp_int *c);
+
+/* b = a*2 */
+int mp_mul_2(mp_int *a, mp_int *b);
+
+/* c = a mod 2**d */
+int mp_mod_2d(mp_int *a, int b, mp_int *c);
+
+/* computes a = 2**b */
+int mp_2expt(mp_int *a, int b);
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(mp_int *a);
+
+/* I Love Earth! */
+
+/* makes a pseudo-random int of a given size */
+int mp_rand(mp_int *a, int digits);
+
+/* ---> binary operations <--- */
+/* c = a XOR b */
+int mp_xor(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a OR b */
+int mp_or(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a AND b */
+int mp_and(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> Basic arithmetic <--- */
+
+/* b = -a */
+int mp_neg(mp_int *a, mp_int *b);
+
+/* b = |a| */
+int mp_abs(mp_int *a, mp_int *b);
+
+/* compare a to b */
+int mp_cmp(mp_int *a, mp_int *b);
+
+/* compare |a| to |b| */
+int mp_cmp_mag(mp_int *a, mp_int *b);
+
+/* c = a + b */
+int mp_add(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a - b */
+int mp_sub(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a * b */
+int mp_mul(mp_int *a, mp_int *b, mp_int *c);
+
+/* b = a*a */
+int mp_sqr(mp_int *a, mp_int *b);
+
+/* a/b => cb + d == a */
+int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a mod b, 0 <= c < b */
+int mp_mod(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> single digit functions <--- */
+
+/* compare against a single digit */
+int mp_cmp_d(mp_int *a, mp_digit b);
+
+/* c = a + b */
+int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a - b */
+int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a * b */
+int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* a/b => cb + d == a */
+int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
+
+/* a/3 => 3c + d == a */
+int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
+
+/* c = a**b */
+int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a mod b, 0 <= c < b */
+int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
+
+/* ---> number theory <--- */
+
+/* d = a + b (mod c) */
+int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a - b (mod c) */
+int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a * b (mod c) */
+int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a * a (mod b) */
+int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = 1/a (mod b) */
+int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = (a, b) */
+int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
+
+/* produces value such that U1*a + U2*b = U3 */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
+
+/* c = [a, b] or (a*b)/(a, b) */
+int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
+
+/* finds one of the b'th root of a, such that |c|**b <= |a|
+ *
+ * returns error if a < 0 and b is even
+ */
+int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
+
+/* special sqrt algo */
+int mp_sqrt(mp_int *arg, mp_int *ret);
+
+/* is number a square? */
+int mp_is_square(mp_int *arg, int *ret);
+
+/* computes the jacobi c = (a | n) (or Legendre if b is prime) */
+int mp_jacobi(mp_int *a, mp_int *n, int *c);
+
+/* used to setup the Barrett reduction for a given modulus b */
+int mp_reduce_setup(mp_int *a, mp_int *b);
+
+/* Barrett Reduction, computes a (mod b) with a precomputed value c
+ *
+ * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
+ * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
+ */
+int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
+
+/* setups the montgomery reduction */
+int mp_montgomery_setup(mp_int *a, mp_digit *mp);
+
+/* computes a = B**n mod b without division or multiplication useful for
+ * normalizing numbers in a Montgomery system.
+ */
+int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
+
+/* computes x/R == x (mod N) via Montgomery Reduction */
+int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+
+/* returns 1 if a is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a);
+
+/* sets the value of "d" required for mp_dr_reduce */
+void mp_dr_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b using the Diminished Radix method */
+int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
+
+/* returns true if a can be reduced with mp_reduce_2k */
+int mp_reduce_is_2k(mp_int *a);
+
+/* determines k value for 2k reduction */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
+
+/* returns true if a can be reduced with mp_reduce_2k_l */
+int mp_reduce_is_2k_l(mp_int *a);
+
+/* determines k value for 2k reduction */
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
+
+/* d = a**b (mod c) */
+int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* ---> Primes <--- */
+
+/* number of primes */
+#ifdef MP_8BIT
+ #define PRIME_SIZE 31
+#else
+ #define PRIME_SIZE 256
+#endif
+
+/* table of first PRIME_SIZE primes */
+extern const mp_digit ltm_prime_tab[];
+
+/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
+int mp_prime_is_divisible(mp_int *a, int *result);
+
+/* performs one Fermat test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
+
+/* performs one Miller-Rabin test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
+
+/* This gives [for a given bit size] the number of trials required
+ * such that Miller-Rabin gives a prob of failure lower than 2^-96
+ */
+int mp_prime_rabin_miller_trials(int size);
+
+/* performs t rounds of Miller-Rabin on "a" using the first
+ * t prime bases. Also performs an initial sieve of trial
+ * division. Determines if "a" is prime with probability
+ * of error no more than (1/4)**t.
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime(mp_int *a, int t, int *result);
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
+
+/* makes a truly random prime of a given size (bytes),
+ * call with bbs = 1 if you want it to be congruent to 3 mod 4
+ *
+ * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ * The prime generated will be larger than 2^(8*size).
+ */
+#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ *
+ * LTM_PRIME_BBS - make prime congruent to 3 mod 4
+ * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
+
+int mp_find_prime(mp_int *a);
+
+int mp_isprime(mp_int *a);
+
+/* ---> radix conversion <--- */
+int mp_count_bits(mp_int *a);
+
+int mp_unsigned_bin_size(mp_int *a);
+int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
+int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+
+int mp_signed_bin_size(mp_int *a);
+int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
+int mp_to_signed_bin(mp_int *a, unsigned char *b);
+int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+
+int mp_read_radix(mp_int *a, const char *str, int radix);
+int mp_toradix(mp_int *a, char *str, int radix);
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
+int mp_radix_size(mp_int *a, int radix, int *size);
+
+int mp_fread(mp_int *a, int radix, FILE *stream);
+int mp_fwrite(mp_int *a, int radix, FILE *stream);
+
+#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
+#define mp_raw_size(mp) mp_signed_bin_size(mp)
+#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
+#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
+#define mp_mag_size(mp) mp_unsigned_bin_size(mp)
+#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
+
+#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
+#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
+#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
+#define mp_tohex(M, S) mp_toradix((M), (S), 16)
+
+/* lowlevel functions, do not call! */
+int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
+int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
+#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
+int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int fast_s_mp_sqr(mp_int *a, mp_int *b);
+int s_mp_sqr(mp_int *a, mp_int *b);
+int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_karatsuba_sqr(mp_int *a, mp_int *b);
+int mp_toom_sqr(mp_int *a, mp_int *b);
+int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
+int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode);
+void bn_reverse(unsigned char *s, int len);
+
+extern const char *mp_s_rmap;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
+
+
+/* $Source: /cvs/libtom/libtommath/tommath.h,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2006/03/31 14:18:44 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/tommath_class.h b/source4/heimdal/lib/hcrypto/libtommath/tommath_class.h
new file mode 100644
index 0000000000..fa95a0277a
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/tommath_class.h
@@ -0,0 +1,1000 @@
+#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
+#if defined(LTM2)
+#define LTM3
+#endif
+#if defined(LTM1)
+#define LTM2
+#endif
+#define LTM1
+
+#if defined(LTM_ALL)
+#define BN_ERROR_C
+#define BN_FAST_MP_INVMOD_C
+#define BN_FAST_MP_MONTGOMERY_REDUCE_C
+#define BN_FAST_S_MP_MUL_DIGS_C
+#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+#define BN_FAST_S_MP_SQR_C
+#define BN_MP_2EXPT_C
+#define BN_MP_ABS_C
+#define BN_MP_ADD_C
+#define BN_MP_ADD_D_C
+#define BN_MP_ADDMOD_C
+#define BN_MP_AND_C
+#define BN_MP_CLAMP_C
+#define BN_MP_CLEAR_C
+#define BN_MP_CLEAR_MULTI_C
+#define BN_MP_CMP_C
+#define BN_MP_CMP_D_C
+#define BN_MP_CMP_MAG_C
+#define BN_MP_CNT_LSB_C
+#define BN_MP_COPY_C
+#define BN_MP_COUNT_BITS_C
+#define BN_MP_DIV_C
+#define BN_MP_DIV_2_C
+#define BN_MP_DIV_2D_C
+#define BN_MP_DIV_3_C
+#define BN_MP_DIV_D_C
+#define BN_MP_DR_IS_MODULUS_C
+#define BN_MP_DR_REDUCE_C
+#define BN_MP_DR_SETUP_C
+#define BN_MP_EXCH_C
+#define BN_MP_EXPT_D_C
+#define BN_MP_EXPTMOD_C
+#define BN_MP_EXPTMOD_FAST_C
+#define BN_MP_EXTEUCLID_C
+#define BN_MP_FREAD_C
+#define BN_MP_FWRITE_C
+#define BN_MP_GCD_C
+#define BN_MP_GET_INT_C
+#define BN_MP_GROW_C
+#define BN_MP_INIT_C
+#define BN_MP_INIT_COPY_C
+#define BN_MP_INIT_MULTI_C
+#define BN_MP_INIT_SET_C
+#define BN_MP_INIT_SET_INT_C
+#define BN_MP_INIT_SIZE_C
+#define BN_MP_INVMOD_C
+#define BN_MP_INVMOD_SLOW_C
+#define BN_MP_IS_SQUARE_C
+#define BN_MP_JACOBI_C
+#define BN_MP_KARATSUBA_MUL_C
+#define BN_MP_KARATSUBA_SQR_C
+#define BN_MP_LCM_C
+#define BN_MP_LSHD_C
+#define BN_MP_MOD_C
+#define BN_MP_MOD_2D_C
+#define BN_MP_MOD_D_C
+#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+#define BN_MP_MONTGOMERY_REDUCE_C
+#define BN_MP_MONTGOMERY_SETUP_C
+#define BN_MP_MUL_C
+#define BN_MP_MUL_2_C
+#define BN_MP_MUL_2D_C
+#define BN_MP_MUL_D_C
+#define BN_MP_MULMOD_C
+#define BN_MP_N_ROOT_C
+#define BN_MP_NEG_C
+#define BN_MP_OR_C
+#define BN_MP_PRIME_FERMAT_C
+#define BN_MP_PRIME_IS_DIVISIBLE_C
+#define BN_MP_PRIME_IS_PRIME_C
+#define BN_MP_PRIME_MILLER_RABIN_C
+#define BN_MP_PRIME_NEXT_PRIME_C
+#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+#define BN_MP_PRIME_RANDOM_EX_C
+#define BN_MP_RADIX_SIZE_C
+#define BN_MP_RADIX_SMAP_C
+#define BN_MP_RAND_C
+#define BN_MP_READ_RADIX_C
+#define BN_MP_READ_SIGNED_BIN_C
+#define BN_MP_READ_UNSIGNED_BIN_C
+#define BN_MP_REDUCE_C
+#define BN_MP_REDUCE_2K_C
+#define BN_MP_REDUCE_2K_L_C
+#define BN_MP_REDUCE_2K_SETUP_C
+#define BN_MP_REDUCE_2K_SETUP_L_C
+#define BN_MP_REDUCE_IS_2K_C
+#define BN_MP_REDUCE_IS_2K_L_C
+#define BN_MP_REDUCE_SETUP_C
+#define BN_MP_RSHD_C
+#define BN_MP_SET_C
+#define BN_MP_SET_INT_C
+#define BN_MP_SHRINK_C
+#define BN_MP_SIGNED_BIN_SIZE_C
+#define BN_MP_SQR_C
+#define BN_MP_SQRMOD_C
+#define BN_MP_SQRT_C
+#define BN_MP_SUB_C
+#define BN_MP_SUB_D_C
+#define BN_MP_SUBMOD_C
+#define BN_MP_TO_SIGNED_BIN_C
+#define BN_MP_TO_SIGNED_BIN_N_C
+#define BN_MP_TO_UNSIGNED_BIN_C
+#define BN_MP_TO_UNSIGNED_BIN_N_C
+#define BN_MP_TOOM_MUL_C
+#define BN_MP_TOOM_SQR_C
+#define BN_MP_TORADIX_C
+#define BN_MP_TORADIX_N_C
+#define BN_MP_UNSIGNED_BIN_SIZE_C
+#define BN_MP_XOR_C
+#define BN_MP_ZERO_C
+#define BN_MP_ZERO_MULTI_C
+#define BN_PRIME_TAB_C
+#define BN_REVERSE_C
+#define BN_S_MP_ADD_C
+#define BN_S_MP_EXPTMOD_C
+#define BN_S_MP_MUL_DIGS_C
+#define BN_S_MP_MUL_HIGH_DIGS_C
+#define BN_S_MP_SQR_C
+#define BN_S_MP_SUB_C
+#define BNCORE_C
+#endif
+
+#if defined(BN_ERROR_C)
+ #define BN_MP_ERROR_TO_STRING_C
+#endif
+
+#if defined(BN_FAST_MP_INVMOD_C)
+ #define BN_MP_ISEVEN_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_COPY_C
+ #define BN_MP_MOD_C
+ #define BN_MP_SET_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_ISODD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CMP_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_CMP_D_C
+ #define BN_MP_ADD_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_DIGS_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_SQR_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_2EXPT_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_ABS_C)
+ #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_ADD_C)
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_ADD_D_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_ADDMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_ADD_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_AND_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CLAMP_C)
+#endif
+
+#if defined(BN_MP_CLEAR_C)
+#endif
+
+#if defined(BN_MP_CLEAR_MULTI_C)
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CMP_C)
+ #define BN_MP_CMP_MAG_C
+#endif
+
+#if defined(BN_MP_CMP_D_C)
+#endif
+
+#if defined(BN_MP_CMP_MAG_C)
+#endif
+
+#if defined(BN_MP_CNT_LSB_C)
+ #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_COPY_C)
+ #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_COUNT_BITS_C)
+#endif
+
+#if defined(BN_MP_DIV_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_COPY_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_SET_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_ABS_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CMP_C
+ #define BN_MP_SUB_C
+ #define BN_MP_ADD_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_INIT_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_2_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_DIV_2D_C)
+ #define BN_MP_COPY_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_C
+ #define BN_MP_MOD_2D_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_DIV_3_C)
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_D_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_COPY_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_DIV_3_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DR_IS_MODULUS_C)
+#endif
+
+#if defined(BN_MP_DR_REDUCE_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_DR_SETUP_C)
+#endif
+
+#if defined(BN_MP_EXCH_C)
+#endif
+
+#if defined(BN_MP_EXPT_D_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_SET_C
+ #define BN_MP_SQR_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MUL_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_INVMOD_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_ABS_C
+ #define BN_MP_CLEAR_MULTI_C
+ #define BN_MP_REDUCE_IS_2K_L_C
+ #define BN_S_MP_EXPTMOD_C
+ #define BN_MP_DR_IS_MODULUS_C
+ #define BN_MP_REDUCE_IS_2K_C
+ #define BN_MP_ISODD_C
+ #define BN_MP_EXPTMOD_FAST_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_FAST_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_INIT_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MONTGOMERY_SETUP_C
+ #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+ #define BN_MP_MONTGOMERY_REDUCE_C
+ #define BN_MP_DR_SETUP_C
+ #define BN_MP_DR_REDUCE_C
+ #define BN_MP_REDUCE_2K_SETUP_C
+ #define BN_MP_REDUCE_2K_C
+ #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+ #define BN_MP_MULMOD_C
+ #define BN_MP_SET_C
+ #define BN_MP_MOD_C
+ #define BN_MP_COPY_C
+ #define BN_MP_SQR_C
+ #define BN_MP_MUL_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_EXTEUCLID_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_SET_C
+ #define BN_MP_COPY_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_DIV_C
+ #define BN_MP_MUL_C
+ #define BN_MP_SUB_C
+ #define BN_MP_NEG_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_FREAD_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_S_RMAP_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_CMP_D_C
+#endif
+
+#if defined(BN_MP_FWRITE_C)
+ #define BN_MP_RADIX_SIZE_C
+ #define BN_MP_TORADIX_C
+#endif
+
+#if defined(BN_MP_GCD_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_ABS_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CNT_LSB_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_EXCH_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_GET_INT_C)
+#endif
+
+#if defined(BN_MP_GROW_C)
+#endif
+
+#if defined(BN_MP_INIT_C)
+#endif
+
+#if defined(BN_MP_INIT_COPY_C)
+ #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_INIT_MULTI_C)
+ #define BN_MP_ERR_C
+ #define BN_MP_INIT_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_INIT_SET_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_C
+#endif
+
+#if defined(BN_MP_INIT_SET_INT_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_INT_C
+#endif
+
+#if defined(BN_MP_INIT_SIZE_C)
+ #define BN_MP_INIT_C
+#endif
+
+#if defined(BN_MP_INVMOD_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_ISODD_C
+ #define BN_FAST_MP_INVMOD_C
+ #define BN_MP_INVMOD_SLOW_C
+#endif
+
+#if defined(BN_MP_INVMOD_SLOW_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_MOD_C
+ #define BN_MP_COPY_C
+ #define BN_MP_ISEVEN_C
+ #define BN_MP_SET_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_ISODD_C
+ #define BN_MP_ADD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CMP_C
+ #define BN_MP_CMP_D_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_IS_SQUARE_C)
+ #define BN_MP_MOD_D_C
+ #define BN_MP_INIT_SET_INT_C
+ #define BN_MP_MOD_C
+ #define BN_MP_GET_INT_C
+ #define BN_MP_SQRT_C
+ #define BN_MP_SQR_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_JACOBI_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CNT_LSB_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_MOD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_MUL_C)
+ #define BN_MP_MUL_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_SUB_C
+ #define BN_MP_ADD_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_SQR_C)
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_SQR_C
+ #define BN_MP_SUB_C
+ #define BN_S_MP_ADD_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_ADD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_LCM_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_GCD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_DIV_C
+ #define BN_MP_MUL_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_LSHD_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_RSHD_C
+#endif
+
+#if defined(BN_MP_MOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_DIV_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_ADD_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_MOD_2D_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_COPY_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MOD_D_C)
+ #define BN_MP_DIV_D_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_2EXPT_C
+ #define BN_MP_SET_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_REDUCE_C)
+ #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_SETUP_C)
+#endif
+
+#if defined(BN_MP_MUL_C)
+ #define BN_MP_TOOM_MUL_C
+ #define BN_MP_KARATSUBA_MUL_C
+ #define BN_FAST_S_MP_MUL_DIGS_C
+ #define BN_S_MP_MUL_C
+ #define BN_S_MP_MUL_DIGS_C
+#endif
+
+#if defined(BN_MP_MUL_2_C)
+ #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_MUL_2D_C)
+ #define BN_MP_COPY_C
+ #define BN_MP_GROW_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MUL_D_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MULMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_MUL_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_N_ROOT_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_C
+ #define BN_MP_COPY_C
+ #define BN_MP_EXPT_D_C
+ #define BN_MP_MUL_C
+ #define BN_MP_SUB_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_DIV_C
+ #define BN_MP_CMP_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_NEG_C)
+ #define BN_MP_COPY_C
+ #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_OR_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_FERMAT_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_INIT_C
+ #define BN_MP_EXPTMOD_C
+ #define BN_MP_CMP_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
+ #define BN_MP_MOD_D_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_PRIME_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_PRIME_IS_DIVISIBLE_C
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_C
+ #define BN_MP_PRIME_MILLER_RABIN_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_MILLER_RABIN_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_CNT_LSB_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_EXPTMOD_C
+ #define BN_MP_CMP_C
+ #define BN_MP_SQRMOD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_NEXT_PRIME_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_SET_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_ISEVEN_C
+ #define BN_MP_MOD_D_C
+ #define BN_MP_INIT_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_PRIME_MILLER_RABIN_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
+#endif
+
+#if defined(BN_MP_PRIME_RANDOM_EX_C)
+ #define BN_MP_READ_UNSIGNED_BIN_C
+ #define BN_MP_PRIME_IS_PRIME_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_ADD_D_C
+#endif
+
+#if defined(BN_MP_RADIX_SIZE_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_DIV_D_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_RADIX_SMAP_C)
+ #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_RAND_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_LSHD_C
+#endif
+
+#if defined(BN_MP_READ_RADIX_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_S_RMAP_C
+ #define BN_MP_RADIX_SMAP_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_READ_SIGNED_BIN_C)
+ #define BN_MP_READ_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_READ_UNSIGNED_BIN_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_REDUCE_C)
+ #define BN_MP_REDUCE_SETUP_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_MUL_C
+ #define BN_S_MP_MUL_HIGH_DIGS_C
+ #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ #define BN_MP_MOD_2D_C
+ #define BN_S_MP_MUL_DIGS_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CMP_D_C
+ #define BN_MP_SET_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_ADD_C
+ #define BN_MP_CMP_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_MUL_D_C
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_L_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_MUL_C
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_2EXPT_C
+ #define BN_MP_CLEAR_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_L_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_2EXPT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_C)
+ #define BN_MP_REDUCE_2K_C
+ #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_L_C)
+#endif
+
+#if defined(BN_MP_REDUCE_SETUP_C)
+ #define BN_MP_2EXPT_C
+ #define BN_MP_DIV_C
+#endif
+
+#if defined(BN_MP_RSHD_C)
+ #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_C)
+ #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_INT_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SHRINK_C)
+#endif
+
+#if defined(BN_MP_SIGNED_BIN_SIZE_C)
+ #define BN_MP_UNSIGNED_BIN_SIZE_C
+#endif
+
+#if defined(BN_MP_SQR_C)
+ #define BN_MP_TOOM_SQR_C
+ #define BN_MP_KARATSUBA_SQR_C
+ #define BN_FAST_S_MP_SQR_C
+ #define BN_S_MP_SQR_C
+#endif
+
+#if defined(BN_MP_SQRMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SQR_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_SQRT_C)
+ #define BN_MP_N_ROOT_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_DIV_C
+ #define BN_MP_ADD_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_SUB_C)
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_SUB_D_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SUBMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_C)
+ #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_N_C)
+ #define BN_MP_SIGNED_BIN_SIZE_C
+ #define BN_MP_TO_SIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
+ #define BN_MP_UNSIGNED_BIN_SIZE_C
+ #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TOOM_MUL_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_MOD_2D_C
+ #define BN_MP_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_MUL_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_ADD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_DIV_3_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TOOM_SQR_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_MOD_2D_C
+ #define BN_MP_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_SQR_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_ADD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_DIV_3_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TORADIX_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_DIV_D_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_TORADIX_N_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_DIV_D_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
+ #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_XOR_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_ZERO_C)
+#endif
+
+#if defined(BN_PRIME_TAB_C)
+#endif
+
+#if defined(BN_REVERSE_C)
+#endif
+
+#if defined(BN_S_MP_ADD_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_S_MP_EXPTMOD_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_INIT_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_REDUCE_SETUP_C
+ #define BN_MP_REDUCE_C
+ #define BN_MP_REDUCE_2K_SETUP_L_C
+ #define BN_MP_REDUCE_2K_L_C
+ #define BN_MP_MOD_C
+ #define BN_MP_COPY_C
+ #define BN_MP_SQR_C
+ #define BN_MP_MUL_C
+ #define BN_MP_SET_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_S_MP_MUL_DIGS_C)
+ #define BN_FAST_S_MP_MUL_DIGS_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_MUL_HIGH_DIGS_C)
+ #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SQR_C)
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SUB_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BNCORE_C)
+#endif
+
+#ifdef LTM3
+#define LTM_LAST
+#endif
+#include <tommath_superclass.h>
+#include <tommath_class.h>
+#else
+#define LTM_LAST
+#endif
+
+/* $Source: /cvs/libtom/libtommath/tommath_class.h,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/07/28 11:59:32 $ */
diff --git a/source4/heimdal/lib/hcrypto/libtommath/tommath_superclass.h b/source4/heimdal/lib/hcrypto/libtommath/tommath_superclass.h
new file mode 100644
index 0000000000..2fdebe6838
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/libtommath/tommath_superclass.h
@@ -0,0 +1,76 @@
+/* super class file for PK algos */
+
+/* default ... include all MPI */
+#define LTM_ALL
+
+/* RSA only (does not support DH/DSA/ECC) */
+/* #define SC_RSA_1 */
+
+/* For reference.... On an Athlon64 optimizing for speed...
+
+ LTM's mpi.o with all functions [striped] is 142KiB in size.
+
+*/
+
+/* Works for RSA only, mpi.o is 68KiB */
+#ifdef SC_RSA_1
+ #define BN_MP_SHRINK_C
+ #define BN_MP_LCM_C
+ #define BN_MP_PRIME_RANDOM_EX_C
+ #define BN_MP_INVMOD_C
+ #define BN_MP_GCD_C
+ #define BN_MP_MOD_C
+ #define BN_MP_MULMOD_C
+ #define BN_MP_ADDMOD_C
+ #define BN_MP_EXPTMOD_C
+ #define BN_MP_SET_INT_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_CLEAR_MULTI_C
+ #define BN_MP_UNSIGNED_BIN_SIZE_C
+ #define BN_MP_TO_UNSIGNED_BIN_C
+ #define BN_MP_MOD_D_C
+ #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+ #define BN_REVERSE_C
+ #define BN_PRIME_TAB_C
+
+ /* other modifiers */
+ #define BN_MP_DIV_SMALL /* Slower division, not critical */
+
+ /* here we are on the last pass so we turn things off. The functions classes are still there
+ * but we remove them specifically from the build. This also invokes tweaks in functions
+ * like removing support for even moduli, etc...
+ */
+#ifdef LTM_LAST
+ #undef BN_MP_TOOM_MUL_C
+ #undef BN_MP_TOOM_SQR_C
+ #undef BN_MP_KARATSUBA_MUL_C
+ #undef BN_MP_KARATSUBA_SQR_C
+ #undef BN_MP_REDUCE_C
+ #undef BN_MP_REDUCE_SETUP_C
+ #undef BN_MP_DR_IS_MODULUS_C
+ #undef BN_MP_DR_SETUP_C
+ #undef BN_MP_DR_REDUCE_C
+ #undef BN_MP_REDUCE_IS_2K_C
+ #undef BN_MP_REDUCE_2K_SETUP_C
+ #undef BN_MP_REDUCE_2K_C
+ #undef BN_S_MP_EXPTMOD_C
+ #undef BN_MP_DIV_3_C
+ #undef BN_S_MP_MUL_HIGH_DIGS_C
+ #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ #undef BN_FAST_MP_INVMOD_C
+
+ /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
+ * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
+ * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
+ * trouble.
+ */
+ #undef BN_S_MP_MUL_DIGS_C
+ #undef BN_S_MP_SQR_C
+ #undef BN_MP_MONTGOMERY_REDUCE_C
+#endif
+
+#endif
+
+/* $Source: /cvs/libtom/libtommath/tommath_superclass.h,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/14 13:29:17 $ */
diff --git a/source4/heimdal/lib/hcrypto/md4.c b/source4/heimdal/lib/hcrypto/md4.c
index 435e662a42..1a9f77fed2 100644
--- a/source4/heimdal/lib/hcrypto/md4.c
+++ b/source4/heimdal/lib/hcrypto/md4.c
@@ -191,10 +191,10 @@ MD4_Update (struct md4 *m, const void *v, size_t len)
#if defined(WORDS_BIGENDIAN)
int i;
uint32_t current[16];
- struct x32 *u = (struct x32*)m->save;
+ struct x32 *us = (struct x32*)m->save;
for(i = 0; i < 8; i++){
- current[2*i+0] = swap_uint32_t(u[i].a);
- current[2*i+1] = swap_uint32_t(u[i].b);
+ current[2*i+0] = swap_uint32_t(us[i].a);
+ current[2*i+1] = swap_uint32_t(us[i].b);
}
calc(m, current);
#else
diff --git a/source4/heimdal/lib/hcrypto/md5.c b/source4/heimdal/lib/hcrypto/md5.c
index f99078737b..b35c76e293 100644
--- a/source4/heimdal/lib/hcrypto/md5.c
+++ b/source4/heimdal/lib/hcrypto/md5.c
@@ -215,10 +215,10 @@ MD5_Update (struct md5 *m, const void *v, size_t len)
#if defined(WORDS_BIGENDIAN)
int i;
uint32_t current[16];
- struct x32 *u = (struct x32*)m->save;
+ struct x32 *us = (struct x32*)m->save;
for(i = 0; i < 8; i++){
- current[2*i+0] = swap_uint32_t(u[i].a);
- current[2*i+1] = swap_uint32_t(u[i].b);
+ current[2*i+0] = swap_uint32_t(us[i].a);
+ current[2*i+1] = swap_uint32_t(us[i].b);
}
calc(m, current);
#else
diff --git a/source4/heimdal/lib/hcrypto/rand-fortuna.c b/source4/heimdal/lib/hcrypto/rand-fortuna.c
index c81eb9e2d7..11027b46cf 100644
--- a/source4/heimdal/lib/hcrypto/rand-fortuna.c
+++ b/source4/heimdal/lib/hcrypto/rand-fortuna.c
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <rand.h>
+#include <heim_threads.h>
#ifdef KRB5
#include <krb5-types.h>
@@ -442,10 +443,20 @@ static int have_entropy;
static unsigned resend_bytes;
/*
+ * This mutex protects all of the above static elements from concurrent
+ * access by multiple threads
+ */
+static HEIMDAL_MUTEX fortuna_mutex = HEIMDAL_MUTEX_INITIALIZER;
+
+/*
* Try our best to do an inital seed
*/
#define INIT_BYTES 128
+/*
+ * fortuna_mutex must be held across calls to this function
+ */
+
static int
fortuna_reseed(void)
{
@@ -537,6 +548,9 @@ fortuna_reseed(void)
return entropy_p;
}
+/*
+ * fortuna_mutex must be held by callers of this function
+ */
static int
fortuna_init(void)
{
@@ -555,32 +569,50 @@ fortuna_init(void)
static void
fortuna_seed(const void *indata, int size)
{
+ HEIMDAL_MUTEX_lock(&fortuna_mutex);
+
fortuna_init();
add_entropy(&main_state, indata, size);
if (size >= INIT_BYTES)
have_entropy = 1;
+
+ HEIMDAL_MUTEX_unlock(&fortuna_mutex);
}
static int
fortuna_bytes(unsigned char *outdata, int size)
{
+ int ret = 0;
+
+ HEIMDAL_MUTEX_lock(&fortuna_mutex);
+
if (!fortuna_init())
- return 0;
+ goto out;
+
resend_bytes += size;
if (resend_bytes > FORTUNA_RESEED_BYTE || resend_bytes < size) {
resend_bytes = 0;
fortuna_reseed();
}
extract_data(&main_state, size, outdata);
- return 1;
+ ret = 1;
+
+out:
+ HEIMDAL_MUTEX_unlock(&fortuna_mutex);
+
+ return ret;
}
static void
fortuna_cleanup(void)
{
+ HEIMDAL_MUTEX_lock(&fortuna_mutex);
+
init_done = 0;
have_entropy = 0;
memset(&main_state, 0, sizeof(main_state));
+
+ HEIMDAL_MUTEX_unlock(&fortuna_mutex);
}
static void
@@ -598,7 +630,13 @@ fortuna_pseudorand(unsigned char *outdata, int size)
static int
fortuna_status(void)
{
- return fortuna_init() ? 1 : 0;
+ int result;
+
+ HEIMDAL_MUTEX_lock(&fortuna_mutex);
+ result = fortuna_init();
+ HEIMDAL_MUTEX_unlock(&fortuna_mutex);
+
+ return result ? 1 : 0;
}
const RAND_METHOD hc_rand_fortuna_method = {
diff --git a/source4/heimdal/lib/hcrypto/rand-unix.c b/source4/heimdal/lib/hcrypto/rand-unix.c
index 63dc97fbfa..c52155baaa 100644
--- a/source4/heimdal/lib/hcrypto/rand-unix.c
+++ b/source4/heimdal/lib/hcrypto/rand-unix.c
@@ -47,7 +47,7 @@
*/
int
-_hc_unix_device_fd(int flags, char **fn)
+_hc_unix_device_fd(int flags, const char **fn)
{
static const char *rnd_devices[] = {
"/dev/urandom",
diff --git a/source4/heimdal/lib/hcrypto/rand.c b/source4/heimdal/lib/hcrypto/rand.c
index d360ffcab4..d5c1f687b9 100644
--- a/source4/heimdal/lib/hcrypto/rand.c
+++ b/source4/heimdal/lib/hcrypto/rand.c
@@ -46,6 +46,10 @@
#define O_BINARY 0
#endif
+#ifdef _WIN32
+#include<shlobj.h>
+#endif
+
/**
* @page page_rand RAND - random number
*
@@ -342,7 +346,7 @@ RAND_write_file(const char *filename)
const char *
RAND_file_name(char *filename, size_t size)
{
- char *e = NULL;
+ const char *e = NULL;
int pathp = 0, ret;
if (!issuid()) {
@@ -352,6 +356,8 @@ RAND_file_name(char *filename, size_t size)
if (e)
pathp = 1;
}
+
+#ifndef _WIN32
/*
* Here we really want to call getpwuid(getuid()) but this will
* cause recursive lookups if the nss library uses
@@ -359,7 +365,6 @@ RAND_file_name(char *filename, size_t size)
*
* So at least return the unix /dev/random if we have one
*/
-#ifndef _WIN32
if (e == NULL) {
int fd;
@@ -367,7 +372,22 @@ RAND_file_name(char *filename, size_t size)
if (fd >= 0)
close(fd);
}
+#else /* Win32 */
+
+ if (e == NULL) {
+ char profile[MAX_PATH];
+
+ if (SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL,
+ SHGFP_TYPE_CURRENT, profile) == S_OK) {
+ ret = snprintf(filename, size, "%s\\.rnd", profile);
+
+ if (ret > 0 && ret < size)
+ return filename;
+ }
+ }
+
#endif
+
if (e == NULL)
return NULL;
diff --git a/source4/heimdal/lib/hcrypto/rand.h b/source4/heimdal/lib/hcrypto/rand.h
index f4e2485166..590bd8cf1a 100644
--- a/source4/heimdal/lib/hcrypto/rand.h
+++ b/source4/heimdal/lib/hcrypto/rand.h
@@ -41,7 +41,6 @@
typedef struct RAND_METHOD RAND_METHOD;
-#include <hcrypto/bn.h>
#include <hcrypto/engine.h>
/* symbol renaming */
@@ -105,5 +104,6 @@ int RAND_egd_bytes(const char *, int);
const RAND_METHOD * RAND_fortuna_method(void);
const RAND_METHOD * RAND_unix_method(void);
const RAND_METHOD * RAND_egd_method(void);
+const RAND_METHOD * RAND_w32crypto_method(void);
#endif /* _HEIM_RAND_H */
diff --git a/source4/heimdal/lib/hcrypto/randi.h b/source4/heimdal/lib/hcrypto/randi.h
index a6d921413a..fe021a80ec 100644
--- a/source4/heimdal/lib/hcrypto/randi.h
+++ b/source4/heimdal/lib/hcrypto/randi.h
@@ -45,6 +45,6 @@ extern const RAND_METHOD hc_rand_timer_method;
extern const RAND_METHOD hc_rand_w32crypto_method;
const RAND_METHOD * RAND_timer_method(void);
-int _hc_unix_device_fd(int, char **);
+int _hc_unix_device_fd(int, const char **);
#endif /* _HEIM_RANDI_H */
diff --git a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c
index 9a7f0fd3d6..bf335afd9f 100644
--- a/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c
+++ b/source4/heimdal/lib/hcrypto/rijndael-alg-fst.c
@@ -38,11 +38,6 @@
#include "rijndael-alg-fst.h"
-/* the file should not be used from outside */
-typedef uint8_t u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-
/*
Te0[x] = S [x].[02, 01, 01, 03];
Te1[x] = S [x].[03, 02, 01, 01];
@@ -57,7 +52,7 @@ Td3[x] = Si[x].[09, 0d, 0b, 0e];
Td4[x] = Si[x].[01, 01, 01, 01];
*/
-static const u32 Te0[256] = {
+static const uint32_t Te0[256] = {
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
@@ -123,7 +118,7 @@ static const u32 Te0[256] = {
0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
};
-static const u32 Te1[256] = {
+static const uint32_t Te1[256] = {
0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
@@ -189,7 +184,7 @@ static const u32 Te1[256] = {
0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
};
-static const u32 Te2[256] = {
+static const uint32_t Te2[256] = {
0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
@@ -255,7 +250,7 @@ static const u32 Te2[256] = {
0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
};
-static const u32 Te3[256] = {
+static const uint32_t Te3[256] = {
0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
@@ -322,7 +317,7 @@ static const u32 Te3[256] = {
0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
};
-static const u32 Te4[256] = {
+static const uint32_t Te4[256] = {
0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
@@ -388,7 +383,7 @@ static const u32 Te4[256] = {
0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
};
-static const u32 Td0[256] = {
+static const uint32_t Td0[256] = {
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
@@ -454,7 +449,7 @@ static const u32 Td0[256] = {
0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
};
-static const u32 Td1[256] = {
+static const uint32_t Td1[256] = {
0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
@@ -520,7 +515,7 @@ static const u32 Td1[256] = {
0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
};
-static const u32 Td2[256] = {
+static const uint32_t Td2[256] = {
0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
@@ -587,7 +582,7 @@ static const u32 Td2[256] = {
0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
};
-static const u32 Td3[256] = {
+static const uint32_t Td3[256] = {
0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
@@ -653,7 +648,7 @@ static const u32 Td3[256] = {
0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
};
-static const u32 Td4[256] = {
+static const uint32_t Td4[256] = {
0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
@@ -719,7 +714,7 @@ static const u32 Td4[256] = {
0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
};
-static const u32 rcon[] = {
+static const uint32_t rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000,
0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
@@ -728,11 +723,11 @@ static const u32 rcon[] = {
#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
#ifdef _MSC_VER
-#define GETU32(p) SWAP(*((u32 *)(p)))
-#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+#define GETU32(p) SWAP(*((uint32_t *)(p)))
+#define PUTU32(ct, st) { *((uint32_t *)(ct)) = SWAP((st)); }
#else
-#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
-#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
+#define GETU32(pt) (((uint32_t)(pt)[0] << 24) ^ ((uint32_t)(pt)[1] << 16) ^ ((uint32_t)(pt)[2] << 8) ^ ((uint32_t)(pt)[3]))
+#define PUTU32(ct, st) { (ct)[0] = (uint8_t)((st) >> 24); (ct)[1] = (uint8_t)((st) >> 16); (ct)[2] = (uint8_t)((st) >> 8); (ct)[3] = (uint8_t)(st); }
#endif
/**
@@ -740,9 +735,9 @@ static const u32 rcon[] = {
*
* @return the number of rounds for the given cipher key size.
*/
-int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
+int rijndaelKeySetupEnc(uint32_t rk[/*4*(Nr + 1)*/], const uint8_t cipherKey[], int keyBits) {
int i = 0;
- u32 temp;
+ uint32_t temp;
rk[0] = GETU32(cipherKey );
rk[1] = GETU32(cipherKey + 4);
@@ -826,9 +821,9 @@ int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBit
*
* @return the number of rounds for the given cipher key size.
*/
-int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
+int rijndaelKeySetupDec(uint32_t rk[/*4*(Nr + 1)*/], const uint8_t cipherKey[], int keyBits) {
int Nr, i, j;
- u32 temp;
+ uint32_t temp;
/* expand the cipher key: */
Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
@@ -866,8 +861,8 @@ int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBit
return Nr;
}
-void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) {
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
+void rijndaelEncrypt(const uint32_t rk[/*4*(Nr + 1)*/], int Nr, const uint8_t pt[16], uint8_t ct[16]) {
+ uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
#ifndef FULL_UNROLL
int r;
#endif /* ?FULL_UNROLL */
@@ -1047,8 +1042,8 @@ void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 c
PUTU32(ct + 12, s3);
}
-void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) {
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
+void rijndaelDecrypt(const uint32_t rk[/*4*(Nr + 1)*/], int Nr, const uint8_t ct[16], uint8_t pt[16]) {
+ uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
#ifndef FULL_UNROLL
int r;
#endif /* ?FULL_UNROLL */
diff --git a/source4/heimdal/lib/hcrypto/rsa-imath.c b/source4/heimdal/lib/hcrypto/rsa-imath.c
index a2b9d2a678..23d5352700 100644
--- a/source4/heimdal/lib/hcrypto/rsa-imath.c
+++ b/source4/heimdal/lib/hcrypto/rsa-imath.c
@@ -42,6 +42,8 @@
#include <roken.h>
+#ifdef USE_HCRYPTO_IMATH
+
#include "imath/imath.h"
#include "imath/iprime.h"
@@ -406,7 +408,7 @@ imath_rsa_private_decrypt(int flen, const unsigned char* from,
{
unsigned char *ptr;
mp_result res;
- size_t size;
+ int size;
mpz_t in, out, n, e, b, bi;
int blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0;
int do_unblind = 0;
@@ -673,9 +675,14 @@ const RSA_METHOD hc_rsa_imath_method = {
NULL,
imath_rsa_generate_key
};
+#endif
const RSA_METHOD *
RSA_imath_method(void)
{
+#ifdef USE_HCRYPTO_IMATH
return &hc_rsa_imath_method;
+#else
+ return NULL;
+#endif
}
diff --git a/source4/heimdal/lib/hcrypto/rsa-ltm.c b/source4/heimdal/lib/hcrypto/rsa-ltm.c
new file mode 100644
index 0000000000..ad3686e403
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/rsa-ltm.c
@@ -0,0 +1,630 @@
+/*
+ * Copyright (c) 2006 - 2007, 2010 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <krb5-types.h>
+#include <assert.h>
+
+#include <rsa.h>
+
+#include <roken.h>
+
+#include "tommath.h"
+
+static int
+random_num(mp_int *num, size_t len)
+{
+ unsigned char *p;
+
+ len = (len + 7) / 8;
+ p = malloc(len);
+ if (p == NULL)
+ return 1;
+ if (RAND_bytes(p, len) != 1) {
+ free(p);
+ return 1;
+ }
+ mp_read_unsigned_bin(num, p, len);
+ free(p);
+ return 0;
+}
+
+static void
+BN2mpz(mp_int *s, const BIGNUM *bn)
+{
+ size_t len;
+ void *p;
+
+ len = BN_num_bytes(bn);
+ p = malloc(len);
+ BN_bn2bin(bn, p);
+ mp_read_unsigned_bin(s, p, len);
+ free(p);
+}
+
+static void
+setup_blind(mp_int *n, mp_int *b, mp_int *bi)
+{
+ random_num(b, mp_count_bits(n));
+ mp_mod(b, n, b);
+ mp_invmod(b, n, bi);
+}
+
+static void
+blind(mp_int *in, mp_int *b, mp_int *e, mp_int *n)
+{
+ mp_int t1;
+ mp_init(&t1);
+ /* in' = (in * b^e) mod n */
+ mp_exptmod(b, e, n, &t1);
+ mp_mul(&t1, in, in);
+ mp_mod(in, n, in);
+ mp_clear(&t1);
+}
+
+static void
+unblind(mp_int *out, mp_int *bi, mp_int *n)
+{
+ /* out' = (out * 1/b) mod n */
+ mp_mul(out, bi, out);
+ mp_mod(out, n, out);
+}
+
+static int
+ltm_rsa_private_calculate(mp_int * in, mp_int * p, mp_int * q,
+ mp_int * dmp1, mp_int * dmq1, mp_int * iqmp,
+ mp_int * out)
+{
+ mp_int vp, vq, u;
+
+ mp_init_multi(&vp, &vq, &u, NULL);
+
+ /* vq = c ^ (d mod (q - 1)) mod q */
+ /* vp = c ^ (d mod (p - 1)) mod p */
+ mp_mod(in, p, &u);
+ mp_exptmod(&u, dmp1, p, &vp);
+ mp_mod(in, q, &u);
+ mp_exptmod(&u, dmq1, q, &vq);
+
+ /* C2 = 1/q mod p (iqmp) */
+ /* u = (vp - vq)C2 mod p. */
+ mp_sub(&vp, &vq, &u);
+ if (mp_isneg(&u))
+ mp_add(&u, p, &u);
+ mp_mul(&u, iqmp, &u);
+ mp_mod(&u, p, &u);
+
+ /* c ^ d mod n = vq + u q */
+ mp_mul(&u, q, &u);
+ mp_add(&u, &vq, out);
+
+ mp_clear_multi(&vp, &vq, &u, NULL);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int
+ltm_rsa_public_encrypt(int flen, const unsigned char* from,
+ unsigned char* to, RSA* rsa, int padding)
+{
+ unsigned char *p, *p0;
+ int res;
+ size_t size, padlen;
+ mp_int enc, dec, n, e;
+
+ if (padding != RSA_PKCS1_PADDING)
+ return -1;
+
+ mp_init_multi(&n, &e, &enc, &dec, NULL);
+
+ size = RSA_size(rsa);
+
+ if (size < RSA_PKCS1_PADDING_SIZE || size - RSA_PKCS1_PADDING_SIZE < flen) {
+ mp_clear_multi(&n, &e, &enc, &dec);
+ return -2;
+ }
+
+ BN2mpz(&n, rsa->n);
+ BN2mpz(&e, rsa->e);
+
+ p = p0 = malloc(size - 1);
+ if (p0 == NULL) {
+ mp_clear_multi(&e, &n, &enc, &dec, NULL);
+ return -3;
+ }
+
+ padlen = size - flen - 3;
+
+ *p++ = 2;
+ if (RAND_bytes(p, padlen) != 1) {
+ mp_clear_multi(&e, &n, &enc, &dec, NULL);
+ free(p0);
+ return -4;
+ }
+ while(padlen) {
+ if (*p == 0)
+ *p = 1;
+ padlen--;
+ p++;
+ }
+ *p++ = 0;
+ memcpy(p, from, flen);
+ p += flen;
+ assert((p - p0) == size - 1);
+
+ mp_read_unsigned_bin(&dec, p0, size - 1);
+ free(p0);
+
+ res = mp_exptmod(&dec, &e, &n, &enc);
+
+ mp_clear_multi(&dec, &e, &n, NULL);
+
+ if (res != 0) {
+ mp_clear(&enc);
+ return -4;
+ }
+
+ {
+ size_t ssize;
+ ssize = mp_unsigned_bin_size(&enc);
+ assert(size >= ssize);
+ mp_to_unsigned_bin(&enc, to);
+ size = ssize;
+ }
+ mp_clear(&enc);
+
+ return size;
+}
+
+static int
+ltm_rsa_public_decrypt(int flen, const unsigned char* from,
+ unsigned char* to, RSA* rsa, int padding)
+{
+ unsigned char *p;
+ int res;
+ size_t size;
+ mp_int s, us, n, e;
+
+ if (padding != RSA_PKCS1_PADDING)
+ return -1;
+
+ if (flen > RSA_size(rsa))
+ return -2;
+
+ mp_init_multi(&e, &n, &s, &us, NULL);
+
+ BN2mpz(&n, rsa->n);
+ BN2mpz(&e, rsa->e);
+
+#if 0
+ /* Check that the exponent is larger then 3 */
+ if (mp_int_compare_value(&e, 3) <= 0) {
+ mp_clear_multi(&e, &n, &s, &us, NULL);
+ return -3;
+ }
+#endif
+
+ mp_read_unsigned_bin(&s, rk_UNCONST(from), flen);
+
+ if (mp_cmp(&s, &n) >= 0) {
+ mp_clear_multi(&e, &n, &s, &us, NULL);
+ return -4;
+ }
+
+ res = mp_exptmod(&s, &e, &n, &us);
+
+ mp_clear_multi(&e, &n, &s, NULL);
+
+ if (res != 0) {
+ mp_clear(&us);
+ return -5;
+ }
+ p = to;
+
+
+ size = mp_unsigned_bin_size(&us);
+ assert(size <= RSA_size(rsa));
+ mp_to_unsigned_bin(&us, p);
+
+ mp_clear(&us);
+
+ /* head zero was skipped by mp_to_unsigned_bin */
+ if (*p == 0)
+ return -6;
+ if (*p != 1)
+ return -7;
+ size--; p++;
+ while (size && *p == 0xff) {
+ size--; p++;
+ }
+ if (size == 0 || *p != 0)
+ return -8;
+ size--; p++;
+
+ memmove(to, p, size);
+
+ return size;
+}
+
+static int
+ltm_rsa_private_encrypt(int flen, const unsigned char* from,
+ unsigned char* to, RSA* rsa, int padding)
+{
+ unsigned char *p, *p0;
+ int res;
+ int size;
+ mp_int in, out, n, e;
+ mp_int bi, b;
+ int blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0;
+ int do_unblind = 0;
+
+ if (padding != RSA_PKCS1_PADDING)
+ return -1;
+
+ mp_init_multi(&e, &n, &in, &out, &b, &bi, NULL);
+
+ size = RSA_size(rsa);
+
+ if (size < RSA_PKCS1_PADDING_SIZE || size - RSA_PKCS1_PADDING_SIZE < flen)
+ return -2;
+
+ p0 = p = malloc(size);
+ *p++ = 0;
+ *p++ = 1;
+ memset(p, 0xff, size - flen - 3);
+ p += size - flen - 3;
+ *p++ = 0;
+ memcpy(p, from, flen);
+ p += flen;
+ assert((p - p0) == size);
+
+ BN2mpz(&n, rsa->n);
+ BN2mpz(&e, rsa->e);
+
+ mp_read_unsigned_bin(&in, p0, size);
+ free(p0);
+
+ if(mp_isneg(&in) || mp_cmp(&in, &n) >= 0) {
+ size = -3;
+ goto out;
+ }
+
+ if (blinding) {
+ setup_blind(&n, &b, &bi);
+ blind(&in, &b, &e, &n);
+ do_unblind = 1;
+ }
+
+ if (rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) {
+ mp_int p, q, dmp1, dmq1, iqmp;
+
+ mp_init_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL);
+
+ BN2mpz(&p, rsa->p);
+ BN2mpz(&q, rsa->q);
+ BN2mpz(&dmp1, rsa->dmp1);
+ BN2mpz(&dmq1, rsa->dmq1);
+ BN2mpz(&iqmp, rsa->iqmp);
+
+ res = ltm_rsa_private_calculate(&in, &p, &q, &dmp1, &dmq1, &iqmp, &out);
+
+ mp_clear_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL);
+
+ if (res != 0) {
+ size = -4;
+ goto out;
+ }
+ } else {
+ mp_int d;
+
+ BN2mpz(&d, rsa->d);
+ res = mp_exptmod(&in, &d, &n, &out);
+ mp_clear(&d);
+ if (res != 0) {
+ size = -5;
+ goto out;
+ }
+ }
+
+ if (do_unblind)
+ unblind(&out, &bi, &n);
+
+ if (size > 0) {
+ size_t ssize;
+ ssize = mp_unsigned_bin_size(&out);
+ assert(size >= ssize);
+ mp_to_unsigned_bin(&out, to);
+ size = ssize;
+ }
+
+ out:
+ mp_clear_multi(&e, &n, &in, &out, &b, &bi, NULL);
+
+ return size;
+}
+
+static int
+ltm_rsa_private_decrypt(int flen, const unsigned char* from,
+ unsigned char* to, RSA* rsa, int padding)
+{
+ unsigned char *ptr;
+ int res;
+ size_t size;
+ mp_int in, out, n, e, b, bi;
+ int blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0;
+ int do_unblind = 0;
+
+ if (padding != RSA_PKCS1_PADDING)
+ return -1;
+
+ size = RSA_size(rsa);
+ if (flen > size)
+ return -2;
+
+ mp_init_multi(&in, &n, &e, &out, &bi, &b, NULL);
+
+ BN2mpz(&n, rsa->n);
+ BN2mpz(&e, rsa->e);
+
+ mp_read_unsigned_bin(&in, rk_UNCONST(from), flen);
+
+ if(mp_isneg(&in) || mp_cmp(&in, &n) >= 0) {
+ size = -2;
+ goto out;
+ }
+
+ if (blinding) {
+ setup_blind(&n, &b, &bi);
+ blind(&in, &b, &e, &n);
+ do_unblind = 1;
+ }
+
+ if (rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) {
+ mp_int p, q, dmp1, dmq1, iqmp;
+
+ mp_init_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL);
+
+ BN2mpz(&p, rsa->p);
+ BN2mpz(&q, rsa->q);
+ BN2mpz(&dmp1, rsa->dmp1);
+ BN2mpz(&dmq1, rsa->dmq1);
+ BN2mpz(&iqmp, rsa->iqmp);
+
+ res = ltm_rsa_private_calculate(&in, &p, &q, &dmp1, &dmq1, &iqmp, &out);
+
+ mp_clear_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL);
+
+ if (res != 0) {
+ size = -3;
+ goto out;
+ }
+
+ } else {
+ mp_int d;
+
+ if(mp_isneg(&in) || mp_cmp(&in, &n) >= 0)
+ return -4;
+
+ BN2mpz(&d, rsa->d);
+ res = mp_exptmod(&in, &d, &n, &out);
+ mp_clear(&d);
+ if (res != 0) {
+ size = -5;
+ goto out;
+ }
+ }
+
+ if (do_unblind)
+ unblind(&out, &bi, &n);
+
+ ptr = to;
+ {
+ size_t ssize;
+ ssize = mp_unsigned_bin_size(&out);
+ assert(size >= ssize);
+ mp_to_unsigned_bin(&out, ptr);
+ size = ssize;
+ }
+
+ /* head zero was skipped by mp_int_to_unsigned */
+ if (*ptr != 2) {
+ size = -6;
+ goto out;
+ }
+ size--; ptr++;
+ while (size && *ptr != 0) {
+ size--; ptr++;
+ }
+ if (size == 0)
+ return -7;
+ size--; ptr++;
+
+ memmove(to, ptr, size);
+
+ out:
+ mp_clear_multi(&e, &n, &in, &out, NULL);
+
+ return size;
+}
+
+static BIGNUM *
+mpz2BN(mp_int *s)
+{
+ size_t size;
+ BIGNUM *bn;
+ void *p;
+
+ size = mp_unsigned_bin_size(s);
+ p = malloc(size);
+ if (p == NULL && size != 0)
+ return NULL;
+
+ mp_to_unsigned_bin(s, p);
+
+ bn = BN_bin2bn(p, size, NULL);
+ free(p);
+ return bn;
+}
+
+#define CHECK(f, v) if ((f) != (v)) { goto out; }
+
+static int
+ltm_rsa_generate_key(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
+{
+ mp_int el, p, q, n, d, dmp1, dmq1, iqmp, t1, t2, t3;
+ int counter, ret, bitsp;
+
+ if (bits < 789)
+ return -1;
+
+ bitsp = (bits + 1) / 2;
+
+ ret = -1;
+
+ mp_init_multi(&el, &p, &q, &n, &n, &d, &dmp1, &dmq1, &iqmp, &t1, &t2, &t3, NULL);
+
+ BN2mpz(&el, e);
+
+ /* generate p and q so that p != q and bits(pq) ~ bits */
+ counter = 0;
+ do {
+ BN_GENCB_call(cb, 2, counter++);
+ CHECK(random_num(&p, bitsp), 0);
+ CHECK(mp_find_prime(&p), MP_YES);
+
+ mp_sub_d(&p, 1, &t1);
+ mp_gcd(&t1, &el, &t2);
+ } while(mp_cmp_d(&t2, 1) != 0);
+
+ BN_GENCB_call(cb, 3, 0);
+
+ counter = 0;
+ do {
+ BN_GENCB_call(cb, 2, counter++);
+ CHECK(random_num(&q, bits - bitsp), 0);
+ CHECK(mp_find_prime(&q), MP_YES);
+
+ if (mp_cmp(&p, &q) == 0) /* don't let p and q be the same */
+ continue;
+
+ mp_sub_d(&q, 1, &t1);
+ mp_gcd(&t1, &el, &t2);
+ } while(mp_cmp_d(&t2, 1) != 0);
+
+ /* make p > q */
+ if (mp_cmp(&p, &q) < 0) {
+ mp_int c;
+ c = p;
+ p = q;
+ q = c;
+ }
+
+ BN_GENCB_call(cb, 3, 1);
+
+ /* calculate n, n = p * q */
+ mp_mul(&p, &q, &n);
+
+ /* calculate d, d = 1/e mod (p - 1)(q - 1) */
+ mp_sub_d(&p, 1, &t1);
+ mp_sub_d(&q, 1, &t2);
+ mp_mul(&t1, &t2, &t3);
+ mp_invmod(&el, &t3, &d);
+
+ /* calculate dmp1 dmp1 = d mod (p-1) */
+ mp_mod(&d, &t1, &dmp1);
+ /* calculate dmq1 dmq1 = d mod (q-1) */
+ mp_mod(&d, &t2, &dmq1);
+ /* calculate iqmp iqmp = 1/q mod p */
+ mp_invmod(&q, &p, &iqmp);
+
+ /* fill in RSA key */
+
+ rsa->e = mpz2BN(&el);
+ rsa->p = mpz2BN(&p);
+ rsa->q = mpz2BN(&q);
+ rsa->n = mpz2BN(&n);
+ rsa->d = mpz2BN(&d);
+ rsa->dmp1 = mpz2BN(&dmp1);
+ rsa->dmq1 = mpz2BN(&dmq1);
+ rsa->iqmp = mpz2BN(&iqmp);
+
+ ret = 1;
+
+out:
+ mp_clear_multi(&el, &p, &q, &n, &d, &dmp1,
+ &dmq1, &iqmp, &t1, &t2, &t3, NULL);
+
+ return ret;
+}
+
+static int
+ltm_rsa_init(RSA *rsa)
+{
+ return 1;
+}
+
+static int
+ltm_rsa_finish(RSA *rsa)
+{
+ return 1;
+}
+
+const RSA_METHOD hc_rsa_ltm_method = {
+ "hcrypto ltm RSA",
+ ltm_rsa_public_encrypt,
+ ltm_rsa_public_decrypt,
+ ltm_rsa_private_encrypt,
+ ltm_rsa_private_decrypt,
+ NULL,
+ NULL,
+ ltm_rsa_init,
+ ltm_rsa_finish,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ ltm_rsa_generate_key
+};
+
+const RSA_METHOD *
+RSA_ltm_method(void)
+{
+ return &hc_rsa_ltm_method;
+}
diff --git a/source4/heimdal/lib/hcrypto/rsa.c b/source4/heimdal/lib/hcrypto/rsa.c
index 6a883454a3..a6e09fe283 100644
--- a/source4/heimdal/lib/hcrypto/rsa.c
+++ b/source4/heimdal/lib/hcrypto/rsa.c
@@ -38,8 +38,12 @@
#include <krb5-types.h>
#include <rfc2459_asn1.h>
+#include <der.h>
+
#include <rsa.h>
+#include "common.h"
+
#include <roken.h>
/**
@@ -48,6 +52,20 @@
* RSA is named by its inventors (Ron Rivest, Adi Shamir, and Leonard
* Adleman) (published in 1977), patented expired in 21 September 2000.
*
+ *
+ * Speed for RSA in seconds
+ * no key blinding
+ * 1000 iteration,
+ * same rsa key
+ * operation performed each eteration sign, verify, encrypt, decrypt on a random bit pattern
+ *
+ * gmp: 0.733615
+ * tfm: 2.450173
+ * ltm: 3.79 (default in hcrypto)
+ * openssl: 4.04
+ * cdsa: 15.89
+ * imath: 40.62
+ *
* See the library functions here: @ref hcrypto_rsa
*/
@@ -237,7 +255,7 @@ RSA_set_app_data(RSA *rsa, void *arg)
*/
void *
-RSA_get_app_data(RSA *rsa)
+RSA_get_app_data(const RSA *rsa)
{
return rsa->ex_data.sk;
}
@@ -303,19 +321,136 @@ RSAFUNC(RSA_public_decrypt, (r)->meth->rsa_pub_dec(flen, f, t, r, p))
RSAFUNC(RSA_private_encrypt, (r)->meth->rsa_priv_enc(flen, f, t, r, p))
RSAFUNC(RSA_private_decrypt, (r)->meth->rsa_priv_dec(flen, f, t, r, p))
-/* XXX */
+static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
+
+static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
+static const AlgorithmIdentifier _signature_sha1_data = {
+ { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
+static const AlgorithmIdentifier _signature_sha256_data = {
+ { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
+static const AlgorithmIdentifier _signature_md5_data = {
+ { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+
int
RSA_sign(int type, const unsigned char *from, unsigned int flen,
unsigned char *to, unsigned int *tlen, RSA *rsa)
{
- return -1;
+ if (rsa->meth->rsa_sign)
+ return rsa->meth->rsa_sign(type, from, flen, to, tlen, rsa);
+
+ if (rsa->meth->rsa_priv_enc) {
+ heim_octet_string indata;
+ DigestInfo di;
+ size_t size;
+ int ret;
+
+ memset(&di, 0, sizeof(di));
+
+ if (type == NID_sha1) {
+ di.digestAlgorithm = _signature_sha1_data;
+ } else if (type == NID_md5) {
+ di.digestAlgorithm = _signature_md5_data;
+ } else if (type == NID_sha256) {
+ di.digestAlgorithm = _signature_sha256_data;
+ } else
+ return -1;
+
+ di.digest.data = rk_UNCONST(from);
+ di.digest.length = flen;
+
+ ASN1_MALLOC_ENCODE(DigestInfo,
+ indata.data,
+ indata.length,
+ &di,
+ &size,
+ ret);
+ if (ret)
+ return ret;
+ if (indata.length != size)
+ abort();
+
+ ret = rsa->meth->rsa_priv_enc(indata.length, indata.data, to,
+ rsa, RSA_PKCS1_PADDING);
+ free(indata.data);
+ if (ret > 0) {
+ *tlen = ret;
+ ret = 1;
+ } else
+ ret = 0;
+
+ return ret;
+ }
+
+ return 0;
}
int
RSA_verify(int type, const unsigned char *from, unsigned int flen,
- unsigned char *to, unsigned int tlen, RSA *rsa)
+ unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
{
- return -1;
+ if (rsa->meth->rsa_verify)
+ return rsa->meth->rsa_verify(type, from, flen, sigbuf, siglen, rsa);
+
+ if (rsa->meth->rsa_pub_dec) {
+ const AlgorithmIdentifier *digest_alg;
+ void *data;
+ DigestInfo di;
+ size_t size;
+ int ret, ret2;
+
+ data = malloc(RSA_size(rsa));
+ if (data == NULL)
+ return -1;
+
+ memset(&di, 0, sizeof(di));
+
+ ret = rsa->meth->rsa_pub_dec(siglen, sigbuf, data, rsa, RSA_PKCS1_PADDING);
+ if (ret <= 0) {
+ free(data);
+ return -2;
+ }
+
+ ret2 = decode_DigestInfo(data, ret, &di, &size);
+ free(data);
+ if (ret2 != 0)
+ return -3;
+ if (ret != size) {
+ free_DigestInfo(&di);
+ return -4;
+ }
+
+ if (flen != di.digest.length || memcmp(di.digest.data, from, flen) != 0) {
+ free_DigestInfo(&di);
+ return -5;
+ }
+
+ if (type == NID_sha1) {
+ digest_alg = &_signature_sha1_data;
+ } else if (type == NID_md5) {
+ digest_alg = &_signature_md5_data;
+ } else if (type == NID_sha256) {
+ digest_alg = &_signature_sha256_data;
+ } else {
+ free_DigestInfo(&di);
+ return -1;
+ }
+
+ ret = der_heim_oid_cmp(&digest_alg->algorithm,
+ &di.digestAlgorithm.algorithm);
+ free_DigestInfo(&di);
+
+ if (ret != 0)
+ return 0;
+ return 1;
+ }
+
+ return 0;
}
/*
@@ -380,12 +515,12 @@ RSA_null_method(void)
return &rsa_null_method;
}
+extern const RSA_METHOD hc_rsa_gmp_method;
extern const RSA_METHOD hc_rsa_imath_method;
-#ifdef HAVE_GMP
-static const RSA_METHOD *default_rsa_method = &hc_rsa_gmp_method;
-#else
-static const RSA_METHOD *default_rsa_method = &hc_rsa_imath_method;
-#endif
+extern const RSA_METHOD hc_rsa_tfm_method;
+extern const RSA_METHOD hc_rsa_ltm_method;
+static const RSA_METHOD *default_rsa_method = &hc_rsa_ltm_method;
+
const RSA_METHOD *
RSA_get_default_method(void)
@@ -403,32 +538,6 @@ RSA_set_default_method(const RSA_METHOD *meth)
*
*/
-static BIGNUM *
-heim_int2BN(const heim_integer *i)
-{
- BIGNUM *bn;
-
- bn = BN_bin2bn(i->data, i->length, NULL);
- if (bn)
- BN_set_negative(bn, i->negative);
- return bn;
-}
-
-static int
-bn2heim_int(BIGNUM *bn, heim_integer *integer)
-{
- integer->length = BN_num_bytes(bn);
- integer->data = malloc(integer->length);
- if (integer->data == NULL) {
- integer->length = 0;
- return ENOMEM;
- }
- BN_bn2bin(bn, integer->data);
- integer->negative = BN_is_negative(bn);
- return 0;
-}
-
-
RSA *
d2i_RSAPrivateKey(RSA *rsa, const unsigned char **pp, size_t len)
{
@@ -451,14 +560,14 @@ d2i_RSAPrivateKey(RSA *rsa, const unsigned char **pp, size_t len)
}
}
- k->n = heim_int2BN(&data.modulus);
- k->e = heim_int2BN(&data.publicExponent);
- k->d = heim_int2BN(&data.privateExponent);
- k->p = heim_int2BN(&data.prime1);
- k->q = heim_int2BN(&data.prime2);
- k->dmp1 = heim_int2BN(&data.exponent1);
- k->dmq1 = heim_int2BN(&data.exponent2);
- k->iqmp = heim_int2BN(&data.coefficient);
+ k->n = _hc_integer_to_BN(&data.modulus, NULL);
+ k->e = _hc_integer_to_BN(&data.publicExponent, NULL);
+ k->d = _hc_integer_to_BN(&data.privateExponent, NULL);
+ k->p = _hc_integer_to_BN(&data.prime1, NULL);
+ k->q = _hc_integer_to_BN(&data.prime2, NULL);
+ k->dmp1 = _hc_integer_to_BN(&data.exponent1, NULL);
+ k->dmq1 = _hc_integer_to_BN(&data.exponent2, NULL);
+ k->iqmp = _hc_integer_to_BN(&data.coefficient, NULL);
free_RSAPrivateKey(&data);
if (k->n == NULL || k->e == NULL || k->d == NULL || k->p == NULL ||
@@ -485,14 +594,14 @@ i2d_RSAPrivateKey(RSA *rsa, unsigned char **pp)
memset(&data, 0, sizeof(data));
- ret = bn2heim_int(rsa->n, &data.modulus);
- ret |= bn2heim_int(rsa->e, &data.publicExponent);
- ret |= bn2heim_int(rsa->d, &data.privateExponent);
- ret |= bn2heim_int(rsa->p, &data.prime1);
- ret |= bn2heim_int(rsa->q, &data.prime2);
- ret |= bn2heim_int(rsa->dmp1, &data.exponent1);
- ret |= bn2heim_int(rsa->dmq1, &data.exponent2);
- ret |= bn2heim_int(rsa->iqmp, &data.coefficient);
+ ret = _hc_BN_to_integer(rsa->n, &data.modulus);
+ ret |= _hc_BN_to_integer(rsa->e, &data.publicExponent);
+ ret |= _hc_BN_to_integer(rsa->d, &data.privateExponent);
+ ret |= _hc_BN_to_integer(rsa->p, &data.prime1);
+ ret |= _hc_BN_to_integer(rsa->q, &data.prime2);
+ ret |= _hc_BN_to_integer(rsa->dmp1, &data.exponent1);
+ ret |= _hc_BN_to_integer(rsa->dmq1, &data.exponent2);
+ ret |= _hc_BN_to_integer(rsa->iqmp, &data.coefficient);
if (ret) {
free_RSAPrivateKey(&data);
return -1;
@@ -530,8 +639,8 @@ i2d_RSAPublicKey(RSA *rsa, unsigned char **pp)
memset(&data, 0, sizeof(data));
- if (bn2heim_int(rsa->n, &data.modulus) ||
- bn2heim_int(rsa->e, &data.publicExponent))
+ if (_hc_BN_to_integer(rsa->n, &data.modulus) ||
+ _hc_BN_to_integer(rsa->e, &data.publicExponent))
{
free_RSAPublicKey(&data);
return -1;
@@ -582,8 +691,8 @@ d2i_RSAPublicKey(RSA *rsa, const unsigned char **pp, size_t len)
}
}
- k->n = heim_int2BN(&data.modulus);
- k->e = heim_int2BN(&data.publicExponent);
+ k->n = _hc_integer_to_BN(&data.modulus, NULL);
+ k->e = _hc_integer_to_BN(&data.publicExponent, NULL);
free_RSAPublicKey(&data);
diff --git a/source4/heimdal/lib/hcrypto/rsa.h b/source4/heimdal/lib/hcrypto/rsa.h
index 9354aaaa48..3fd805fcf0 100644
--- a/source4/heimdal/lib/hcrypto/rsa.h
+++ b/source4/heimdal/lib/hcrypto/rsa.h
@@ -41,7 +41,9 @@
/* symbol renaming */
#define RSA_null_method hc_RSA_null_method
#define RSA_imath_method hc_RSA_imath_method
+#define RSA_ltm_method hc_RSA_ltm_method
#define RSA_gmp_method hc_RSA_gmp_method
+#define RSA_tfm_method hc_RSA_tfm_method
#define RSA_new hc_RSA_new
#define RSA_new_method hc_RSA_new_method
#define RSA_free hc_RSA_free
@@ -136,6 +138,8 @@ struct RSA {
const RSA_METHOD *RSA_null_method(void);
const RSA_METHOD *RSA_imath_method(void);
const RSA_METHOD *RSA_gmp_method(void);
+const RSA_METHOD *RSA_tfm_method(void);
+const RSA_METHOD *RSA_ltm_method(void);
/*
*
@@ -153,7 +157,7 @@ const RSA_METHOD * RSA_get_method(const RSA *);
int RSA_set_method(RSA *, const RSA_METHOD *);
int RSA_set_app_data(RSA *, void *arg);
-void * RSA_get_app_data(RSA *);
+void * RSA_get_app_data(const RSA *);
int RSA_check_key(const RSA *);
int RSA_size(const RSA *);
diff --git a/source4/heimdal/lib/hcrypto/sha.c b/source4/heimdal/lib/hcrypto/sha.c
index 062f70509c..9c8b39e241 100644
--- a/source4/heimdal/lib/hcrypto/sha.c
+++ b/source4/heimdal/lib/hcrypto/sha.c
@@ -240,13 +240,13 @@ SHA1_Update (struct sha *m, const void *v, size_t len)
if(offset == 64){
#if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
int i;
- uint32_t current[16];
- struct x32 *u = (struct x32*)m->save;
+ uint32_t SHA1current[16];
+ struct x32 *us = (struct x32*)m->save;
for(i = 0; i < 8; i++){
- current[2*i+0] = swap_uint32_t(u[i].a);
- current[2*i+1] = swap_uint32_t(u[i].b);
+ SHA1current[2*i+0] = swap_uint32_t(us[i].a);
+ SHA1current[2*i+1] = swap_uint32_t(us[i].b);
}
- calc(m, current);
+ calc(m, SHA1current);
#else
calc(m, (uint32_t*)m->save);
#endif
diff --git a/source4/heimdal/lib/hcrypto/sha256.c b/source4/heimdal/lib/hcrypto/sha256.c
index baa87d15ff..5e601bb358 100644
--- a/source4/heimdal/lib/hcrypto/sha256.c
+++ b/source4/heimdal/lib/hcrypto/sha256.c
@@ -183,10 +183,10 @@ SHA256_Update (SHA256_CTX *m, const void *v, size_t len)
#if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
int i;
uint32_t current[16];
- struct x32 *u = (struct x32*)m->save;
+ struct x32 *us = (struct x32*)m->save;
for(i = 0; i < 8; i++){
- current[2*i+0] = swap_uint32_t(u[i].a);
- current[2*i+1] = swap_uint32_t(u[i].b);
+ current[2*i+0] = swap_uint32_t(us[i].a);
+ current[2*i+1] = swap_uint32_t(us[i].b);
}
calc(m, current);
#else
diff --git a/source4/heimdal/lib/hcrypto/ui.c b/source4/heimdal/lib/hcrypto/ui.c
index f6f8a1ffe2..e32bb9a0be 100644
--- a/source4/heimdal/lib/hcrypto/ui.c
+++ b/source4/heimdal/lib/hcrypto/ui.c
@@ -77,7 +77,7 @@ read_string(const char *preprompt, const char *prompt,
p = buf;
while(intr_flag == 0){
c = ((echo)? _getche(): _getch());
- if(c == '\n')
+ if(c == '\n' || c == '\r')
break;
if(of == 0)
*p++ = c;
diff --git a/source4/heimdal/lib/hcrypto/validate.c b/source4/heimdal/lib/hcrypto/validate.c
new file mode 100644
index 0000000000..3ed358df66
--- /dev/null
+++ b/source4/heimdal/lib/hcrypto/validate.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2010 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getarg.h>
+#include <roken.h>
+
+#include <evp.h>
+#include <hmac.h>
+#include <err.h>
+
+struct tests {
+ const EVP_CIPHER *(*cipher)(void);
+ const char *name;
+ void *key;
+ size_t keysize;
+ void *iv;
+ size_t datasize;
+ void *indata;
+ void *outdata;
+ void *outiv;
+};
+
+struct tests tests[] = {
+ {
+ EVP_aes_256_cbc,
+ "aes-256",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 32,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 16,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xdc\x95\xc0\x78\xa2\x40\x89\x89\xad\x48\xa2\x14\x92\x84\x20\x87"
+ },
+#if 0
+ {
+ EVP_aes_128_cfb8,
+ "aes-cfb8-128",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 16,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 16,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e"
+ },
+#endif
+ {
+ EVP_des_ede3_cbc,
+ "des-ede3",
+ "\x19\x17\xff\xe6\xbb\x77\x2e\xfc"
+ "\x29\x76\x43\xbc\x63\x56\x7e\x9a"
+ "\x00\x2e\x4d\x43\x1d\x5f\xfd\x58",
+ 24,
+ "\xbf\x9a\x12\xb7\x26\x69\xfd\x05",
+ 16,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x55\x95\x97\x76\xa9\x6c\x66\x40\x64\xc7\xf4\x1c\x21\xb7\x14\x1b"
+ },
+#if 0
+ {
+ EVP_camellia_128_cbc,
+ "camellia128",
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 16,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ 16,
+ "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x07\x92\x3A\x39\xEB\x0A\x81\x7D\x1C\x4D\x87\xBD\xB8\x2D\x1F\x1C",
+ NULL
+ },
+#endif
+ {
+ EVP_rc4,
+ "rc4 8",
+ "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
+ 8,
+ NULL,
+ 8,
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x74\x94\xC2\xE7\x10\x4B\x08\x79",
+ NULL
+ },
+ {
+ EVP_rc4,
+ "rc4 5",
+ "\x61\x8a\x63\xd2\xfb",
+ 5,
+ NULL,
+ 5,
+ "\xdc\xee\x4c\xf9\x2c",
+ "\xf1\x38\x29\xc9\xde",
+ NULL
+ },
+ {
+ EVP_rc4,
+ "rc4 309",
+ "\x29\x04\x19\x72\xfb\x42\xba\x5f\xc7\x12\x77\x12\xf1\x38\x29\xc9",
+ 16,
+ NULL,
+ 309,
+ "\x52\x75\x69\x73\x6c\x69\x6e\x6e"
+ "\x75\x6e\x20\x6c\x61\x75\x6c\x75"
+ "\x20\x6b\x6f\x72\x76\x69\x73\x73"
+ "\x73\x61\x6e\x69\x2c\x20\x74\xe4"
+ "\x68\x6b\xe4\x70\xe4\x69\x64\x65"
+ "\x6e\x20\x70\xe4\xe4\x6c\x6c\xe4"
+ "\x20\x74\xe4\x79\x73\x69\x6b\x75"
+ "\x75\x2e\x20\x4b\x65\x73\xe4\x79"
+ "\xf6\x6e\x20\x6f\x6e\x20\x6f\x6e"
+ "\x6e\x69\x20\x6f\x6d\x61\x6e\x61"
+ "\x6e\x69\x2c\x20\x6b\x61\x73\x6b"
+ "\x69\x73\x61\x76\x75\x75\x6e\x20"
+ "\x6c\x61\x61\x6b\x73\x6f\x74\x20"
+ "\x76\x65\x72\x68\x6f\x75\x75\x2e"
+ "\x20\x45\x6e\x20\x6d\x61\x20\x69"
+ "\x6c\x6f\x69\x74\x73\x65\x2c\x20"
+ "\x73\x75\x72\x65\x20\x68\x75\x6f"
+ "\x6b\x61\x61\x2c\x20\x6d\x75\x74"
+ "\x74\x61\x20\x6d\x65\x74\x73\xe4"
+ "\x6e\x20\x74\x75\x6d\x6d\x75\x75"
+ "\x73\x20\x6d\x75\x6c\x6c\x65\x20"
+ "\x74\x75\x6f\x6b\x61\x61\x2e\x20"
+ "\x50\x75\x75\x6e\x74\x6f\x20\x70"
+ "\x69\x6c\x76\x65\x6e\x2c\x20\x6d"
+ "\x69\x20\x68\x75\x6b\x6b\x75\x75"
+ "\x2c\x20\x73\x69\x69\x6e\x74\x6f"
+ "\x20\x76\x61\x72\x61\x6e\x20\x74"
+ "\x75\x75\x6c\x69\x73\x65\x6e\x2c"
+ "\x20\x6d\x69\x20\x6e\x75\x6b\x6b"
+ "\x75\x75\x2e\x20\x54\x75\x6f\x6b"
+ "\x73\x75\x74\x20\x76\x61\x6e\x61"
+ "\x6d\x6f\x6e\x20\x6a\x61\x20\x76"
+ "\x61\x72\x6a\x6f\x74\x20\x76\x65"
+ "\x65\x6e\x2c\x20\x6e\x69\x69\x73"
+ "\x74\xe4\x20\x73\x79\x64\xe4\x6d"
+ "\x65\x6e\x69\x20\x6c\x61\x75\x6c"
+ "\x75\x6e\x20\x74\x65\x65\x6e\x2e"
+ "\x20\x2d\x20\x45\x69\x6e\x6f\x20"
+ "\x4c\x65\x69\x6e\x6f",
+ "\x35\x81\x86\x99\x90\x01\xe6\xb5"
+ "\xda\xf0\x5e\xce\xeb\x7e\xee\x21"
+ "\xe0\x68\x9c\x1f\x00\xee\xa8\x1f"
+ "\x7d\xd2\xca\xae\xe1\xd2\x76\x3e"
+ "\x68\xaf\x0e\xad\x33\xd6\x6c\x26"
+ "\x8b\xc9\x46\xc4\x84\xfb\xe9\x4c"
+ "\x5f\x5e\x0b\x86\xa5\x92\x79\xe4"
+ "\xf8\x24\xe7\xa6\x40\xbd\x22\x32"
+ "\x10\xb0\xa6\x11\x60\xb7\xbc\xe9"
+ "\x86\xea\x65\x68\x80\x03\x59\x6b"
+ "\x63\x0a\x6b\x90\xf8\xe0\xca\xf6"
+ "\x91\x2a\x98\xeb\x87\x21\x76\xe8"
+ "\x3c\x20\x2c\xaa\x64\x16\x6d\x2c"
+ "\xce\x57\xff\x1b\xca\x57\xb2\x13"
+ "\xf0\xed\x1a\xa7\x2f\xb8\xea\x52"
+ "\xb0\xbe\x01\xcd\x1e\x41\x28\x67"
+ "\x72\x0b\x32\x6e\xb3\x89\xd0\x11"
+ "\xbd\x70\xd8\xaf\x03\x5f\xb0\xd8"
+ "\x58\x9d\xbc\xe3\xc6\x66\xf5\xea"
+ "\x8d\x4c\x79\x54\xc5\x0c\x3f\x34"
+ "\x0b\x04\x67\xf8\x1b\x42\x59\x61"
+ "\xc1\x18\x43\x07\x4d\xf6\x20\xf2"
+ "\x08\x40\x4b\x39\x4c\xf9\xd3\x7f"
+ "\xf5\x4b\x5f\x1a\xd8\xf6\xea\x7d"
+ "\xa3\xc5\x61\xdf\xa7\x28\x1f\x96"
+ "\x44\x63\xd2\xcc\x35\xa4\xd1\xb0"
+ "\x34\x90\xde\xc5\x1b\x07\x11\xfb"
+ "\xd6\xf5\x5f\x79\x23\x4d\x5b\x7c"
+ "\x76\x66\x22\xa6\x6d\xe9\x2b\xe9"
+ "\x96\x46\x1d\x5e\x4d\xc8\x78\xef"
+ "\x9b\xca\x03\x05\x21\xe8\x35\x1e"
+ "\x4b\xae\xd2\xfd\x04\xf9\x46\x73"
+ "\x68\xc4\xad\x6a\xc1\x86\xd0\x82"
+ "\x45\xb2\x63\xa2\x66\x6d\x1f\x6c"
+ "\x54\x20\xf1\x59\x9d\xfd\x9f\x43"
+ "\x89\x21\xc2\xf5\xa4\x63\x93\x8c"
+ "\xe0\x98\x22\x65\xee\xf7\x01\x79"
+ "\xbc\x55\x3f\x33\x9e\xb1\xa4\xc1"
+ "\xaf\x5f\x6a\x54\x7f"
+ }
+};
+
+static int
+test_cipher(struct tests *t)
+{
+ const EVP_CIPHER *c = t->cipher();
+ EVP_CIPHER_CTX ectx;
+ EVP_CIPHER_CTX dctx;
+ void *d;
+
+ EVP_CIPHER_CTX_init(&ectx);
+ EVP_CIPHER_CTX_init(&dctx);
+
+ if (EVP_CipherInit_ex(&ectx, c, NULL, NULL, NULL, 1) != 1)
+ errx(1, "%s: EVP_CipherInit_ex einit", t->name);
+ if (EVP_CipherInit_ex(&dctx, c, NULL, NULL, NULL, 0) != 1)
+ errx(1, "%s: EVP_CipherInit_ex dinit", t->name);
+
+ EVP_CIPHER_CTX_set_key_length(&ectx, t->keysize);
+ EVP_CIPHER_CTX_set_key_length(&dctx, t->keysize);
+
+ if (EVP_CipherInit_ex(&ectx, NULL, NULL, t->key, t->iv, 1) != 1)
+ errx(1, "%s: EVP_CipherInit_ex encrypt", t->name);
+ if (EVP_CipherInit_ex(&dctx, NULL, NULL, t->key, t->iv, 0) != 1)
+ errx(1, "%s: EVP_CipherInit_ex decrypt", t->name);
+
+ d = emalloc(t->datasize);
+
+ if (!EVP_Cipher(&ectx, d, t->indata, t->datasize))
+ return 1;
+
+ if (memcmp(d, t->outdata, t->datasize) != 0)
+ errx(1, "%s: encrypt not the same", t->name);
+
+ if (!EVP_Cipher(&dctx, d, d, t->datasize))
+ return 1;
+
+ if (memcmp(d, t->indata, t->datasize) != 0)
+ errx(1, "%s: decrypt not the same", t->name);
+
+ if (t->outiv)
+ /* XXXX check */;
+
+ EVP_CIPHER_CTX_cleanup(&ectx);
+ EVP_CIPHER_CTX_cleanup(&dctx);
+ free(d);
+
+ return 0;
+}
+
+static void
+check_hmac(void)
+{
+ unsigned char buf[4] = { 0, 0, 0, 0 };
+ char hmackey[] = "hello-world";
+ size_t hmackey_size = sizeof(hmackey);
+ unsigned int hmaclen;
+ unsigned char hmac[EVP_MAX_MD_SIZE];
+ HMAC_CTX c;
+
+ char answer[20] = "\x2c\xfa\x32\xb7\x2b\x8a\xf6\xdf\xcf\xda"
+ "\x6f\xd1\x52\x4d\x54\x58\x73\x0f\xf3\x24";
+
+ HMAC_CTX_init(&c);
+ HMAC_Init_ex(&c, hmackey, hmackey_size, EVP_sha1(), NULL);
+ HMAC_Update(&c, buf, sizeof(buf));
+ HMAC_Final(&c, hmac, &hmaclen);
+ HMAC_CTX_cleanup(&c);
+
+ if (hmaclen != 20)
+ errx(1, "hmaclen = %d\n", (int)hmaclen);
+
+ if (ct_memcmp(hmac, answer, hmaclen) != 0)
+ errx(1, "wrong answer\n");
+}
+
+void
+hcrypto_validate(void)
+{
+ static int validated = 0;
+ unsigned int i;
+
+ /* its ok to run this twice, do don't check for races */
+ if (validated)
+ return;
+ validated++;
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ test_cipher(&tests[i]);
+
+ check_hmac();
+}
diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c
index faf0b6bdf2..fb32fdb845 100644
--- a/source4/heimdal/lib/hdb/ext.c
+++ b/source4/heimdal/lib/hdb/ext.c
@@ -316,7 +316,7 @@ hdb_entry_get_password(krb5_context context, HDB *db,
str = pw.data;
if (str[pw.length - 1] != '\0') {
- krb5_set_error_message(context, EINVAL, "password malformated");
+ krb5_set_error_message(context, EINVAL, "malformed password");
return EINVAL;
}
@@ -332,7 +332,8 @@ hdb_entry_get_password(krb5_context context, HDB *db,
ret = krb5_unparse_name(context, entry->principal, &str);
if (ret == 0) {
- krb5_set_error_message(context, ENOENT, "no password attributefor %s", str);
+ krb5_set_error_message(context, ENOENT,
+ "no password attribute for %s", str);
free(str);
} else
krb5_clear_error_message(context);
diff --git a/source4/heimdal/lib/hdb/hdb_err.et b/source4/heimdal/lib/hdb/hdb_err.et
index 120dbfb9fa..2cad4daba4 100644
--- a/source4/heimdal/lib/hdb/hdb_err.et
+++ b/source4/heimdal/lib/hdb/hdb_err.et
@@ -24,6 +24,7 @@ error_code EXISTS, "Entry already exists in database"
error_code BADVERSION, "Wrong database version"
error_code NO_MKEY, "No correct master key"
error_code MANDATORY_OPTION, "Entry contains unknown mandatory extension"
+error_code NO_WRITE_SUPPORT, "HDB backend doesn't contain write support"
error_code NOT_FOUND_HERE, "The secret for this entry is not replicated to this database"
end
diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c
index 524cea6f45..efaed7f420 100644
--- a/source4/heimdal/lib/hdb/keytab.c
+++ b/source4/heimdal/lib/hdb/keytab.c
@@ -52,7 +52,7 @@ struct hdb_cursor {
* HDB:[HDBFORMAT:database-specific-data[:mkey=mkey-file]]
*/
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
{
struct hdb_data *d;
@@ -99,7 +99,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
hdb_close(krb5_context context, krb5_keytab id)
{
struct hdb_data *d = id->data;
@@ -110,7 +110,7 @@ hdb_close(krb5_context context, krb5_keytab id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
hdb_get_name(krb5_context context,
krb5_keytab id,
char *name,
@@ -169,7 +169,7 @@ find_db (krb5_context context,
* it in `entry'. return 0 or an error code
*/
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
hdb_get_entry(krb5_context context,
krb5_keytab id,
krb5_const_principal principal,
@@ -256,7 +256,7 @@ hdb_get_entry(krb5_context context,
* it in `entry'. return 0 or an error code
*/
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
hdb_start_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *cursor)
@@ -309,7 +309,7 @@ hdb_start_seq_get(krb5_context context,
return ret;
}
-static int
+static int KRB5_CALLCONV
hdb_next_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry,
@@ -391,7 +391,7 @@ hdb_next_entry(krb5_context context,
}
-static int
+static int KRB5_CALLCONV
hdb_end_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *cursor)
diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c
index 360bb33a3a..760eccfd43 100644
--- a/source4/heimdal/lib/hdb/mkey.c
+++ b/source4/heimdal/lib/hdb/mkey.c
@@ -146,7 +146,7 @@ read_master_keytab(krb5_context context, const char *filename,
/* read a MIT master keyfile */
static krb5_error_code
read_master_mit(krb5_context context, const char *filename,
- hdb_master_key *mkey)
+ int byteorder, hdb_master_key *mkey)
{
int fd;
krb5_error_code ret;
@@ -166,20 +166,16 @@ read_master_mit(krb5_context context, const char *filename,
close(fd);
return errno;
}
- krb5_storage_set_flags(sp, KRB5_STORAGE_HOST_BYTEORDER);
+ krb5_storage_set_flags(sp, byteorder);
/* could possibly use ret_keyblock here, but do it with more
checks for now */
{
ret = krb5_ret_int16(sp, &enctype);
if (ret)
goto out;
- if((htons(enctype) & 0xff00) == 0x3000) {
- ret = HEIM_ERR_BAD_MKEY;
- krb5_set_error_message(context, ret, "unknown keytype in %s: "
- "%#x, expected %#x",
- filename, htons(enctype), 0x3000);
- goto out;
- }
+ ret = krb5_enctype_valid(context, enctype);
+ if (ret)
+ goto out;
key.keytype = enctype;
ret = krb5_ret_data(sp, &key.keyvalue);
if(ret)
@@ -330,7 +326,14 @@ hdb_read_master_key(krb5_context context, const char *filename,
} else if(buf[0] == 5 && buf[1] >= 1 && buf[1] <= 2) {
ret = read_master_keytab(context, filename, mkey);
} else {
- ret = read_master_mit(context, filename, mkey);
+ /*
+ * Check both LittleEndian and BigEndian since they key file
+ * might be moved from a machine with diffrent byte order, or
+ * its running on MacOS X that always uses BE master keys.
+ */
+ ret = read_master_mit(context, filename, KRB5_STORAGE_BYTEORDER_LE, mkey);
+ if (ret)
+ ret = read_master_mit(context, filename, KRB5_STORAGE_BYTEORDER_BE, mkey);
}
return ret;
}
diff --git a/source4/heimdal/lib/hdb/ndbm.c b/source4/heimdal/lib/hdb/ndbm.c
index bad3c49742..2a57d2ac27 100644
--- a/source4/heimdal/lib/hdb/ndbm.c
+++ b/source4/heimdal/lib/hdb/ndbm.c
@@ -37,9 +37,11 @@
#if defined(HAVE_GDBM_NDBM_H)
#include <gdbm/ndbm.h>
+#define WRITE_SUPPORT 1
#elif defined(HAVE_NDBM_H)
#include <ndbm.h>
#elif defined(HAVE_DBM_H)
+#define WRITE_SUPPORT 1
#include <dbm.h>
#endif
@@ -243,6 +245,7 @@ static krb5_error_code
NDBM__put(krb5_context context, HDB *db, int replace,
krb5_data key, krb5_data value)
{
+#ifdef WRITE_SUPPORT
struct ndbm_db *d = (struct ndbm_db *)db->hdb_db;
datum k, v;
int code;
@@ -262,6 +265,9 @@ NDBM__put(krb5_context context, HDB *db, int replace,
if (code < 0)
return code;
return 0;
+#else
+ return HDB_ERR_NO_WRITE_SUPPORT;
+#endif
}
static krb5_error_code
diff --git a/source4/heimdal/lib/hx509/ca.c b/source4/heimdal/lib/hx509/ca.c
index 8ec6eae22a..492064d86d 100644
--- a/source4/heimdal/lib/hx509/ca.c
+++ b/source4/heimdal/lib/hx509/ca.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006 - 2010 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -53,11 +53,15 @@ struct hx509_ca_tbs {
unsigned int key:1;
unsigned int serial:1;
unsigned int domaincontroller:1;
+ unsigned int xUniqueID:1;
} flags;
time_t notBefore;
time_t notAfter;
int pathLenConstraint; /* both for CA and Proxy */
CRLDistributionPoints crldp;
+ heim_bit_string subjectUniqueID;
+ heim_bit_string issuerUniqueID;
+
};
/**
@@ -80,15 +84,6 @@ hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs)
if (*tbs == NULL)
return ENOMEM;
- (*tbs)->subject = NULL;
- (*tbs)->san.len = 0;
- (*tbs)->san.val = NULL;
- (*tbs)->eku.len = 0;
- (*tbs)->eku.val = NULL;
- (*tbs)->pathLenConstraint = 0;
- (*tbs)->crldp.len = 0;
- (*tbs)->crldp.val = NULL;
-
return 0;
}
@@ -111,7 +106,8 @@ hx509_ca_tbs_free(hx509_ca_tbs *tbs)
free_ExtKeyUsage(&(*tbs)->eku);
der_free_heim_integer(&(*tbs)->serial);
free_CRLDistributionPoints(&(*tbs)->crldp);
-
+ der_free_bit_string(&(*tbs)->subjectUniqueID);
+ der_free_bit_string(&(*tbs)->issuerUniqueID);
hx509_name_free(&(*tbs)->subject);
memset(*tbs, 0, sizeof(**tbs));
@@ -485,7 +481,8 @@ hx509_ca_tbs_add_crl_dp_uri(hx509_context context,
name.u.fullName.val = &gn;
gn.element = choice_GeneralName_uniformResourceIdentifier;
- gn.u.uniformResourceIdentifier = rk_UNCONST(uri);
+ gn.u.uniformResourceIdentifier.data = rk_UNCONST(uri);
+ gn.u.uniformResourceIdentifier.length = strlen(uri);
ASN1_MALLOC_ENCODE(DistributionPointName,
dp.distributionPoint->data,
@@ -785,7 +782,8 @@ hx509_ca_tbs_add_san_hostname(hx509_context context,
memset(&gn, 0, sizeof(gn));
gn.element = choice_GeneralName_dNSName;
- gn.u.dNSName = rk_UNCONST(dnsname);
+ gn.u.dNSName.data = rk_UNCONST(dnsname);
+ gn.u.dNSName.length = strlen(dnsname);
return add_GeneralNames(&tbs->san, &gn);
}
@@ -812,7 +810,8 @@ hx509_ca_tbs_add_san_rfc822name(hx509_context context,
memset(&gn, 0, sizeof(gn));
gn.element = choice_GeneralName_rfc822Name;
- gn.u.rfc822Name = rk_UNCONST(rfc822Name);
+ gn.u.rfc822Name.data = rk_UNCONST(rfc822Name);
+ gn.u.rfc822Name.length = strlen(rfc822Name);
return add_GeneralNames(&tbs->san, &gn);
}
@@ -840,6 +839,50 @@ hx509_ca_tbs_set_subject(hx509_context context,
}
/**
+ * Set the issuerUniqueID and subjectUniqueID
+ *
+ * These are only supposed to be used considered with version 2
+ * certificates, replaced by the two extensions SubjectKeyIdentifier
+ * and IssuerKeyIdentifier. This function is to allow application
+ * using legacy protocol to issue them.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param issuerUniqueID to be set
+ * @param subjectUniqueID to be set
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
+int
+hx509_ca_tbs_set_unique(hx509_context context,
+ hx509_ca_tbs tbs,
+ const heim_bit_string *subjectUniqueID,
+ const heim_bit_string *issuerUniqueID)
+{
+ int ret;
+
+ der_free_bit_string(&tbs->subjectUniqueID);
+ der_free_bit_string(&tbs->issuerUniqueID);
+
+ if (subjectUniqueID) {
+ ret = der_copy_bit_string(subjectUniqueID, &tbs->subjectUniqueID);
+ if (ret)
+ return ret;
+ }
+
+ if (issuerUniqueID) {
+ ret = der_copy_bit_string(issuerUniqueID, &tbs->issuerUniqueID);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
* Expand the the subject name in the to-be-signed certificate object
* using hx509_name_expand().
*
@@ -861,6 +904,10 @@ hx509_ca_tbs_subject_expand(hx509_context context,
return hx509_name_expand(context, tbs->subject, env);
}
+/*
+ *
+ */
+
static int
add_extension(hx509_context context,
TBSCertificate *tbsc,
@@ -1090,7 +1137,35 @@ ca_sign(hx509_context context,
goto out;
}
/* issuerUniqueID [1] IMPLICIT BIT STRING OPTIONAL */
+ if (tbs->issuerUniqueID.length) {
+ tbsc->issuerUniqueID = calloc(1, sizeof(*tbsc->issuerUniqueID));
+ if (tbsc->issuerUniqueID == NULL) {
+ ret = ENOMEM;
+ hx509_set_error_string(context, 0, ret, "Out of memory");
+ goto out;
+ }
+ ret = der_copy_bit_string(&tbs->issuerUniqueID, tbsc->issuerUniqueID);
+ if (ret) {
+ hx509_set_error_string(context, 0, ret, "Out of memory");
+ goto out;
+ }
+ }
/* subjectUniqueID [2] IMPLICIT BIT STRING OPTIONAL */
+ if (tbs->subjectUniqueID.length) {
+ tbsc->subjectUniqueID = calloc(1, sizeof(*tbsc->subjectUniqueID));
+ if (tbsc->subjectUniqueID == NULL) {
+ ret = ENOMEM;
+ hx509_set_error_string(context, 0, ret, "Out of memory");
+ goto out;
+ }
+
+ ret = der_copy_bit_string(&tbs->subjectUniqueID, tbsc->subjectUniqueID);
+ if (ret) {
+ hx509_set_error_string(context, 0, ret, "Out of memory");
+ goto out;
+ }
+ }
+
/* extensions [3] EXPLICIT Extensions OPTIONAL */
tbsc->extensions = calloc(1, sizeof(*tbsc->extensions));
if (tbsc->extensions == NULL) {
diff --git a/source4/heimdal/lib/hx509/cert.c b/source4/heimdal/lib/hx509/cert.c
index 4783edd681..93a172e553 100644
--- a/source4/heimdal/lib/hx509/cert.c
+++ b/source4/heimdal/lib/hx509/cert.c
@@ -1510,6 +1510,65 @@ hx509_cert_get_SPKI_AlgorithmIdentifier(hx509_context context,
return ret;
}
+static int
+get_x_unique_id(hx509_context context, const char *name,
+ const heim_bit_string *cert, heim_bit_string *subject)
+{
+ int ret;
+
+ if (cert == NULL) {
+ ret = HX509_EXTENSION_NOT_FOUND;
+ hx509_set_error_string(context, 0, ret, "%s unique id doesn't exists", name);
+ return ret;
+ }
+ ret = der_copy_bit_string(cert, subject);
+ if (ret) {
+ hx509_set_error_string(context, 0, ret, "malloc out of memory", name);
+ return ret;
+ }
+ return 0;
+}
+
+/**
+ * Get a copy of the Issuer Unique ID
+ *
+ * @param context a hx509_context
+ * @param p a hx509 certificate
+ * @param issuer the issuer id returned, free with der_free_bit_string()
+ *
+ * @return An hx509 error code, see hx509_get_error_string(). The
+ * error code HX509_EXTENSION_NOT_FOUND is returned if the certificate
+ * doesn't have a issuerUniqueID
+ *
+ * @ingroup hx509_cert
+ */
+
+int
+hx509_cert_get_issuer_unique_id(hx509_context context, hx509_cert p, heim_bit_string *issuer)
+{
+ return get_x_unique_id(context, "issuer", p->data->tbsCertificate.issuerUniqueID, issuer);
+}
+
+/**
+ * Get a copy of the Subect Unique ID
+ *
+ * @param context a hx509_context
+ * @param p a hx509 certificate
+ * @param subject the subject id returned, free with der_free_bit_string()
+ *
+ * @return An hx509 error code, see hx509_get_error_string(). The
+ * error code HX509_EXTENSION_NOT_FOUND is returned if the certificate
+ * doesn't have a subjectUniqueID
+ *
+ * @ingroup hx509_cert
+ */
+
+int
+hx509_cert_get_subject_unique_id(hx509_context context, hx509_cert p, heim_bit_string *subject)
+{
+ return get_x_unique_id(context, "subject", p->data->tbsCertificate.subjectUniqueID, subject);
+}
+
hx509_private_key
_hx509_cert_private_key(hx509_cert p)
@@ -1696,19 +1755,20 @@ match_general_name(const GeneralName *c, const GeneralName *n, int *match)
case choice_GeneralName_rfc822Name: {
const char *s;
size_t len1, len2;
- s = strchr(c->u.rfc822Name, '@');
+ s = memchr(c->u.rfc822Name.data, '@', c->u.rfc822Name.length);
if (s) {
- if (strcasecmp(c->u.rfc822Name, n->u.rfc822Name) != 0)
+ if (der_printable_string_cmp(&c->u.rfc822Name, &n->u.rfc822Name) != 0)
return HX509_NAME_CONSTRAINT_ERROR;
} else {
- s = strchr(n->u.rfc822Name, '@');
+ s = memchr(n->u.rfc822Name.data, '@', n->u.rfc822Name.length);
if (s == NULL)
return HX509_NAME_CONSTRAINT_ERROR;
- len1 = strlen(c->u.rfc822Name);
- len2 = strlen(s + 1);
+ len1 = c->u.rfc822Name.length;
+ len2 = n->u.rfc822Name.length -
+ (s - ((char *)n->u.rfc822Name.data));
if (len1 > len2)
return HX509_NAME_CONSTRAINT_ERROR;
- if (strcasecmp(s + 1 + len2 - len1, c->u.rfc822Name) != 0)
+ if (memcmp(s + 1 + len2 - len1, c->u.rfc822Name.data, len1) != 0)
return HX509_NAME_CONSTRAINT_ERROR;
if (len1 < len2 && s[len2 - len1 + 1] != '.')
return HX509_NAME_CONSTRAINT_ERROR;
@@ -1718,14 +1778,16 @@ match_general_name(const GeneralName *c, const GeneralName *n, int *match)
}
case choice_GeneralName_dNSName: {
size_t lenc, lenn;
+ char *ptr;
- lenc = strlen(c->u.dNSName);
- lenn = strlen(n->u.dNSName);
+ lenc = c->u.dNSName.length;
+ lenn = n->u.dNSName.length;
if (lenc > lenn)
return HX509_NAME_CONSTRAINT_ERROR;
- if (strcasecmp(&n->u.dNSName[lenn - lenc], c->u.dNSName) != 0)
+ ptr = n->u.dNSName.data;
+ if (memcmp(&ptr[lenn - lenc], c->u.dNSName.data, lenc) != 0)
return HX509_NAME_CONSTRAINT_ERROR;
- if (lenc != lenn && n->u.dNSName[lenn - lenc - 1] != '.')
+ if (lenn != lenc && ptr[lenn - lenc - 1] != '.')
return HX509_NAME_CONSTRAINT_ERROR;
*match = 1;
return 0;
@@ -2405,12 +2467,17 @@ hx509_verify_hostname(hx509_context context,
for (j = 0; j < san.len; j++) {
switch (san.val[j].element) {
- case choice_GeneralName_dNSName:
- if (strcasecmp(san.val[j].u.dNSName, hostname) == 0) {
+ case choice_GeneralName_dNSName: {
+ heim_printable_string hn;
+ hn.data = rk_UNCONST(hostname);
+ hn.length = strlen(hostname);
+
+ if (der_printable_string_cmp(&san.val[j].u.dNSName, &hn) == 0) {
free_GeneralNames(&san);
return 0;
}
break;
+ }
default:
break;
}
@@ -2428,14 +2495,24 @@ hx509_verify_hostname(hx509_context context,
if (der_heim_oid_cmp(&n->type, &asn1_oid_id_at_commonName) == 0) {
DirectoryString *ds = &n->value;
switch (ds->element) {
- case choice_DirectoryString_printableString:
- if (strcasecmp(ds->u.printableString, hostname) == 0)
+ case choice_DirectoryString_printableString: {
+ heim_printable_string hn;
+ hn.data = rk_UNCONST(hostname);
+ hn.length = strlen(hostname);
+
+ if (der_printable_string_cmp(&ds->u.printableString, &hn) == 0)
return 0;
break;
- case choice_DirectoryString_ia5String:
- if (strcasecmp(ds->u.ia5String, hostname) == 0)
- return 0;
+ }
+ case choice_DirectoryString_ia5String: {
+ heim_ia5_string hn;
+ hn.data = rk_UNCONST(hostname);
+ hn.length = strlen(hostname);
+
+ if (der_ia5_string_cmp(&ds->u.ia5String, &hn) == 0)
+ return 0;
break;
+ }
case choice_DirectoryString_utf8String:
if (strcasecmp(ds->u.utf8String, hostname) == 0)
return 0;
diff --git a/source4/heimdal/lib/hx509/char_map.h b/source4/heimdal/lib/hx509/char_map.h
new file mode 100644
index 0000000000..d2b39d041f
--- /dev/null
+++ b/source4/heimdal/lib/hx509/char_map.h
@@ -0,0 +1,45 @@
+#define Q_CONTROL_CHAR 1
+#define Q_PRINTABLE 2
+#define Q_RFC2253_QUOTE_FIRST 4
+#define Q_RFC2253_QUOTE_LAST 8
+#define Q_RFC2253_QUOTE 16
+#define Q_RFC2253_HEX 32
+
+#define Q_RFC2253 (Q_RFC2253_QUOTE_FIRST|Q_RFC2253_QUOTE_LAST|Q_RFC2253_QUOTE|Q_RFC2253_HEX)
+
+
+
+unsigned char char_map[] = {
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x06 , 0x00 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 ,
+ 0x00 , 0x00 , 0x00 , 0x12 , 0x12 , 0x02 , 0x02 , 0x02 ,
+ 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
+ 0x02 , 0x02 , 0x02 , 0x10 , 0x10 , 0x12 , 0x10 , 0x02 ,
+ 0x00 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
+ 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
+ 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
+ 0x02 , 0x02 , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
+ 0x00 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
+ 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
+ 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 , 0x02 ,
+ 0x02 , 0x02 , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 ,
+ 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21 , 0x21
+};
diff --git a/source4/heimdal/lib/hx509/cms.c b/source4/heimdal/lib/hx509/cms.c
index 5506cee463..224c39086c 100644
--- a/source4/heimdal/lib/hx509/cms.c
+++ b/source4/heimdal/lib/hx509/cms.c
@@ -1170,6 +1170,7 @@ struct sigctx {
heim_octet_string content;
hx509_peer_info peer;
int cmsidflag;
+ int leafonly;
hx509_certs certs;
hx509_certs anchors;
hx509_certs pool;
@@ -1360,7 +1361,7 @@ sig_process(hx509_context context, void *ctx, hx509_cert cert)
if (sigctx->certs) {
unsigned int i;
- if (sigctx->pool) {
+ if (sigctx->pool && sigctx->leafonly == 0) {
_hx509_calculate_path(context,
HX509_CALCULATE_PATH_NO_ANCHOR,
time(NULL),
@@ -1415,6 +1416,12 @@ cert_process(hx509_context context, void *ctx, hx509_cert cert)
return ret;
}
+static int
+cmp_AlgorithmIdentifier(const AlgorithmIdentifier *p, const AlgorithmIdentifier *q)
+{
+ return der_heim_oid_cmp(&p->algorithm, &q->algorithm);
+}
+
int
hx509_cms_create_signed(hx509_context context,
int flags,
@@ -1427,7 +1434,7 @@ hx509_cms_create_signed(hx509_context context,
hx509_certs pool,
heim_octet_string *signed_data)
{
- unsigned int i;
+ unsigned int i, j;
hx509_name name;
int ret;
size_t size;
@@ -1454,9 +1461,22 @@ hx509_cms_create_signed(hx509_context context,
else
sigctx.cmsidflag = CMS_ID_SKI;
- ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &sigctx.certs);
- if (ret)
- return ret;
+ /**
+ * Use HX509_CMS_SIGNATURE_LEAF_ONLY to only request leaf
+ * certificates to be added to the SignedData.
+ */
+ sigctx.leafonly = (flags & HX509_CMS_SIGNATURE_LEAF_ONLY) ? 1 : 0;
+
+ /**
+ * Use HX509_CMS_NO_CERTS to make the SignedData contain no
+ * certificates, overrides HX509_CMS_SIGNATURE_LEAF_ONLY.
+ */
+
+ if ((flags & HX509_CMS_SIGNATURE_NO_CERTS) == 0) {
+ ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &sigctx.certs);
+ if (ret)
+ return ret;
+ }
sigctx.anchors = anchors;
sigctx.pool = pool;
@@ -1497,22 +1517,19 @@ hx509_cms_create_signed(hx509_context context,
}
if (sigctx.sd.signerInfos.len) {
- ALLOC_SEQ(&sigctx.sd.digestAlgorithms, sigctx.sd.signerInfos.len);
- if (sigctx.sd.digestAlgorithms.val == NULL) {
- ret = ENOMEM;
- hx509_clear_error_string(context);
- goto out;
- }
-
- /* XXX remove dups */
for (i = 0; i < sigctx.sd.signerInfos.len; i++) {
AlgorithmIdentifier *di =
&sigctx.sd.signerInfos.val[i].digestAlgorithm;
- ret = copy_AlgorithmIdentifier(di,
- &sigctx.sd.digestAlgorithms.val[i]);
- if (ret) {
- hx509_clear_error_string(context);
- goto out;
+
+ for (j = 0; j < sigctx.sd.digestAlgorithms.len; j++)
+ if (cmp_AlgorithmIdentifier(di, &sigctx.sd.digestAlgorithms.val[j]) == 0)
+ break;
+ if (j < sigctx.sd.digestAlgorithms.len) {
+ ret = add_DigestAlgorithmIdentifiers(&sigctx.sd.digestAlgorithms, di);
+ if (ret) {
+ hx509_clear_error_string(context);
+ goto out;
+ }
}
}
}
diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c
index 77be4413ac..c2e5e70748 100644
--- a/source4/heimdal/lib/hx509/crypto.c
+++ b/source4/heimdal/lib/hx509/crypto.c
@@ -149,11 +149,6 @@ const AlgorithmIdentifier _hx509_signature_md5_data = {
{ 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
};
-static const unsigned md2_oid_tree[] = { 1, 2, 840, 113549, 2, 2 };
-const AlgorithmIdentifier _hx509_signature_md2_data = {
- { 6, rk_UNCONST(md2_oid_tree) }, rk_UNCONST(&null_entry_oid)
-};
-
static const unsigned ecPublicKey[] ={ 1, 2, 840, 10045, 2, 1 };
const AlgorithmIdentifier _hx509_signature_ecPublicKey = {
{ 6, rk_UNCONST(ecPublicKey) }, NULL
@@ -194,11 +189,6 @@ const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
{ 7, rk_UNCONST(rsa_with_md5_oid) }, NULL
};
-static const unsigned rsa_with_md2_oid[] ={ 1, 2, 840, 113549, 1, 1, 2 };
-const AlgorithmIdentifier _hx509_signature_rsa_with_md2_data = {
- { 7, rk_UNCONST(rsa_with_md2_oid) }, NULL
-};
-
static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
const AlgorithmIdentifier _hx509_signature_rsa_data = {
{ 7, rk_UNCONST(rsa_oid) }, NULL
@@ -283,11 +273,11 @@ heim_oid2ecnid(heim_oid *oid)
* Now map to openssl OID fun
*/
- if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp256r1) == 0)
+ if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP256R1) == 0)
return NID_X9_62_prime256v1;
- else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r1) == 0)
+ else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R1) == 0)
return NID_secp160r1;
- else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r2) == 0)
+ else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R2) == 0)
return NID_secp160r2;
return -1;
@@ -370,7 +360,7 @@ ecdsa_verify_signature(hx509_context context,
/* set up EC KEY */
spi = &signer->tbsCertificate.subjectPublicKeyInfo;
- if (der_heim_oid_cmp(&spi->algorithm.algorithm, &asn1_oid_id_ecPublicKey) != 0)
+ if (der_heim_oid_cmp(&spi->algorithm.algorithm, ASN1_OID_ID_ECPUBLICKEY) != 0)
return HX509_CRYPTO_SIG_INVALID_FORMAT;
#ifdef HAVE_OPENSSL
@@ -431,7 +421,7 @@ ecdsa_create_signature(hx509_context context,
unsigned int siglen;
int ret;
- if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
+ if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) != 0)
_hx509_abort("internal error passing private key to wrong ops");
sig_oid = sig_alg->sig_oid;
@@ -661,7 +651,7 @@ rsa_create_signature(hx509_context context,
size_t size;
int ret;
- if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0)
+ if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0)
return HX509_ALG_NOT_SUPP;
if (alg)
@@ -669,19 +659,19 @@ rsa_create_signature(hx509_context context,
else
sig_oid = signer->signature_alg;
- if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha256WithRSAEncryption) == 0) {
+ if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) {
digest_alg = hx509_signature_sha256();
- } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha1WithRSAEncryption) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) {
digest_alg = hx509_signature_sha1();
- } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
digest_alg = hx509_signature_md5();
- } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
digest_alg = hx509_signature_md5();
- } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_dsa_with_sha1) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_DSA_WITH_SHA1) == 0) {
digest_alg = hx509_signature_sha1();
- } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
digest_alg = hx509_signature_sha1();
- } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_heim_rsa_pkcs1_x509) == 0) {
+ } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_HEIM_RSA_PKCS1_X509) == 0) {
digest_alg = NULL;
} else
return HX509_ALG_NOT_SUPP;
@@ -767,7 +757,7 @@ rsa_private_key_import(hx509_context context,
"Failed to parse RSA key");
return HX509_PARSING_KEY_FAILED;
}
- private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
+ private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
return 0;
}
@@ -790,7 +780,7 @@ rsa_private_key2SPKI(hx509_context context,
}
spki->subjectPublicKey.length = len * 8;
- ret = set_digest_alg(&spki->algorithm, &asn1_oid_id_pkcs1_rsaEncryption,
+ ret = set_digest_alg(&spki->algorithm, ASN1_OID_ID_PKCS1_RSAENCRYPTION,
"\x05\x00", 2);
if (ret) {
hx509_set_error_string(context, 0, ret, "malloc - out of memory");
@@ -844,7 +834,7 @@ rsa_generate_private_key(hx509_context context,
"Failed to generate RSA key");
return HX509_PARSING_KEY_FAILED;
}
- private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
+ private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
return 0;
}
@@ -900,7 +890,7 @@ rsa_get_internal(hx509_context context,
static hx509_private_key_ops rsa_private_key_ops = {
"RSA PRIVATE KEY",
- &asn1_oid_id_pkcs1_rsaEncryption,
+ ASN1_OID_ID_PKCS1_RSAENCRYPTION,
NULL,
rsa_private_key2SPKI,
rsa_private_key_export,
@@ -973,7 +963,7 @@ ecdsa_private_key_import(hx509_context context,
"Failed to parse EC private key");
return HX509_PARSING_KEY_FAILED;
}
- private_key->signature_alg = &asn1_oid_id_ecdsa_with_SHA256;
+ private_key->signature_alg = ASN1_OID_ID_ECDSA_WITH_SHA256;
return 0;
}
@@ -997,7 +987,7 @@ ecdsa_get_internal(hx509_context context,
static hx509_private_key_ops ecdsa_private_key_ops = {
"EC PRIVATE KEY",
- &asn1_oid_id_ecPublicKey,
+ ASN1_OID_ID_ECPUBLICKEY,
ecdsa_available,
ecdsa_private_key2SPKI,
ecdsa_private_key_export,
@@ -1110,7 +1100,7 @@ dsa_parse_private_key(hx509_context context,
d2i_DSAPrivateKey(NULL, &p, len);
if (private_key->private_key.dsa == NULL)
return EINVAL;
- private_key->signature_alg = &asn1_oid_id_dsa_with_sha1;
+ private_key->signature_alg = ASN1_OID_ID_DSA_WITH_SHA1;
return 0;
/* else */
@@ -1197,9 +1187,9 @@ evp_md_verify_signature(hx509_context context,
static const struct signature_alg ecdsa_with_sha256_alg = {
"ecdsa-with-sha256",
- &asn1_oid_id_ecdsa_with_SHA256,
+ ASN1_OID_ID_ECDSA_WITH_SHA256,
&_hx509_signature_ecdsa_with_sha256_data,
- &asn1_oid_id_ecPublicKey,
+ ASN1_OID_ID_ECPUBLICKEY,
&_hx509_signature_sha256_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
0,
@@ -1211,9 +1201,9 @@ static const struct signature_alg ecdsa_with_sha256_alg = {
static const struct signature_alg ecdsa_with_sha1_alg = {
"ecdsa-with-sha1",
- &asn1_oid_id_ecdsa_with_SHA1,
+ ASN1_OID_ID_ECDSA_WITH_SHA1,
&_hx509_signature_ecdsa_with_sha1_data,
- &asn1_oid_id_ecPublicKey,
+ ASN1_OID_ID_ECPUBLICKEY,
&_hx509_signature_sha1_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
0,
@@ -1227,9 +1217,9 @@ static const struct signature_alg ecdsa_with_sha1_alg = {
static const struct signature_alg heim_rsa_pkcs1_x509 = {
"rsa-pkcs1-x509",
- &asn1_oid_id_heim_rsa_pkcs1_x509,
+ ASN1_OID_ID_HEIM_RSA_PKCS1_X509,
&_hx509_signature_rsa_pkcs1_x509_data,
- &asn1_oid_id_pkcs1_rsaEncryption,
+ ASN1_OID_ID_PKCS1_RSAENCRYPTION,
NULL,
PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
0,
@@ -1240,9 +1230,9 @@ static const struct signature_alg heim_rsa_pkcs1_x509 = {
static const struct signature_alg pkcs1_rsa_sha1_alg = {
"rsa",
- &asn1_oid_id_pkcs1_rsaEncryption,
+ ASN1_OID_ID_PKCS1_RSAENCRYPTION,
&_hx509_signature_rsa_with_sha1_data,
- &asn1_oid_id_pkcs1_rsaEncryption,
+ ASN1_OID_ID_PKCS1_RSAENCRYPTION,
NULL,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
0,
@@ -1253,9 +1243,9 @@ static const struct signature_alg pkcs1_rsa_sha1_alg = {
static const struct signature_alg rsa_with_sha256_alg = {
"rsa-with-sha256",
- &asn1_oid_id_pkcs1_sha256WithRSAEncryption,
+ ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION,
&_hx509_signature_rsa_with_sha256_data,
- &asn1_oid_id_pkcs1_rsaEncryption,
+ ASN1_OID_ID_PKCS1_RSAENCRYPTION,
&_hx509_signature_sha256_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
0,
@@ -1266,9 +1256,9 @@ static const struct signature_alg rsa_with_sha256_alg = {
static const struct signature_alg rsa_with_sha1_alg = {
"rsa-with-sha1",
- &asn1_oid_id_pkcs1_sha1WithRSAEncryption,
+ ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION,
&_hx509_signature_rsa_with_sha1_data,
- &asn1_oid_id_pkcs1_rsaEncryption,
+ ASN1_OID_ID_PKCS1_RSAENCRYPTION,
&_hx509_signature_sha1_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
0,
@@ -1277,25 +1267,25 @@ static const struct signature_alg rsa_with_sha1_alg = {
rsa_create_signature
};
-static const struct signature_alg rsa_with_md5_alg = {
- "rsa-with-md5",
- &asn1_oid_id_pkcs1_md5WithRSAEncryption,
- &_hx509_signature_rsa_with_md5_data,
- &asn1_oid_id_pkcs1_rsaEncryption,
- &_hx509_signature_md5_data,
- PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
- 1230739889,
+static const struct signature_alg rsa_with_sha1_alg_secsig = {
+ "rsa-with-sha1",
+ ASN1_OID_ID_SECSIG_SHA_1WITHRSAENCRYPTION,
+ &_hx509_signature_rsa_with_sha1_data,
+ ASN1_OID_ID_PKCS1_RSAENCRYPTION,
+ &_hx509_signature_sha1_data,
+ PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
+ 0,
NULL,
rsa_verify_signature,
rsa_create_signature
};
-static const struct signature_alg rsa_with_md2_alg = {
- "rsa-with-md2",
- &asn1_oid_id_pkcs1_md2WithRSAEncryption,
- &_hx509_signature_rsa_with_md2_data,
- &asn1_oid_id_pkcs1_rsaEncryption,
- &_hx509_signature_md2_data,
+static const struct signature_alg rsa_with_md5_alg = {
+ "rsa-with-md5",
+ ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION,
+ &_hx509_signature_rsa_with_md5_data,
+ ASN1_OID_ID_PKCS1_RSAENCRYPTION,
+ &_hx509_signature_md5_data,
PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1230739889,
NULL,
@@ -1305,9 +1295,9 @@ static const struct signature_alg rsa_with_md2_alg = {
static const struct signature_alg dsa_sha1_alg = {
"dsa-with-sha1",
- &asn1_oid_id_dsa_with_sha1,
+ ASN1_OID_ID_DSA_WITH_SHA1,
NULL,
- &asn1_oid_id_dsa,
+ ASN1_OID_ID_DSA,
&_hx509_signature_sha1_data,
PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
0,
@@ -1318,7 +1308,7 @@ static const struct signature_alg dsa_sha1_alg = {
static const struct signature_alg sha256_alg = {
"sha-256",
- &asn1_oid_id_sha256,
+ ASN1_OID_ID_SHA256,
&_hx509_signature_sha256_data,
NULL,
NULL,
@@ -1331,7 +1321,7 @@ static const struct signature_alg sha256_alg = {
static const struct signature_alg sha1_alg = {
"sha1",
- &asn1_oid_id_secsig_sha_1,
+ ASN1_OID_ID_SECSIG_SHA_1,
&_hx509_signature_sha1_data,
NULL,
NULL,
@@ -1344,7 +1334,7 @@ static const struct signature_alg sha1_alg = {
static const struct signature_alg md5_alg = {
"rsa-md5",
- &asn1_oid_id_rsa_digest_md5,
+ ASN1_OID_ID_RSA_DIGEST_MD5,
&_hx509_signature_md5_data,
NULL,
NULL,
@@ -1355,19 +1345,6 @@ static const struct signature_alg md5_alg = {
NULL
};
-static const struct signature_alg md2_alg = {
- "rsa-md2",
- &asn1_oid_id_rsa_digest_md2,
- &_hx509_signature_md2_data,
- NULL,
- NULL,
- SIG_DIGEST,
- 0,
- EVP_md2,
- evp_md_verify_signature,
- NULL
-};
-
/*
* Order matter in this structure, "best" first for each "key
* compatible" type (type is ECDSA, RSA, DSA, none, etc)
@@ -1380,15 +1357,14 @@ static const struct signature_alg *sig_algs[] = {
#endif
&rsa_with_sha256_alg,
&rsa_with_sha1_alg,
+ &rsa_with_sha1_alg_secsig,
&pkcs1_rsa_sha1_alg,
&rsa_with_md5_alg,
- &rsa_with_md2_alg,
&heim_rsa_pkcs1_x509,
&dsa_sha1_alg,
&sha256_alg,
&sha1_alg,
&md5_alg,
- &md2_alg,
NULL
};
@@ -1641,7 +1617,7 @@ _hx509_public_encrypt(hx509_context context,
ciphertext->length = ret;
ciphertext->data = to;
- ret = der_copy_oid(&asn1_oid_id_pkcs1_rsaEncryption, encryption_oid);
+ ret = der_copy_oid(ASN1_OID_ID_PKCS1_RSAENCRYPTION, encryption_oid);
if (ret) {
der_free_octet_string(ciphertext);
hx509_set_error_string(context, 0, ENOMEM, "out of memory");
@@ -1750,7 +1726,7 @@ _hx509_generate_private_key_init(hx509_context context,
{
*ctx = NULL;
- if (der_heim_oid_cmp(oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0) {
+ if (der_heim_oid_cmp(oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) {
hx509_set_error_string(context, 0, EINVAL,
"private key not an RSA key");
return EINVAL;
@@ -1845,10 +1821,6 @@ hx509_signature_md5(void)
{ return &_hx509_signature_md5_data; }
const AlgorithmIdentifier *
-hx509_signature_md2(void)
-{ return &_hx509_signature_md2_data; }
-
-const AlgorithmIdentifier *
hx509_signature_ecPublicKey(void)
{ return &_hx509_signature_ecPublicKey; }
@@ -1881,10 +1853,6 @@ hx509_signature_rsa_with_md5(void)
{ return &_hx509_signature_rsa_with_md5_data; }
const AlgorithmIdentifier *
-hx509_signature_rsa_with_md2(void)
-{ return &_hx509_signature_rsa_with_md2_data; }
-
-const AlgorithmIdentifier *
hx509_signature_rsa(void)
{ return &_hx509_signature_rsa_data; }
@@ -1961,11 +1929,11 @@ _hx509_private_key_free(hx509_private_key *key)
if (--(*key)->ref > 0)
return 0;
- if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) {
+ if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
if ((*key)->private_key.rsa)
RSA_free((*key)->private_key.rsa);
#ifdef HAVE_OPENSSL
- } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0) {
+ } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0) {
if ((*key)->private_key.ecdsa)
EC_KEY_free((*key)->private_key.ecdsa);
#endif
@@ -1982,7 +1950,7 @@ _hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
if (key->private_key.rsa)
RSA_free(key->private_key.rsa);
key->private_key.rsa = ptr;
- key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
+ key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
key->md = &pkcs1_rsa_sha1_alg;
}
@@ -2048,7 +2016,11 @@ struct hx509cipher {
struct hx509_crypto_data {
char *name;
int flags;
-#define ALLOW_WEAK 1
+#define ALLOW_WEAK 1
+
+#define PADDING_NONE 2
+#define PADDING_PKCS7 4
+#define PADDING_FLAGS (2|4)
const struct hx509cipher *cipher;
const EVP_CIPHER *c;
heim_octet_string key;
@@ -2204,7 +2176,7 @@ static const struct hx509cipher ciphers[] = {
{
"rc2-cbc",
CIPHER_WEAK,
- &asn1_oid_id_pkcs3_rc2_cbc,
+ ASN1_OID_ID_PKCS3_RC2_CBC,
NULL,
EVP_rc2_cbc,
CMSRC2CBCParam_get,
@@ -2213,7 +2185,7 @@ static const struct hx509cipher ciphers[] = {
{
"rc2-cbc",
CIPHER_WEAK,
- &asn1_oid_id_rsadsi_rc2_cbc,
+ ASN1_OID_ID_RSADSI_RC2_CBC,
NULL,
EVP_rc2_cbc,
CMSRC2CBCParam_get,
@@ -2231,7 +2203,7 @@ static const struct hx509cipher ciphers[] = {
{
"des-ede3-cbc",
0,
- &asn1_oid_id_pkcs3_des_ede3_cbc,
+ ASN1_OID_ID_PKCS3_DES_EDE3_CBC,
NULL,
EVP_des_ede3_cbc,
CMSCBCParam_get,
@@ -2240,7 +2212,7 @@ static const struct hx509cipher ciphers[] = {
{
"des-ede3-cbc",
0,
- &asn1_oid_id_rsadsi_des_ede3_cbc,
+ ASN1_OID_ID_RSADSI_DES_EDE3_CBC,
hx509_crypto_des_rsdi_ede3_cbc,
EVP_des_ede3_cbc,
CMSCBCParam_get,
@@ -2249,7 +2221,7 @@ static const struct hx509cipher ciphers[] = {
{
"aes-128-cbc",
0,
- &asn1_oid_id_aes_128_cbc,
+ ASN1_OID_ID_AES_128_CBC,
hx509_crypto_aes128_cbc,
EVP_aes_128_cbc,
CMSCBCParam_get,
@@ -2258,7 +2230,7 @@ static const struct hx509cipher ciphers[] = {
{
"aes-192-cbc",
0,
- &asn1_oid_id_aes_192_cbc,
+ ASN1_OID_ID_AES_192_CBC,
NULL,
EVP_aes_192_cbc,
CMSCBCParam_get,
@@ -2267,7 +2239,7 @@ static const struct hx509cipher ciphers[] = {
{
"aes-256-cbc",
0,
- &asn1_oid_id_aes_256_cbc,
+ ASN1_OID_ID_AES_256_CBC,
hx509_crypto_aes256_cbc,
EVP_aes_256_cbc,
CMSCBCParam_get,
@@ -2334,6 +2306,7 @@ hx509_crypto_init(hx509_context context,
return ENOMEM;
}
+ (*crypto)->flags = PADDING_PKCS7;
(*crypto)->cipher = cipher;
(*crypto)->c = (*cipher->evp_func)();
@@ -2379,6 +2352,23 @@ hx509_crypto_allow_weak(hx509_crypto crypto)
crypto->flags |= ALLOW_WEAK;
}
+void
+hx509_crypto_set_padding(hx509_crypto crypto, int padding_type)
+{
+ switch (padding_type) {
+ case HX509_CRYPTO_PADDING_PKCS7:
+ crypto->flags &= ~PADDING_FLAGS;
+ crypto->flags |= PADDING_PKCS7;
+ break;
+ case HX509_CRYPTO_PADDING_NONE:
+ crypto->flags &= ~PADDING_FLAGS;
+ crypto->flags |= PADDING_NONE;
+ break;
+ default:
+ _hx509_abort("Invalid padding");
+ }
+}
+
int
hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
{
@@ -2497,12 +2487,17 @@ hx509_crypto_encrypt(hx509_crypto crypto,
goto out;
}
- if (EVP_CIPHER_block_size(crypto->c) == 1) {
+ assert(crypto->flags & PADDING_FLAGS);
+ if (crypto->flags & PADDING_NONE) {
padsize = 0;
- } else {
- int bsize = EVP_CIPHER_block_size(crypto->c);
- padsize = bsize - (length % bsize);
+ } else if (crypto->flags & PADDING_PKCS7) {
+ if (EVP_CIPHER_block_size(crypto->c) == 1) {
+ } else {
+ int bsize = EVP_CIPHER_block_size(crypto->c);
+ padsize = bsize - (length % bsize);
+ }
}
+
(*ciphertext)->length = length + padsize;
(*ciphertext)->data = malloc(length + padsize);
if ((*ciphertext)->data == NULL) {
@@ -2592,7 +2587,7 @@ hx509_crypto_decrypt(hx509_crypto crypto,
}
EVP_CIPHER_CTX_cleanup(&evp);
- if (EVP_CIPHER_block_size(crypto->c) > 1) {
+ if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) {
int padsize;
unsigned char *p;
int j, bsize = EVP_CIPHER_block_size(crypto->c);
@@ -2704,33 +2699,33 @@ find_string2key(const heim_oid *oid,
const EVP_MD **md,
PBE_string2key_func *s2k)
{
- if (der_heim_oid_cmp(oid, &asn1_oid_id_pbewithSHAAnd40BitRC2_CBC) == 0) {
+ if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) {
*c = EVP_rc2_40_cbc();
*md = EVP_sha1();
*s2k = PBE_string2key;
return &asn1_oid_private_rc2_40;
- } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC2_CBC) == 0) {
+ } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) {
*c = EVP_rc2_cbc();
*md = EVP_sha1();
*s2k = PBE_string2key;
- return &asn1_oid_id_pkcs3_rc2_cbc;
+ return ASN1_OID_ID_PKCS3_RC2_CBC;
#if 0
- } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd40BitRC4) == 0) {
+ } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC4) == 0) {
*c = EVP_rc4_40();
*md = EVP_sha1();
*s2k = PBE_string2key;
return NULL;
- } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC4) == 0) {
+ } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC4) == 0) {
*c = EVP_rc4();
*md = EVP_sha1();
*s2k = PBE_string2key;
- return &asn1_oid_id_pkcs3_rc4;
+ return ASN1_OID_ID_PKCS3_RC4;
#endif
- } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC) == 0) {
+ } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) {
*c = EVP_des_ede3_cbc();
*md = EVP_sha1();
*s2k = PBE_string2key;
- return &asn1_oid_id_pkcs3_des_ede3_cbc;
+ return ASN1_OID_ID_PKCS3_DES_EDE3_CBC;
}
return NULL;
@@ -2907,9 +2902,9 @@ match_keys_ec(hx509_cert c, hx509_private_key private_key)
int
_hx509_match_keys(hx509_cert c, hx509_private_key key)
{
- if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0)
+ if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0)
return match_keys_rsa(c, key);
- if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0)
+ if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0)
return match_keys_ec(c, key);
return 0;
diff --git a/source4/heimdal/lib/hx509/hx509.h b/source4/heimdal/lib/hx509/hx509.h
index 86aad7ec9c..b6eeac9d18 100644
--- a/source4/heimdal/lib/hx509/hx509.h
+++ b/source4/heimdal/lib/hx509/hx509.h
@@ -71,6 +71,11 @@ enum {
HX509_VALIDATE_F_VERBOSE = 2
};
+enum {
+ HX509_CRYPTO_PADDING_PKCS7 = 0,
+ HX509_CRYPTO_PADDING_NONE = 1
+};
+
struct hx509_cert_attribute_data {
heim_oid oid;
heim_octet_string data;
@@ -157,6 +162,8 @@ typedef enum {
#define HX509_CMS_SIGNATURE_DETACHED 0x01
#define HX509_CMS_SIGNATURE_ID_NAME 0x02
#define HX509_CMS_SIGNATURE_NO_SIGNER 0x04
+#define HX509_CMS_SIGNATURE_LEAF_ONLY 0x08
+#define HX509_CMS_SIGNATURE_NO_CERTS 0x10
/* hx509_verify_hostname nametype */
typedef enum {
diff --git a/source4/heimdal/lib/hx509/ks_p11.c b/source4/heimdal/lib/hx509/ks_p11.c
index 52697f834b..23f6a4826a 100644
--- a/source4/heimdal/lib/hx509/ks_p11.c
+++ b/source4/heimdal/lib/hx509/ks_p11.c
@@ -835,7 +835,7 @@ p11_init(hx509_context context,
goto out;
}
- getFuncs = dlsym(p->dl_handle, "C_GetFunctionList");
+ getFuncs = (CK_C_GetFunctionList) dlsym(p->dl_handle, "C_GetFunctionList");
if (getFuncs == NULL) {
ret = HX509_PKCS11_LOAD;
hx509_set_error_string(context, 0, ret,
@@ -1139,7 +1139,6 @@ p11_printinfo(hx509_context context,
MECHNAME(CKM_SHA256, "sha256");
MECHNAME(CKM_SHA_1, "sha1");
MECHNAME(CKM_MD5, "md5");
- MECHNAME(CKM_MD2, "md2");
MECHNAME(CKM_RIPEMD160, "ripemd-160");
MECHNAME(CKM_DES_ECB, "des-ecb");
MECHNAME(CKM_DES_CBC, "des-cbc");
diff --git a/source4/heimdal/lib/hx509/name.c b/source4/heimdal/lib/hx509/name.c
index e795b1e44e..83b8f86d41 100644
--- a/source4/heimdal/lib/hx509/name.c
+++ b/source4/heimdal/lib/hx509/name.c
@@ -33,6 +33,7 @@
#include "hx_locl.h"
#include <wind.h>
+#include "char_map.h"
/**
* @page page_name PKIX/X.509 Names
@@ -79,11 +80,11 @@ static const struct {
};
static char *
-quote_string(const char *f, size_t len, size_t *rlen)
+quote_string(const char *f, size_t len, int flags, size_t *rlen)
{
size_t i, j, tolen;
- const char *from = f;
- char *to;
+ const unsigned char *from = (const unsigned char *)f;
+ unsigned char *to;
tolen = len * 3 + 1;
to = malloc(tolen);
@@ -91,26 +92,29 @@ quote_string(const char *f, size_t len, size_t *rlen)
return NULL;
for (i = 0, j = 0; i < len; i++) {
- if (from[i] == ' ' && i + 1 < len)
+ unsigned char map = char_map[from[i]] & flags;
+ if (i == 0 && (map & Q_RFC2253_QUOTE_FIRST)) {
+ to[j++] = '\\';
to[j++] = from[i];
- else if (from[i] == ',' || from[i] == '=' || from[i] == '+' ||
- from[i] == '<' || from[i] == '>' || from[i] == '#' ||
- from[i] == ';' || from[i] == ' ')
- {
+ } else if ((i + 1) == len && (map & Q_RFC2253_QUOTE_LAST)) {
+
to[j++] = '\\';
to[j++] = from[i];
- } else if (((unsigned char)from[i]) >= 32 && ((unsigned char)from[i]) <= 127) {
+ } else if (map & Q_RFC2253_QUOTE) {
+ to[j++] = '\\';
to[j++] = from[i];
- } else {
- int l = snprintf(&to[j], tolen - j - 1,
+ } else if (map & Q_RFC2253_HEX) {
+ int l = snprintf((char *)&to[j], tolen - j - 1,
"#%02x", (unsigned char)from[i]);
j += l;
+ } else {
+ to[j++] = from[i];
}
}
to[j] = '\0';
assert(j < tolen);
*rlen = j;
- return to;
+ return (char *)to;
}
@@ -121,7 +125,7 @@ append_string(char **str, size_t *total_len, const char *ss,
char *s, *qs;
if (quote)
- qs = quote_string(ss, len, &len);
+ qs = quote_string(ss, len, Q_RFC2253, &len);
else
qs = rk_UNCONST(ss);
@@ -203,7 +207,7 @@ _hx509_Name_to_string(const Name *n, char **str)
return ENOMEM;
for (i = n->u.rdnSequence.len - 1 ; i >= 0 ; i--) {
- int len;
+ size_t len;
for (j = 0; j < n->u.rdnSequence.val[i].len; j++) {
DirectoryString *ds = &n->u.rdnSequence.val[i].val[j].value;
@@ -214,13 +218,16 @@ _hx509_Name_to_string(const Name *n, char **str)
switch(ds->element) {
case choice_DirectoryString_ia5String:
- ss = ds->u.ia5String;
+ ss = ds->u.ia5String.data;
+ len = ds->u.ia5String.length;
break;
case choice_DirectoryString_printableString:
- ss = ds->u.printableString;
+ ss = ds->u.printableString.data;
+ len = ds->u.printableString.length;
break;
case choice_DirectoryString_utf8String:
ss = ds->u.utf8String;
+ len = strlen(ss);
break;
case choice_DirectoryString_bmpString: {
const uint16_t *bmp = ds->u.bmpString.data;
@@ -240,10 +247,12 @@ _hx509_Name_to_string(const Name *n, char **str)
return ret;
}
ss[k] = '\0';
+ len = k;
break;
}
case choice_DirectoryString_teletexString:
ss = ds->u.teletexString;
+ len = strlen(ss);
break;
case choice_DirectoryString_universalString: {
const uint32_t *uni = ds->u.universalString.data;
@@ -263,6 +272,7 @@ _hx509_Name_to_string(const Name *n, char **str)
return ret;
}
ss[k] = '\0';
+ len = k;
break;
}
default:
@@ -272,10 +282,9 @@ _hx509_Name_to_string(const Name *n, char **str)
append_string(str, &total_len, oidname, strlen(oidname), 0);
free(oidname);
append_string(str, &total_len, "=", 1, 0);
- len = strlen(ss);
append_string(str, &total_len, ss, len, 1);
- if (ds->element == choice_DirectoryString_universalString ||
- ds->element == choice_DirectoryString_bmpString)
+ if (ds->element == choice_DirectoryString_bmpString ||
+ ds->element == choice_DirectoryString_universalString)
{
free(ss);
}
@@ -319,7 +328,7 @@ _hx509_Name_to_string(const Name *n, char **str)
static int
dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
{
- wind_profile_flags flags = 0;
+ wind_profile_flags flags;
size_t i, len;
int ret;
uint32_t *name;
@@ -329,22 +338,28 @@ dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
switch(ds->element) {
case choice_DirectoryString_ia5String:
- COPYCHARARRAY(ds, ia5String, len, name);
+ flags = WIND_PROFILE_LDAP;
+ COPYVOIDARRAY(ds, ia5String, len, name);
break;
case choice_DirectoryString_printableString:
- flags = WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE;
- COPYCHARARRAY(ds, printableString, len, name);
+ flags = WIND_PROFILE_LDAP;
+ flags |= WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE;
+ COPYVOIDARRAY(ds, printableString, len, name);
break;
case choice_DirectoryString_teletexString:
+ flags = WIND_PROFILE_LDAP_CASE;
COPYCHARARRAY(ds, teletexString, len, name);
break;
case choice_DirectoryString_bmpString:
+ flags = WIND_PROFILE_LDAP;
COPYVALARRAY(ds, bmpString, len, name);
break;
case choice_DirectoryString_universalString:
+ flags = WIND_PROFILE_LDAP;
COPYVALARRAY(ds, universalString, len, name);
break;
case choice_DirectoryString_utf8String:
+ flags = WIND_PROFILE_LDAP;
ret = wind_utf8ucs4_length(ds->u.utf8String, &len);
if (ret)
return ret;
@@ -367,8 +382,7 @@ dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
*rlen = *rlen * 2;
*rname = malloc(*rlen * sizeof((*rname)[0]));
- ret = wind_stringprep(name, len, *rname, rlen,
- WIND_PROFILE_LDAP|flags);
+ ret = wind_stringprep(name, len, *rname, rlen, flags);
if (ret == WIND_ERR_OVERRUN) {
free(*rname);
*rname = NULL;
@@ -934,12 +948,14 @@ hx509_general_name_unparse(GeneralName *name, char **str)
break;
}
case choice_GeneralName_rfc822Name:
- strpool = rk_strpoolprintf(strpool, "rfc822Name: %s\n",
- name->u.rfc822Name);
+ strpool = rk_strpoolprintf(strpool, "rfc822Name: %.*s\n",
+ (int)name->u.rfc822Name.length,
+ (char *)name->u.rfc822Name.data);
break;
case choice_GeneralName_dNSName:
- strpool = rk_strpoolprintf(strpool, "dNSName: %s\n",
- name->u.dNSName);
+ strpool = rk_strpoolprintf(strpool, "dNSName: %.*s\n",
+ (int)name->u.dNSName.length,
+ (char *)name->u.dNSName.data);
break;
case choice_GeneralName_directoryName: {
Name dir;
@@ -956,8 +972,9 @@ hx509_general_name_unparse(GeneralName *name, char **str)
break;
}
case choice_GeneralName_uniformResourceIdentifier:
- strpool = rk_strpoolprintf(strpool, "URI: %s",
- name->u.uniformResourceIdentifier);
+ strpool = rk_strpoolprintf(strpool, "URI: %.*s",
+ (int)name->u.uniformResourceIdentifier.length,
+ (char *)name->u.uniformResourceIdentifier.data);
break;
case choice_GeneralName_iPAddress: {
unsigned char *a = name->u.iPAddress.data;
diff --git a/source4/heimdal/lib/hx509/req.c b/source4/heimdal/lib/hx509/req.c
index 0d174e0cec..917f08891b 100644
--- a/source4/heimdal/lib/hx509/req.c
+++ b/source4/heimdal/lib/hx509/req.c
@@ -143,7 +143,8 @@ _hx509_request_add_dns_name(hx509_context context,
memset(&name, 0, sizeof(name));
name.element = choice_GeneralName_dNSName;
- name.u.dNSName = rk_UNCONST(hostname);
+ name.u.dNSName.data = rk_UNCONST(hostname);
+ name.u.dNSName.length = strlen(hostname);
return add_GeneralNames(&req->san, &name);
}
@@ -157,7 +158,8 @@ _hx509_request_add_email(hx509_context context,
memset(&name, 0, sizeof(name));
name.element = choice_GeneralName_rfc822Name;
- name.u.dNSName = rk_UNCONST(email);
+ name.u.dNSName.data = rk_UNCONST(email);
+ name.u.dNSName.length = strlen(email);
return add_GeneralNames(&req->san, &name);
}
diff --git a/source4/heimdal/lib/hx509/sel.c b/source4/heimdal/lib/hx509/sel.c
index 5932ce84c3..561818c9f1 100644
--- a/source4/heimdal/lib/hx509/sel.c
+++ b/source4/heimdal/lib/hx509/sel.c
@@ -175,6 +175,7 @@ _hx509_expr_eval(hx509_context context, hx509_env env, struct hx_expr *expr)
return eval_comp(context, env, expr->arg1);
default:
_hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
+ UNREACHABLE(return 0);
}
}
diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c
index 19a5997453..6f20cdcf6c 100644
--- a/source4/heimdal/lib/krb5/acache.c
+++ b/source4/heimdal/lib/krb5/acache.c
@@ -43,8 +43,8 @@
static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
static cc_initialize_func init_func;
-static void (*set_target_uid)(uid_t);
-static void (*clear_target)(void);
+static void (KRB5_CALLCONV *set_target_uid)(uid_t);
+static void (KRB5_CALLCONV *clear_target)(void);
#ifdef HAVE_DLOPEN
static void *cc_handle;
@@ -56,7 +56,7 @@ typedef struct krb5_acc {
cc_ccache_t ccache;
} krb5_acc;
-static krb5_error_code acc_close(krb5_context, krb5_ccache);
+static krb5_error_code KRB5_CALLCONV acc_close(krb5_context, krb5_ccache);
#define ACACHE(X) ((krb5_acc *)(X)->data.data)
@@ -106,6 +106,8 @@ init_ccapi(krb5_context context)
if (lib == NULL) {
#ifdef __APPLE__
lib = "/System/Library/Frameworks/Kerberos.framework/Kerberos";
+#elif defined(KRB5_USE_PATH_TOKENS) && defined(_WIN32)
+ lib = "%{LIBDIR}/libkrb5_cc.dll";
#else
lib = "/usr/lib/libkrb5_cc.so";
#endif
@@ -120,7 +122,18 @@ init_ccapi(krb5_context context)
#define RTLD_LOCAL 0
#endif
+#ifdef KRB5_USE_PATH_TOKENS
+ {
+ char * explib = NULL;
+ if (_krb5_expand_path_tokens(context, lib, &explib) == 0) {
+ cc_handle = dlopen(explib, RTLD_LAZY|RTLD_LOCAL);
+ free(explib);
+ }
+ }
+#else
cc_handle = dlopen(lib, RTLD_LAZY|RTLD_LOCAL);
+#endif
+
if (cc_handle == NULL) {
HEIMDAL_MUTEX_unlock(&acc_mutex);
if (context)
@@ -131,8 +144,10 @@ init_ccapi(krb5_context context)
}
init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize");
- set_target_uid = dlsym(cc_handle, "krb5_ipc_client_set_target_uid");
- clear_target = dlsym(cc_handle, "krb5_ipc_client_clear_target");
+ set_target_uid = (void (KRB5_CALLCONV *)(uid_t))
+ dlsym(cc_handle, "krb5_ipc_client_set_target_uid");
+ clear_target = (void (KRB5_CALLCONV *)(void))
+ dlsym(cc_handle, "krb5_ipc_client_clear_target");
HEIMDAL_MUTEX_unlock(&acc_mutex);
if (init_func == NULL) {
if (context)
@@ -157,14 +172,16 @@ void
_heim_krb5_ipc_client_set_target_uid(uid_t uid)
{
init_ccapi(NULL);
- (*set_target_uid)(uid);
+ if (set_target_uid != NULL)
+ (*set_target_uid)(uid);
}
void
_heim_krb5_ipc_client_clear_target(void)
{
init_ccapi(NULL);
- (*clear_target)();
+ if (clear_target != NULL)
+ (*clear_target)();
}
static krb5_error_code
@@ -436,7 +453,7 @@ get_cc_name(krb5_acc *a)
}
-static const char*
+static const char* KRB5_CALLCONV
acc_get_name(krb5_context context,
krb5_ccache id)
{
@@ -473,7 +490,7 @@ acc_get_name(krb5_context context,
return a->cache_name;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_alloc(krb5_context context, krb5_ccache *id)
{
krb5_error_code ret;
@@ -503,7 +520,7 @@ acc_alloc(krb5_context context, krb5_ccache *id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
{
krb5_error_code ret;
@@ -543,7 +560,7 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_gen_new(krb5_context context, krb5_ccache *id)
{
krb5_error_code ret;
@@ -561,7 +578,7 @@ acc_gen_new(krb5_context context, krb5_ccache *id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_initialize(krb5_context context,
krb5_ccache id,
krb5_principal primary_principal)
@@ -615,7 +632,7 @@ acc_initialize(krb5_context context,
return translate_cc_error(context, error);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_close(krb5_context context,
krb5_ccache id)
{
@@ -637,7 +654,7 @@ acc_close(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_destroy(krb5_context context,
krb5_ccache id)
{
@@ -655,7 +672,7 @@ acc_destroy(krb5_context context,
return translate_cc_error(context, error);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_store_cred(krb5_context context,
krb5_ccache id,
krb5_creds *creds)
@@ -690,7 +707,7 @@ acc_store_cred(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_get_principal(krb5_context context,
krb5_ccache id,
krb5_principal *principal)
@@ -718,7 +735,7 @@ acc_get_principal(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_get_first (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
@@ -743,7 +760,7 @@ acc_get_first (krb5_context context,
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_get_next (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor,
@@ -770,7 +787,7 @@ acc_get_next (krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_end_get (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
@@ -780,7 +797,7 @@ acc_end_get (krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_remove_cred(krb5_context context,
krb5_ccache id,
krb5_flags which,
@@ -856,7 +873,7 @@ acc_remove_cred(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_set_flags(krb5_context context,
krb5_ccache id,
krb5_flags flags)
@@ -864,7 +881,7 @@ acc_set_flags(krb5_context context,
return 0;
}
-static int
+static int KRB5_CALLCONV
acc_get_version(krb5_context context,
krb5_ccache id)
{
@@ -876,7 +893,7 @@ struct cache_iter {
cc_ccache_iterator_t iter;
};
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
{
struct cache_iter *iter;
@@ -910,7 +927,7 @@ acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
{
struct cache_iter *iter = cursor;
@@ -948,7 +965,7 @@ acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
{
struct cache_iter *iter = cursor;
@@ -961,7 +978,7 @@ acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
{
krb5_acc *afrom = ACACHE(from);
@@ -993,7 +1010,7 @@ acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
return translate_cc_error(context, error);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_get_default_name(krb5_context context, char **str)
{
krb5_error_code ret;
@@ -1015,18 +1032,18 @@ acc_get_default_name(krb5_context context, char **str)
return translate_cc_error(context, error);
}
- asprintf(str, "API:%s", name->data);
+ error = asprintf(str, "API:%s", name->data);
(*name->func->release)(name);
(*cc->func->release)(cc);
- if (*str == NULL) {
+ if (error < 0 || *str == NULL) {
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
return ENOMEM;
}
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_set_default(krb5_context context, krb5_ccache id)
{
krb5_acc *a = ACACHE(id);
@@ -1045,7 +1062,7 @@ acc_set_default(krb5_context context, krb5_ccache id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
acc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime)
{
krb5_acc *a = ACACHE(id);
diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c
index ce8040d07c..32a131b07c 100644
--- a/source4/heimdal/lib/krb5/cache.c
+++ b/source4/heimdal/lib/krb5/cache.c
@@ -83,7 +83,7 @@ main (int argc, char **argv)
while((ret = krb5_cc_next_cred(context, id, &cursor, &creds)) == 0){
char *principal;
- krb5_unparse_name_short(context, creds.server, &principal);
+ krb5_unparse_name(context, creds.server, &principal);
printf("principal: %s\\n", principal);
free(principal);
krb5_free_cred_contents (context, &creds);
@@ -206,8 +206,10 @@ allocate_ccache (krb5_context context,
}
ret = (*id)->ops->resolve(context, id, residual);
- if(ret)
+ if(ret) {
free(*id);
+ *id = NULL;
+ }
#ifdef KRB5_USE_PATH_TOKENS
if (exp_residual)
@@ -217,6 +219,25 @@ allocate_ccache (krb5_context context,
return ret;
}
+static int
+is_possible_path_name(const char * name)
+{
+ const char * colon;
+
+ if ((colon = strchr(name, ':')) == NULL)
+ return TRUE;
+
+#ifdef _WIN32
+ /* <drive letter>:\path\to\cache ? */
+
+ if (colon == name + 1 &&
+ strchr(colon + 1, ':') == NULL)
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
/**
* Find and allocate a ccache in `id' from the specification in `residual'.
* If the ccache name doesn't contain any colon, interpret it as a file name.
@@ -251,7 +272,7 @@ krb5_cc_resolve(krb5_context context,
id);
}
}
- if (strchr (name, ':') == NULL)
+ if (is_possible_path_name(name))
return allocate_ccache (context, &krb5_fcc_ops, name, id);
else {
krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE,
@@ -389,84 +410,7 @@ krb5_cc_get_ops(krb5_context context, krb5_ccache id)
krb5_error_code
_krb5_expand_default_cc_name(krb5_context context, const char *str, char **res)
{
-#ifndef KRB5_USE_PATH_TOKENS
- size_t tlen, len = 0;
- char *tmp, *tmp2, *append;
-
- *res = NULL;
-
- while (str && *str) {
- tmp = strstr(str, "%{");
- if (tmp && tmp != str) {
- append = malloc((tmp - str) + 1);
- if (append) {
- memcpy(append, str, tmp - str);
- append[tmp - str] = '\0';
- }
- str = tmp;
- } else if (tmp) {
- tmp2 = strchr(tmp, '}');
- if (tmp2 == NULL) {
- if (*res)
- free(*res);
- *res = NULL;
- krb5_set_error_message(context, KRB5_CONFIG_BADFORMAT,
- "variable missing }");
- return KRB5_CONFIG_BADFORMAT;
- }
- if (strncasecmp(tmp, "%{uid}", 6) == 0)
- asprintf(&append, "%u", (unsigned)getuid());
- else if (strncasecmp(tmp, "%{null}", 7) == 0)
- append = strdup("");
- else {
- if (*res)
- free(*res);
- *res = NULL;
- krb5_set_error_message(context,
- KRB5_CONFIG_BADFORMAT,
- "expand default cache unknown "
- "variable \"%.*s\"",
- (int)(tmp2 - tmp) - 2, tmp + 2);
- return KRB5_CONFIG_BADFORMAT;
- }
- str = tmp2 + 1;
- } else {
- append = strdup(str);
- str = NULL;
- }
- if (append == NULL) {
- if (*res)
- free(*res);
- *res = NULL;
- krb5_set_error_message(context, ENOMEM,
- N_("malloc: out of memory", ""));
- return ENOMEM;
- }
-
- tlen = strlen(append);
- tmp = realloc(*res, len + tlen + 1);
- if (tmp == NULL) {
- free(append);
- if (*res)
- free(*res);
- *res = NULL;
- krb5_set_error_message(context, ENOMEM,
- N_("malloc: out of memory", ""));
- return ENOMEM;
- }
- *res = tmp;
- memcpy(*res + len, append, tlen + 1);
- len = len + tlen;
- free(append);
- }
- return 0;
-#else /* _WIN32 */
- /* On Windows, we use the more generic _krb5_expand_path_tokens()
- function which also handles path tokens in addition to %{uid}
- and %{null} */
-
return _krb5_expand_path_tokens(context, str, res);
-#endif
}
/*
@@ -554,7 +498,7 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_cc_set_default_name(krb5_context context, const char *name)
{
krb5_error_code ret = 0;
- char *p;
+ char *p = NULL, *exp_p = NULL;
if (name == NULL) {
const char *e = NULL;
@@ -606,26 +550,17 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
return ENOMEM;
}
-#ifdef KRB5_USE_PATH_TOKENS
- {
- char * exp_p = NULL;
-
- if (_krb5_expand_path_tokens(context, p, &exp_p) == 0) {
- free (p);
- p = exp_p;
- } else {
- free (p);
- return EINVAL;
- }
- }
-#endif
+ ret = _krb5_expand_path_tokens(context, p, &exp_p);
+ free(p);
+ if (ret)
+ return ret;
if (context->default_cc_name)
free(context->default_cc_name);
- context->default_cc_name = p;
+ context->default_cc_name = exp_p;
- return ret;
+ return 0;
}
/**
@@ -1499,7 +1434,7 @@ krb5_cccol_cursor_next(krb5_context context, krb5_cccol_cursor cursor,
cursor->cursor = NULL;
if (ret != KRB5_CC_END)
break;
-
+
cursor->idx++;
}
if (cursor->idx >= context->num_cc_ops) {
diff --git a/source4/heimdal/lib/krb5/ccache_plugin.h b/source4/heimdal/lib/krb5/ccache_plugin.h
new file mode 100644
index 0000000000..f6871d65d1
--- /dev/null
+++ b/source4/heimdal/lib/krb5/ccache_plugin.h
@@ -0,0 +1,39 @@
+/***********************************************************************
+ * Copyright (c) 2010, Secure Endpoints Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+#ifndef HEIMDAL_KRB5_CCACHE_PLUGIN_H
+#define HEIMDAL_KRB5_CCACHE_PLUGIN_H 1
+
+#include <krb5.h>
+
+#define KRB5_PLUGIN_CCACHE "ccache_ops"
+
+#endif /* HEIMDAL_KRB5_CCACHE_PLUGIN_H */
diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c
index 4eb4e12fad..22d0b90bd8 100644
--- a/source4/heimdal/lib/krb5/config_file.c
+++ b/source4/heimdal/lib/krb5/config_file.c
@@ -239,7 +239,12 @@ parse_binding(struct fileptr *f, unsigned *lineno, char *p,
return ret;
}
-#ifdef __APPLE__
+#if defined(__APPLE__)
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
+#define HAVE_CFPROPERTYLISTCREATEWITHSTREAM 1
+#endif
+
static char *
cfstring2cstring(CFStringRef string)
{
@@ -293,7 +298,6 @@ parse_plist_config(krb5_context context, const char *path, krb5_config_section *
{
CFReadStreamRef s;
CFDictionaryRef d;
- CFErrorRef e;
CFURLRef url;
url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)path, strlen(path), FALSE);
@@ -315,7 +319,11 @@ parse_plist_config(krb5_context context, const char *path, krb5_config_section *
return ENOENT;
}
- d = (CFDictionaryRef)CFPropertyListCreateWithStream (kCFAllocatorDefault, s, 0, kCFPropertyListImmutable, NULL, &e);
+#ifdef HAVE_CFPROPERTYLISTCREATEWITHSTREAM
+ d = (CFDictionaryRef)CFPropertyListCreateWithStream(NULL, s, 0, kCFPropertyListImmutable, NULL, NULL);
+#else
+ d = (CFDictionaryRef)CFPropertyListCreateFromStream(NULL, s, 0, kCFPropertyListImmutable, NULL, NULL);
+#endif
CFRelease(s);
if (d == NULL) {
krb5_clear_error_message(context);
@@ -447,8 +455,9 @@ krb5_config_parse_file_multi (krb5_context context,
fname = newfname;
}
#else /* KRB5_USE_PATH_TOKENS */
- asprintf(&newfname, "%%{USERCONFIG}/%s", &fname[1]);
- if (newfname == NULL) {
+ if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 ||
+ newfname == NULL)
+ {
krb5_set_error_message(context, ENOMEM,
N_("malloc: out of memory", ""));
return ENOMEM;
diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c
index adcbb703ee..0897c5e7a0 100644
--- a/source4/heimdal/lib/krb5/context.c
+++ b/source4/heimdal/lib/krb5/context.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2010 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -215,6 +215,14 @@ init_context_from_config_file(krb5_context context)
krb5_config_free_strings(s);
}
+ tmp = krb5_config_get_string(context, NULL, "libdefaults",
+ "check-rd-req-server", NULL);
+ if (tmp == NULL && !issuid())
+ tmp = getenv("KRB5_CHECK_RD_REQ_SERVER");
+ if(tmp) {
+ if (strcasecmp(tmp, "ignore") == 0)
+ context->flags |= KRB5_CTX_F_RD_REQ_IGNORE;
+ }
return 0;
}
@@ -239,6 +247,7 @@ cc_ops_register(krb5_context context)
#endif
krb5_cc_register(context, &krb5_kcm_ops, TRUE);
#endif
+ _krb5_load_ccache_plugins(context);
return 0;
}
@@ -380,6 +389,13 @@ out:
#ifndef HEIMDAL_SMALLER
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_get_permitted_enctypes(krb5_context context,
+ krb5_enctype **etypes)
+{
+ return krb5_get_default_in_tkt_etypes(context, etypes);
+}
+
/*
*
*/
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index eda5e634d1..47f910260e 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -96,11 +96,11 @@ struct checksum_type {
size_t blocksize;
size_t checksumsize;
unsigned flags;
- krb5_enctype (*checksum)(krb5_context context,
- struct key_data *key,
- const void *buf, size_t len,
- unsigned usage,
- Checksum *csum);
+ krb5_error_code (*checksum)(krb5_context context,
+ struct key_data *key,
+ const void *buf, size_t len,
+ unsigned usage,
+ Checksum *csum);
krb5_error_code (*verify)(krb5_context context,
struct key_data *key,
const void *buf, size_t len,
@@ -4004,7 +4004,7 @@ krb5_generate_random_block(void *buf, size_t len)
rng_initialized = 1;
}
HEIMDAL_MUTEX_unlock(&crypto_mutex);
- if (RAND_bytes(buf, len) != 1)
+ if (RAND_bytes(buf, len) <= 0)
krb5_abortx(NULL, "Failed to generate random block");
}
diff --git a/source4/heimdal/lib/krb5/data.c b/source4/heimdal/lib/krb5/data.c
index 838135ffad..c4c202be5d 100644
--- a/source4/heimdal/lib/krb5/data.c
+++ b/source4/heimdal/lib/krb5/data.c
@@ -87,7 +87,7 @@ krb5_free_data(krb5_context context,
/**
* Allocate data of and krb5_data.
*
- * @param p krb5_data to free.
+ * @param p krb5_data to allocate.
* @param len size to allocate.
*
* @return Returns 0 to indicate success. Otherwise an kerberos et
diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c
index adab6f5e84..237d346f4d 100644
--- a/source4/heimdal/lib/krb5/error_string.c
+++ b/source4/heimdal/lib/krb5/error_string.c
@@ -96,11 +96,17 @@ krb5_vset_error_message (krb5_context context, krb5_error_code ret,
const char *fmt, va_list args)
__attribute__ ((format (printf, 3, 0)))
{
+ int r;
- krb5_clear_error_message(context);
HEIMDAL_MUTEX_lock(context->mutex);
+ if (context->error_string) {
+ free(context->error_string);
+ context->error_string = NULL;
+ }
context->error_code = ret;
- vasprintf(&context->error_string, fmt, args);
+ r = vasprintf(&context->error_string, fmt, args);
+ if (r < 0)
+ context->error_string = NULL;
HEIMDAL_MUTEX_unlock(context->mutex);
}
@@ -144,19 +150,22 @@ krb5_vprepend_error_message(krb5_context context, krb5_error_code ret,
const char *fmt, va_list args)
__attribute__ ((format (printf, 3, 0)))
{
- char *str, *str2;
+ char *str = NULL, *str2 = NULL;
HEIMDAL_MUTEX_lock(context->mutex);
if (context->error_code != ret) {
HEIMDAL_MUTEX_unlock(context->mutex);
return;
}
- vasprintf(&str, fmt, args);
+ if (vasprintf(&str, fmt, args) < 0 || str == NULL) {
+ HEIMDAL_MUTEX_unlock(context->mutex);
+ return;
+ }
if (context->error_string) {
int e;
e = asprintf(&str2, "%s: %s", str, context->error_string);
free(context->error_string);
- if (e < 0)
+ if (e < 0 || str2 == NULL)
context->error_string = NULL;
else
context->error_string = str2;
@@ -241,7 +250,7 @@ krb5_get_error_message(krb5_context context, krb5_error_code code)
return strdup(msg);
}
- if (asprintf(&str, "<unknown error: %d>", (int)code) == -1)
+ if (asprintf(&str, "<unknown error: %d>", (int)code) == -1 || str == NULL)
return NULL;
return str;
diff --git a/source4/heimdal/lib/krb5/expand_path.c b/source4/heimdal/lib/krb5/expand_path.c
new file mode 100644
index 0000000000..70096e1c7a
--- /dev/null
+++ b/source4/heimdal/lib/krb5/expand_path.c
@@ -0,0 +1,500 @@
+
+/***********************************************************************
+ * Copyright (c) 2009, Secure Endpoints Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+#include "krb5_locl.h"
+
+typedef int PTYPE;
+
+#ifdef _WIN32
+#include <shlobj.h>
+#include <sddl.h>
+
+/*
+ * Expand a %{TEMP} token
+ *
+ * The %{TEMP} token expands to the temporary path for the current
+ * user as returned by GetTempPath().
+ *
+ * @note: Since the GetTempPath() function relies on the TMP or TEMP
+ * environment variables, this function will failover to the system
+ * temporary directory until the user profile is loaded. In addition,
+ * the returned path may or may not exist.
+ */
+static int
+_expand_temp_folder(krb5_context context, PTYPE param, const char *postfix, char **ret)
+{
+ TCHAR tpath[MAX_PATH];
+ size_t len;
+
+ if (!GetTempPath(sizeof(tpath)/sizeof(tpath[0]), tpath)) {
+ if (context)
+ krb5_set_error_message(context, EINVAL,
+ "Failed to get temporary path (GLE=%d)",
+ GetLastError());
+ return EINVAL;
+ }
+
+ len = strlen(tpath);
+
+ if (len > 0 && tpath[len - 1] == '\\')
+ tpath[len - 1] = '\0';
+
+ *ret = strdup(tpath);
+
+ if (*ret == NULL) {
+ if (context)
+ krb5_set_error_message(context, ENOMEM, "strdup - Out of memory");
+ return ENOMEM;
+ }
+
+ return 0;
+}
+
+extern HINSTANCE _krb5_hInstance;
+
+/*
+ * Expand a %{BINDIR} token
+ *
+ * This is also used to expand a few other tokens on Windows, since
+ * most of the executable binaries end up in the same directory. The
+ * "bin" directory is considered to be the directory in which the
+ * krb5.dll is located.
+ */
+static int
+_expand_bin_dir(krb5_context context, PTYPE param, const char *postfix, char **ret)
+{
+ TCHAR path[MAX_PATH];
+ TCHAR *lastSlash;
+ DWORD nc;
+
+ nc = GetModuleFileName(_krb5_hInstance, path, sizeof(path)/sizeof(path[0]));
+ if (nc == 0 ||
+ nc == sizeof(path)/sizeof(path[0])) {
+ return EINVAL;
+ }
+
+ lastSlash = strrchr(path, '\\');
+ if (lastSlash != NULL) {
+ TCHAR *fslash = strrchr(lastSlash, '/');
+
+ if (fslash != NULL)
+ lastSlash = fslash;
+
+ *lastSlash = '\0';
+ }
+
+ if (postfix) {
+ if (strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0]))
+ return EINVAL;
+ }
+
+ *ret = strdup(path);
+ if (*ret == NULL)
+ return ENOMEM;
+
+ return 0;
+}
+
+/*
+ * Expand a %{USERID} token
+ *
+ * The %{USERID} token expands to the string representation of the
+ * user's SID. The user account that will be used is the account
+ * corresponding to the current thread's security token. This means
+ * that:
+ *
+ * - If the current thread token has the anonymous impersonation
+ * level, the call will fail.
+ *
+ * - If the current thread is impersonating a token at
+ * SecurityIdentification level the call will fail.
+ *
+ */
+static int
+_expand_userid(krb5_context context, PTYPE param, const char *postfix, char **ret)
+{
+ int rv = EINVAL;
+ HANDLE hThread = NULL;
+ HANDLE hToken = NULL;
+ PTOKEN_OWNER pOwner = NULL;
+ DWORD len = 0;
+ LPTSTR strSid = NULL;
+
+ hThread = GetCurrentThread();
+
+ if (!OpenThreadToken(hThread, TOKEN_QUERY,
+ FALSE, /* Open the thread token as the
+ current thread user. */
+ &hToken)) {
+
+ DWORD le = GetLastError();
+
+ if (le == ERROR_NO_TOKEN) {
+ HANDLE hProcess = GetCurrentProcess();
+
+ le = 0;
+ if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
+ le = GetLastError();
+ }
+
+ if (le != 0) {
+ if (context)
+ krb5_set_error_message(context, rv,
+ "Can't open thread token (GLE=%d)", le);
+ goto _exit;
+ }
+ }
+
+ if (!GetTokenInformation(hToken, TokenOwner, NULL, 0, &len)) {
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ if (context)
+ krb5_set_error_message(context, rv,
+ "Unexpected error reading token information (GLE=%d)",
+ GetLastError());
+ goto _exit;
+ }
+
+ if (len == 0) {
+ if (context)
+ krb5_set_error_message(context, rv,
+ "GetTokenInformation() returned truncated buffer");
+ goto _exit;
+ }
+
+ pOwner = malloc(len);
+ if (pOwner == NULL) {
+ if (context)
+ krb5_set_error_message(context, rv, "Out of memory");
+ goto _exit;
+ }
+ } else {
+ if (context)
+ krb5_set_error_message(context, rv, "GetTokenInformation() returned truncated buffer");
+ goto _exit;
+ }
+
+ if (!GetTokenInformation(hToken, TokenOwner, pOwner, len, &len)) {
+ if (context)
+ krb5_set_error_message(context, rv, "GetTokenInformation() failed. GLE=%d", GetLastError());
+ goto _exit;
+ }
+
+ if (!ConvertSidToStringSid(pOwner->Owner, &strSid)) {
+ if (context)
+ krb5_set_error_message(context, rv, "Can't convert SID to string. GLE=%d", GetLastError());
+ goto _exit;
+ }
+
+ *ret = strdup(strSid);
+ if (*ret == NULL && context)
+ krb5_set_error_message(context, rv, "Out of memory");
+
+ rv = 0;
+
+ _exit:
+ if (hToken != NULL)
+ CloseHandle(hToken);
+
+ if (pOwner != NULL)
+ free (pOwner);
+
+ if (strSid != NULL)
+ LocalFree(strSid);
+
+ return rv;
+}
+
+/*
+ * Expand a folder identified by a CSIDL
+ */
+
+static int
+_expand_csidl(krb5_context context, PTYPE folder, const char *postfix, char **ret)
+{
+ TCHAR path[MAX_PATH];
+ size_t len;
+
+ if (SHGetFolderPath(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path) != S_OK) {
+ if (context)
+ krb5_set_error_message(context, EINVAL, "Unable to determine folder path");
+ return EINVAL;
+ }
+
+ len = strlen(path);
+
+ if (len > 0 && path[len - 1] == '\\')
+ path[len - 1] = '\0';
+
+ if (postfix &&
+ strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0])) {
+ return ENOMEM;
+ }
+
+ *ret = strdup(path);
+ if (*ret == NULL) {
+ if (context)
+ krb5_set_error_message(context, ENOMEM, "Out of memory");
+ return ENOMEM;
+ }
+ return 0;
+}
+
+#else
+
+static int
+_expand_path(krb5_context context, PTYPE param, const char *postfix, char **ret)
+{
+ *ret = strdup(postfix);
+ if (*ret == NULL) {
+ krb5_set_error_message(context, ENOMEM, "malloc - out of memory");
+ return ENOMEM;
+ }
+ return 0;
+}
+
+static int
+_expand_temp_folder(krb5_context context, PTYPE param, const char *postfix, char **ret)
+{
+ const char *p = NULL;
+
+ if (issuid())
+ p = getenv("TEMP");
+ if (p)
+ *ret = strdup(p);
+ else
+ *ret = strdup("/tmp");
+ if (*ret == NULL)
+ return ENOMEM;
+ return 0;
+}
+
+static int
+_expand_userid(krb5_context context, PTYPE param, const char *postfix, char **str)
+{
+ int ret = asprintf(str, "%ld", (unsigned long)getuid());
+ if (ret < 0 || *str == NULL)
+ return ENOMEM;
+ return 0;
+}
+
+
+#endif /* _WIN32 */
+
+/**
+ * Expand a %{null} token
+ *
+ * The expansion of a %{null} token is always the empty string.
+ */
+
+static int
+_expand_null(krb5_context context, PTYPE param, const char *postfix, char **ret)
+{
+ *ret = strdup("");
+ if (*ret == NULL) {
+ if (context)
+ krb5_set_error_message(context, ENOMEM, "Out of memory");
+ return ENOMEM;
+ }
+ return 0;
+}
+
+
+static const struct token {
+ const char * tok;
+ int ftype;
+#define FTYPE_CSIDL 0
+#define FTYPE_SPECIAL 1
+
+ PTYPE param;
+ const char * postfix;
+
+ int (*exp_func)(krb5_context, PTYPE, const char *, char **);
+
+#define SPECIALP(f, P) FTYPE_SPECIAL, 0, P, f
+#define SPECIAL(f) SPECIALP(f, NULL)
+
+} tokens[] = {
+#ifdef _WIN32
+#define CSIDLP(C,P) FTYPE_CSIDL, C, P, _expand_csidl
+#define CSIDL(C) CSIDLP(C, NULL)
+
+ {"APPDATA", CSIDL(CSIDL_APPDATA)}, /* Roaming application data (for current user) */
+ {"COMMON_APPDATA", CSIDL(CSIDL_COMMON_APPDATA)}, /* Application data (all users) */
+ {"LOCAL_APPDATA", CSIDL(CSIDL_LOCAL_APPDATA)}, /* Local application data (for current user) */
+ {"SYSTEM", CSIDL(CSIDL_SYSTEM)}, /* Windows System folder (e.g. %WINDIR%\System32) */
+ {"WINDOWS", CSIDL(CSIDL_WINDOWS)}, /* Windows folder */
+ {"USERCONFIG", CSIDLP(CSIDL_APPDATA, "\\" PACKAGE)}, /* Per user Heimdal configuration file path */
+ {"COMMONCONFIG", CSIDLP(CSIDL_COMMON_APPDATA, "\\" PACKAGE)}, /* Common Heimdal configuration file path */
+ {"LIBDIR", SPECIAL(_expand_bin_dir)},
+ {"BINDIR", SPECIAL(_expand_bin_dir)},
+ {"LIBEXEC", SPECIAL(_expand_bin_dir)},
+ {"SBINDIR", SPECIAL(_expand_bin_dir)},
+#else
+ {"LIBDIR", FTYPE_SPECIAL, 0, LIBDIR, _expand_path},
+ {"BINDIR", FTYPE_SPECIAL, 0, BINDIR, _expand_path},
+ {"LIBEXEC", FTYPE_SPECIAL, 0, LIBEXECDIR, _expand_path},
+ {"SBINDIR", FTYPE_SPECIAL, 0, SBINDIR, _expand_path},
+#endif
+ {"TEMP", SPECIAL(_expand_temp_folder)},
+ {"USERID", SPECIAL(_expand_userid)},
+ {"uid", SPECIAL(_expand_userid)},
+ {"null", SPECIAL(_expand_null)}
+};
+
+static int
+_expand_token(krb5_context context,
+ const char *token,
+ const char *token_end,
+ char **ret)
+{
+ size_t i;
+
+ *ret = NULL;
+
+ if (token[0] != '%' || token[1] != '{' || token_end[0] != '}' ||
+ token_end - token <= 2) {
+ if (context)
+ krb5_set_error_message(context, EINVAL,"Invalid token.");
+ return EINVAL;
+ }
+
+ for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) {
+ if (!strncmp(token+2, tokens[i].tok, (token_end - token) - 2))
+ return tokens[i].exp_func(context, tokens[i].param,
+ tokens[i].postfix, ret);
+ }
+
+ if (context)
+ krb5_set_error_message(context, EINVAL, "Invalid token.");
+ return EINVAL;
+}
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+_krb5_expand_path_tokens(krb5_context context,
+ const char *path_in,
+ char **ppath_out)
+{
+ char *tok_begin, *tok_end, *append;
+ const char *path_left;
+ size_t len = 0;
+
+ if (path_in == NULL || *path_in == '\0') {
+ *ppath_out = strdup("");
+ return 0;
+ }
+
+ *ppath_out = NULL;
+
+ for (path_left = path_in; path_left && *path_left; ) {
+
+ tok_begin = strstr(path_left, "%{");
+
+ if (tok_begin && tok_begin != path_left) {
+
+ append = malloc((tok_begin - path_left) + 1);
+ if (append) {
+ memcpy(append, path_left, tok_begin - path_left);
+ append[tok_begin - path_left] = '\0';
+ }
+ path_left = tok_begin;
+
+ } else if (tok_begin) {
+
+ tok_end = strchr(tok_begin, '}');
+ if (tok_end == NULL) {
+ if (*ppath_out)
+ free(*ppath_out);
+ *ppath_out = NULL;
+ if (context)
+ krb5_set_error_message(context, EINVAL, "variable missing }");
+ return EINVAL;
+ }
+
+ if (_expand_token(context, tok_begin, tok_end, &append)) {
+ if (*ppath_out)
+ free(*ppath_out);
+ *ppath_out = NULL;
+ return EINVAL;
+ }
+
+ path_left = tok_end + 1;
+ } else {
+
+ append = strdup(path_left);
+ path_left = NULL;
+
+ }
+
+ if (append == NULL) {
+
+ if (*ppath_out)
+ free(*ppath_out);
+ *ppath_out = NULL;
+ if (context)
+ krb5_set_error_message(context, ENOMEM, "malloc - out of memory");
+ return ENOMEM;
+
+ }
+
+ {
+ size_t append_len = strlen(append);
+ char * new_str = realloc(*ppath_out, len + append_len + 1);
+
+ if (new_str == NULL) {
+ free(append);
+ if (*ppath_out)
+ free(*ppath_out);
+ *ppath_out = NULL;
+ if (context)
+ krb5_set_error_message(context, ENOMEM, "malloc - out of memory");
+ return ENOMEM;
+ }
+
+ *ppath_out = new_str;
+ memcpy(*ppath_out + len, append, append_len + 1);
+ len = len + append_len;
+ free(append);
+ }
+ }
+
+#ifdef _WIN32
+ /* Also deal with slashes */
+ if (*ppath_out) {
+ char * c;
+ for (c = *ppath_out; *c; c++)
+ if (*c == '/')
+ *c = '\\';
+ }
+#endif
+
+ return 0;
+}
diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c
index 67c4c74444..218bd2cdbf 100644
--- a/source4/heimdal/lib/krb5/fcache.c
+++ b/source4/heimdal/lib/krb5/fcache.c
@@ -58,7 +58,7 @@ struct fcc_cursor {
#define FCC_CURSOR(C) ((struct fcc_cursor*)(C))
-static const char*
+static const char* KRB5_CALLCONV
fcc_get_name(krb5_context context,
krb5_ccache id)
{
@@ -167,20 +167,20 @@ write_storage(krb5_context context, krb5_storage *sp, int fd)
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_lock(krb5_context context, krb5_ccache id,
int fd, krb5_boolean exclusive)
{
return _krb5_xlock(context, fd, exclusive, fcc_get_name(context, id));
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_unlock(krb5_context context, int fd)
{
return _krb5_xunlock(context, fd);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
{
krb5_fcache *f;
@@ -304,12 +304,13 @@ _krb5_erase_file(krb5_context context, const char *filename)
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_gen_new(krb5_context context, krb5_ccache *id)
{
+ char *file = NULL, *exp_file = NULL;
+ krb5_error_code ret;
krb5_fcache *f;
int fd;
- char *file;
f = malloc(sizeof(*f));
if(f == NULL) {
@@ -317,39 +318,30 @@ fcc_gen_new(krb5_context context, krb5_ccache *id)
N_("malloc: out of memory", ""));
return KRB5_CC_NOMEM;
}
- asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT);
- if(file == NULL) {
+ ret = asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT);
+ if(ret < 0 || file == NULL) {
free(f);
krb5_set_error_message(context, KRB5_CC_NOMEM,
N_("malloc: out of memory", ""));
return KRB5_CC_NOMEM;
}
-#ifdef KRB5_USE_PATH_TOKENS
- {
- char * exp_file = NULL;
- krb5_error_code ec;
+ ret = _krb5_expand_path_tokens(context, file, &exp_file);
+ free(file);
+ if (ret)
+ return ret;
- ec = _krb5_expand_path_tokens(context, file, &exp_file);
+ file = exp_file;
- if (ec == 0) {
- free(file);
- file = exp_file;
- } else {
- free(file);
- return ec;
- }
- }
-#endif
- fd = mkstemp(file);
+ fd = mkstemp(exp_file);
if(fd < 0) {
int ret = errno;
- krb5_set_error_message(context, ret, N_("mkstemp %s failed", ""), file);
+ krb5_set_error_message(context, ret, N_("mkstemp %s failed", ""), exp_file);
free(f);
- free(file);
+ free(exp_file);
return ret;
}
close(fd);
- f->filename = file;
+ f->filename = exp_file;
f->version = 0;
(*id)->data.data = f;
(*id)->data.length = sizeof(*f);
@@ -381,7 +373,7 @@ storage_set_flags(krb5_context context, krb5_storage *sp, int vno)
krb5_storage_set_flags(sp, flags);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_open(krb5_context context,
krb5_ccache id,
int *fd_ret,
@@ -412,7 +404,7 @@ fcc_open(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_initialize(krb5_context context,
krb5_ccache id,
krb5_principal primary_principal)
@@ -468,7 +460,7 @@ fcc_initialize(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_close(krb5_context context,
krb5_ccache id)
{
@@ -477,7 +469,7 @@ fcc_close(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_destroy(krb5_context context,
krb5_ccache id)
{
@@ -485,7 +477,7 @@ fcc_destroy(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_store_cred(krb5_context context,
krb5_ccache id,
krb5_creds *creds)
@@ -675,7 +667,7 @@ init_fcc (krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_get_principal(krb5_context context,
krb5_ccache id,
krb5_principal *principal)
@@ -696,12 +688,12 @@ fcc_get_principal(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_end_get (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor);
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_get_first (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
@@ -734,7 +726,7 @@ fcc_get_first (krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_get_next (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor,
@@ -752,7 +744,7 @@ fcc_get_next (krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_end_get (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
@@ -764,7 +756,7 @@ fcc_end_get (krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_remove_cred(krb5_context context,
krb5_ccache id,
krb5_flags which,
@@ -772,7 +764,7 @@ fcc_remove_cred(krb5_context context,
{
krb5_error_code ret;
krb5_ccache copy, newfile;
- char *newname;
+ char *newname = NULL;
int fd;
ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &copy);
@@ -791,10 +783,10 @@ fcc_remove_cred(krb5_context context,
return ret;
}
- asprintf(&newname, "FILE:%s.XXXXXX", FILENAME(id));
- if (newname == NULL) {
+ ret = asprintf(&newname, "FILE:%s.XXXXXX", FILENAME(id));
+ if (ret < 0 || newname == NULL) {
krb5_cc_destroy(context, copy);
- return ret;
+ return ENOMEM;
}
fd = mkstemp(&newname[5]);
@@ -821,7 +813,7 @@ fcc_remove_cred(krb5_context context,
return ret;
}
- ret = rename(&newname[5], FILENAME(id));
+ ret = rk_rename(&newname[5], FILENAME(id));
if (ret)
ret = errno;
free(newname);
@@ -830,7 +822,7 @@ fcc_remove_cred(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_set_flags(krb5_context context,
krb5_ccache id,
krb5_flags flags)
@@ -838,7 +830,7 @@ fcc_set_flags(krb5_context context,
return 0; /* XXX */
}
-static int
+static int KRB5_CALLCONV
fcc_get_version(krb5_context context,
krb5_ccache id)
{
@@ -849,7 +841,7 @@ struct fcache_iter {
int first;
};
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
{
struct fcache_iter *iter;
@@ -864,7 +856,7 @@ fcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
{
struct fcache_iter *iter = cursor;
@@ -904,7 +896,7 @@ fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
{
struct fcache_iter *iter = cursor;
@@ -912,20 +904,12 @@ fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
{
krb5_error_code ret = 0;
- ret = rename(FILENAME(from), FILENAME(to));
-#ifdef RENAME_DOES_NOT_UNLINK
- if (ret && (errno == EEXIST || errno == EACCES)) {
- ret = unlink(FILENAME(to));
- if (ret == 0) {
- ret = rename(FILENAME(from), FILENAME(to));
- }
- }
-#endif
+ ret = rk_rename(FILENAME(from), FILENAME(to));
if (ret && errno != EXDEV) {
char buf[128];
@@ -990,11 +974,12 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
{
krb5_storage *sp;
int fd;
- ret = init_fcc (context, to, &sp, &fd, NULL);
- if (sp)
- krb5_storage_free(sp);
- fcc_unlock(context, fd);
- close(fd);
+ if ((ret = init_fcc (context, to, &sp, &fd, NULL)) == 0) {
+ if (sp)
+ krb5_storage_free(sp);
+ fcc_unlock(context, fd);
+ close(fd);
+ }
}
fcc_close(context, from);
@@ -1002,7 +987,7 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_get_default_name(krb5_context context, char **str)
{
return _krb5_expand_default_cc_name(context,
@@ -1010,7 +995,7 @@ fcc_get_default_name(krb5_context context, char **str)
str);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime)
{
krb5_error_code ret;
@@ -1031,17 +1016,17 @@ fcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat kdc_offset)
{
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fcc_get_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat *kdc_offset)
{
krb5_error_code ret;
- krb5_storage *sp;
+ krb5_storage *sp = NULL;
int fd;
ret = init_fcc(context, id, &sp, &fd, kdc_offset);
if (sp)
diff --git a/source4/heimdal/lib/krb5/generate_seq_number.c b/source4/heimdal/lib/krb5/generate_seq_number.c
index 575f842d8b..6001d69261 100644
--- a/source4/heimdal/lib/krb5/generate_seq_number.c
+++ b/source4/heimdal/lib/krb5/generate_seq_number.c
@@ -38,7 +38,7 @@ krb5_generate_seq_number(krb5_context context,
const krb5_keyblock *key,
uint32_t *seqno)
{
- if (RAND_bytes((void *)seqno, sizeof(*seqno)) != 1)
+ if (RAND_bytes((void *)seqno, sizeof(*seqno)) <= 0)
krb5_abortx(context, "Failed to generate random block");
/* MIT used signed numbers, lets not stomp into that space directly */
*seqno &= 0x3fffffff;
diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c
index 75e44f0cd4..8f9d462190 100644
--- a/source4/heimdal/lib/krb5/get_cred.c
+++ b/source4/heimdal/lib/krb5/get_cred.c
@@ -314,7 +314,7 @@ _krb5_get_krbtgt(krb5_context context,
}
/* DCE compatible decrypt proc */
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
decrypt_tkt_with_subkey (krb5_context context,
krb5_keyblock *key,
krb5_key_usage usage,
@@ -939,9 +939,9 @@ get_cred_kdc_referral(krb5_context context,
ret = EINVAL;
if (ret) {
- ret = get_cred_kdc_address (context, ccache, flags, NULL,
- &referral, &tgt, impersonate_principal,
- second_ticket, &ticket);
+ ret = get_cred_kdc_address(context, ccache, flags, NULL,
+ &referral, &tgt, impersonate_principal,
+ second_ticket, &ticket);
if (ret)
goto out;
}
@@ -956,8 +956,8 @@ get_cred_kdc_referral(krb5_context context,
krb5_set_error_message(context, KRB5KRB_AP_ERR_NOT_US,
N_("Got back an non krbtgt "
"ticket referrals", ""));
- krb5_free_cred_contents(context, &ticket);
- return KRB5KRB_AP_ERR_NOT_US;
+ ret = KRB5KRB_AP_ERR_NOT_US;
+ goto out;
}
referral_realm = ticket.server->name.name_string.val[1];
@@ -979,8 +979,8 @@ get_cred_kdc_referral(krb5_context context,
"loops back to realm %s", ""),
tgt.server->realm,
referral_realm);
- krb5_free_cred_contents(context, &ticket);
- return KRB5_GET_IN_TKT_LOOP;
+ ret = KRB5_GET_IN_TKT_LOOP;
+ goto out;
}
tickets++;
}
@@ -996,10 +996,8 @@ get_cred_kdc_referral(krb5_context context,
}
ret = add_cred(context, &ticket, ret_tgts);
- if (ret) {
- krb5_free_cred_contents(context, &ticket);
+ if (ret)
goto out;
- }
/* try realm in the referral */
ret = krb5_principal_set_realm(context,
@@ -1017,6 +1015,7 @@ get_cred_kdc_referral(krb5_context context,
out:
krb5_free_principal(context, referral.server);
krb5_free_cred_contents(context, &tgt);
+ krb5_free_cred_contents(context, &ticket);
return ret;
}
diff --git a/source4/heimdal/lib/krb5/get_default_principal.c b/source4/heimdal/lib/krb5/get_default_principal.c
index 539dedfa47..ba4301ce29 100644
--- a/source4/heimdal/lib/krb5/get_default_principal.c
+++ b/source4/heimdal/lib/krb5/get_default_principal.c
@@ -104,8 +104,6 @@ krb5_error_code
_krb5_get_default_principal_local(krb5_context context,
krb5_principal *princ)
{
- krb5_error_code ret = 0;
-
/* See if we can get the principal first. We only expect this to
work if logged into a domain. */
{
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index f443788075..869687aa63 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -94,7 +94,7 @@ free_paid(krb5_context context, struct pa_info_data *ppaid)
krb5_free_data(context, ppaid->s2kparams);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
default_s2k_func(krb5_context context, krb5_enctype type,
krb5_const_pointer keyseed,
krb5_salt salt, krb5_data *s2kparms,
@@ -234,11 +234,12 @@ report_expiration (krb5_context context,
const char *str,
time_t now)
{
- char *p;
+ char *p = NULL;
- asprintf (&p, "%s%s", str, ctime(&now));
- (*prompter) (context, data, NULL, p, 0, NULL);
- free (p);
+ if (asprintf(&p, "%s%s", str, ctime(&now)) < 0 || p == NULL)
+ return;
+ (*prompter)(context, data, NULL, p, 0, NULL);
+ free(p);
}
/*
@@ -562,10 +563,14 @@ change_password (krb5_context context,
&result_string);
if (ret)
goto out;
- asprintf (&p, "%s: %.*s\n",
- result_code ? "Error" : "Success",
- (int)result_string.length,
- result_string.length > 0 ? (char*)result_string.data : "");
+ if (asprintf(&p, "%s: %.*s\n",
+ result_code ? "Error" : "Success",
+ (int)result_string.length,
+ result_string.length > 0 ? (char*)result_string.data : "") < 0)
+ {
+ ret = ENOMEM;
+ goto out;
+ }
/* return the result */
(*prompter) (context, data, NULL, p, 0, NULL);
@@ -1454,7 +1459,7 @@ krb5_init_creds_set_password(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
keytab_key_proc(krb5_context context, krb5_enctype enctype,
krb5_const_pointer keyseed,
krb5_salt salt, krb5_data *s2kparms,
@@ -1581,7 +1586,7 @@ krb5_init_creds_set_keytab(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
keyblock_key_proc(krb5_context context, krb5_enctype enctype,
krb5_const_pointer keyseed,
krb5_salt salt, krb5_data *s2kparms,
@@ -1613,7 +1618,8 @@ krb5_init_creds_set_keyblock(krb5_context context,
* @param in input data from KDC, first round it should be reset by krb5_data_zer().
* @param out reply to KDC.
* @param hostinfo KDC address info, first round it can be NULL.
- * @param flags status of the round, if 1 is set, continue one more round.
+ * @param flags status of the round, if
+ * KRB5_INIT_CREDS_STEP_FLAG_CONTINUE is set, continue one more round.
*
* @return 0 for success, or an Kerberos 5 error code, see
* krb5_get_error_message().
@@ -1816,7 +1822,7 @@ krb5_init_creds_step(krb5_context context,
out->data = ctx->req_buffer.data;
out->length = ctx->req_buffer.length;
- *flags = 1;
+ *flags = KRB5_INIT_CREDS_STEP_FLAG_CONTINUE;
return 0;
out:
diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c
index 01ea184773..80a72ecbf7 100644
--- a/source4/heimdal/lib/krb5/kcm.c
+++ b/source4/heimdal/lib/krb5/kcm.c
@@ -1205,94 +1205,6 @@ _krb5_kcm_noop(krb5_context context,
/*
* Request:
* NameZ
- * Mode
- *
- * Response:
- *
- */
-krb5_error_code
-_krb5_kcm_chmod(krb5_context context,
- krb5_ccache id,
- uint16_t mode)
-{
- krb5_error_code ret;
- krb5_kcmcache *k = KCMCACHE(id);
- krb5_storage *request;
-
- ret = krb5_kcm_storage_request(context, KCM_OP_CHMOD, &request);
- if (ret)
- return ret;
-
- ret = krb5_store_stringz(request, k->name);
- if (ret) {
- krb5_storage_free(request);
- return ret;
- }
-
- ret = krb5_store_int16(request, mode);
- if (ret) {
- krb5_storage_free(request);
- return ret;
- }
-
- ret = krb5_kcm_call(context, request, NULL, NULL);
-
- krb5_storage_free(request);
- return ret;
-}
-
-
-/*
- * Request:
- * NameZ
- * UID
- * GID
- *
- * Response:
- *
- */
-krb5_error_code
-_krb5_kcm_chown(krb5_context context,
- krb5_ccache id,
- uint32_t uid,
- uint32_t gid)
-{
- krb5_error_code ret;
- krb5_kcmcache *k = KCMCACHE(id);
- krb5_storage *request;
-
- ret = krb5_kcm_storage_request(context, KCM_OP_CHOWN, &request);
- if (ret)
- return ret;
-
- ret = krb5_store_stringz(request, k->name);
- if (ret) {
- krb5_storage_free(request);
- return ret;
- }
-
- ret = krb5_store_int32(request, uid);
- if (ret) {
- krb5_storage_free(request);
- return ret;
- }
-
- ret = krb5_store_int32(request, gid);
- if (ret) {
- krb5_storage_free(request);
- return ret;
- }
-
- ret = krb5_kcm_call(context, request, NULL, NULL);
-
- krb5_storage_free(request);
- return ret;
-}
-
-
-/*
- * Request:
- * NameZ
* ServerPrincipalPresent
* ServerPrincipal OPTIONAL
* Key
diff --git a/source4/heimdal/lib/krb5/keytab.c b/source4/heimdal/lib/krb5/keytab.c
index 79b079a056..d1ffd57738 100644
--- a/source4/heimdal/lib/krb5/keytab.c
+++ b/source4/heimdal/lib/krb5/keytab.c
@@ -73,11 +73,6 @@
* store the keytab in a AFS keyfile (usually /usr/afs/etc/KeyFile ),
* the type's name is AFSKEYFILE. The residual part is a filename.
*
- * - krb4
- * the keytab is a Kerberos 4 srvtab that is on-the-fly converted to
- * a keytab. The type's name is krb4 The residual part is a
- * filename.
- *
* - memory
* The keytab is stored in a memory segment. This allows sensitive
* and/or temporary data not to be stored on disk. The type's name
@@ -113,7 +108,7 @@ main (int argc, char **argv)
if (ret)
krb5_err(context, 1, ret, "krb5_kt_start_seq_get");
while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){
- krb5_unparse_name_short(context, entry.principal, &principal);
+ krb5_unparse_name(context, entry.principal, &principal);
printf("principal: %s\n", principal);
free(principal);
krb5_kt_free_entry(context, &entry);
diff --git a/source4/heimdal/lib/krb5/keytab_any.c b/source4/heimdal/lib/krb5/keytab_any.c
index 02de8c8028..d056964769 100644
--- a/source4/heimdal/lib/krb5/keytab_any.c
+++ b/source4/heimdal/lib/krb5/keytab_any.c
@@ -53,7 +53,7 @@ free_list (krb5_context context, struct any_data *a)
}
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
any_resolve(krb5_context context, const char *name, krb5_keytab id)
{
struct any_data *a, *a0 = NULL, *prev = NULL;
@@ -95,7 +95,7 @@ any_resolve(krb5_context context, const char *name, krb5_keytab id)
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
any_get_name (krb5_context context,
krb5_keytab id,
char *name,
@@ -106,7 +106,7 @@ any_get_name (krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
any_close (krb5_context context,
krb5_keytab id)
{
@@ -121,7 +121,7 @@ struct any_cursor_extra_data {
krb5_kt_cursor cursor;
};
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
any_start_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *c)
@@ -150,7 +150,7 @@ any_start_seq_get(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
any_next_entry (krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry,
@@ -182,7 +182,7 @@ any_next_entry (krb5_context context,
} while (1);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
any_end_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *cursor)
@@ -198,7 +198,7 @@ any_end_seq_get(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
any_add_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry)
@@ -218,7 +218,7 @@ any_add_entry(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
any_remove_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry)
diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c
index 9a21db0cbb..2b9ea7f11d 100644
--- a/source4/heimdal/lib/krb5/keytab_file.c
+++ b/source4/heimdal/lib/krb5/keytab_file.c
@@ -286,7 +286,7 @@ krb5_kt_store_principal(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_resolve(krb5_context context, const char *name, krb5_keytab id)
{
struct fkt_data *d;
@@ -307,7 +307,7 @@ fkt_resolve(krb5_context context, const char *name, krb5_keytab id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_resolve_java14(krb5_context context, const char *name, krb5_keytab id)
{
krb5_error_code ret;
@@ -320,7 +320,7 @@ fkt_resolve_java14(krb5_context context, const char *name, krb5_keytab id)
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_close(krb5_context context, krb5_keytab id)
{
struct fkt_data *d = id->data;
@@ -329,7 +329,7 @@ fkt_close(krb5_context context, krb5_keytab id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_destroy(krb5_context context, krb5_keytab id)
{
struct fkt_data *d = id->data;
@@ -337,7 +337,7 @@ fkt_destroy(krb5_context context, krb5_keytab id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_get_name(krb5_context context,
krb5_keytab id,
char *name,
@@ -430,7 +430,7 @@ fkt_start_seq_get_int(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_start_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *c)
@@ -503,7 +503,7 @@ loop:
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_next_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry,
@@ -512,7 +512,7 @@ fkt_next_entry(krb5_context context,
return fkt_next_entry_int(context, id, entry, cursor, NULL, NULL);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_end_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *cursor)
@@ -523,7 +523,7 @@ fkt_end_seq_get(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_setup_keytab(krb5_context context,
krb5_keytab id,
krb5_storage *sp)
@@ -537,7 +537,7 @@ fkt_setup_keytab(krb5_context context,
return krb5_store_int8 (sp, id->version);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_add_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry)
@@ -723,7 +723,7 @@ fkt_add_entry(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
fkt_remove_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry)
diff --git a/source4/heimdal/lib/krb5/keytab_keyfile.c b/source4/heimdal/lib/krb5/keytab_keyfile.c
index 54666c7d44..28bbaeee8c 100644
--- a/source4/heimdal/lib/krb5/keytab_keyfile.c
+++ b/source4/heimdal/lib/krb5/keytab_keyfile.c
@@ -128,7 +128,7 @@ get_cell_and_realm (krb5_context context, struct akf_data *d)
* init and get filename
*/
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
akf_resolve(krb5_context context, const char *name, krb5_keytab id)
{
int ret;
@@ -164,7 +164,7 @@ akf_resolve(krb5_context context, const char *name, krb5_keytab id)
* cleanup
*/
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
akf_close(krb5_context context, krb5_keytab id)
{
struct akf_data *d = id->data;
@@ -179,7 +179,7 @@ akf_close(krb5_context context, krb5_keytab id)
* Return filename
*/
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
akf_get_name(krb5_context context,
krb5_keytab id,
char *name,
@@ -195,7 +195,7 @@ akf_get_name(krb5_context context,
* Init
*/
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
akf_start_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *c)
@@ -226,7 +226,7 @@ akf_start_seq_get(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
akf_next_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry,
@@ -281,7 +281,7 @@ akf_next_entry(krb5_context context,
return ret;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
akf_end_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *cursor)
@@ -291,7 +291,7 @@ akf_end_seq_get(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
akf_add_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry)
diff --git a/source4/heimdal/lib/krb5/keytab_memory.c b/source4/heimdal/lib/krb5/keytab_memory.c
index 73ffa1c67d..0ee684d363 100644
--- a/source4/heimdal/lib/krb5/keytab_memory.c
+++ b/source4/heimdal/lib/krb5/keytab_memory.c
@@ -50,7 +50,7 @@ static HEIMDAL_MUTEX mkt_mutex = HEIMDAL_MUTEX_INITIALIZER;
static struct mkt_data *mkt_head;
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mkt_resolve(krb5_context context, const char *name, krb5_keytab id)
{
struct mkt_data *d;
@@ -95,7 +95,7 @@ mkt_resolve(krb5_context context, const char *name, krb5_keytab id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mkt_close(krb5_context context, krb5_keytab id)
{
struct mkt_data *d = id->data, **dp;
@@ -126,7 +126,7 @@ mkt_close(krb5_context context, krb5_keytab id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mkt_get_name(krb5_context context,
krb5_keytab id,
char *name,
@@ -137,7 +137,7 @@ mkt_get_name(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mkt_start_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *c)
@@ -147,7 +147,7 @@ mkt_start_seq_get(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mkt_next_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry,
@@ -159,7 +159,7 @@ mkt_next_entry(krb5_context context,
return krb5_kt_copy_entry_contents(context, &d->entries[c->fd++], entry);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mkt_end_seq_get(krb5_context context,
krb5_keytab id,
krb5_kt_cursor *cursor)
@@ -167,7 +167,7 @@ mkt_end_seq_get(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mkt_add_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry)
@@ -185,7 +185,7 @@ mkt_add_entry(krb5_context context,
&d->entries[d->num_entries++]);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mkt_remove_entry(krb5_context context,
krb5_keytab id,
krb5_keytab_entry *entry)
diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h
index c810b8bc74..8f4210e19b 100644
--- a/source4/heimdal/lib/krb5/krb5.h
+++ b/source4/heimdal/lib/krb5/krb5.h
@@ -63,6 +63,12 @@
#endif
#endif
+#ifdef _WIN32
+#define KRB5_CALLCONV __stdcall
+#else
+#define KRB5_CALLCONV
+#endif
+
/* simple constants */
#ifndef TRUE
@@ -404,6 +410,10 @@ typedef union {
#define KRB5_TC_MATCH_2ND_TKT (1 << 23)
#define KRB5_TC_MATCH_IS_SKEY (1 << 22)
+/* constants for get_flags and set_flags */
+#define KRB5_TC_OPENCLOSE 0x00000001
+#define KRB5_TC_NOTICKET 0x00000002
+
typedef AuthorizationData krb5_authdata;
typedef KRB_ERROR krb5_error;
@@ -427,33 +437,34 @@ typedef struct krb5_cc_cache_cursor_data *krb5_cc_cache_cursor;
typedef struct krb5_cc_ops {
int version;
const char *prefix;
- const char* (*get_name)(krb5_context, krb5_ccache);
- krb5_error_code (*resolve)(krb5_context, krb5_ccache *, const char *);
- krb5_error_code (*gen_new)(krb5_context, krb5_ccache *);
- krb5_error_code (*init)(krb5_context, krb5_ccache, krb5_principal);
- krb5_error_code (*destroy)(krb5_context, krb5_ccache);
- krb5_error_code (*close)(krb5_context, krb5_ccache);
- krb5_error_code (*store)(krb5_context, krb5_ccache, krb5_creds*);
- krb5_error_code (*retrieve)(krb5_context, krb5_ccache,
- krb5_flags, const krb5_creds*, krb5_creds *);
- krb5_error_code (*get_princ)(krb5_context, krb5_ccache, krb5_principal*);
- krb5_error_code (*get_first)(krb5_context, krb5_ccache, krb5_cc_cursor *);
- krb5_error_code (*get_next)(krb5_context, krb5_ccache,
- krb5_cc_cursor*, krb5_creds*);
- krb5_error_code (*end_get)(krb5_context, krb5_ccache, krb5_cc_cursor*);
- krb5_error_code (*remove_cred)(krb5_context, krb5_ccache,
- krb5_flags, krb5_creds*);
- krb5_error_code (*set_flags)(krb5_context, krb5_ccache, krb5_flags);
- int (*get_version)(krb5_context, krb5_ccache);
- krb5_error_code (*get_cache_first)(krb5_context, krb5_cc_cursor *);
- krb5_error_code (*get_cache_next)(krb5_context, krb5_cc_cursor, krb5_ccache *);
- krb5_error_code (*end_cache_get)(krb5_context, krb5_cc_cursor);
- krb5_error_code (*move)(krb5_context, krb5_ccache, krb5_ccache);
- krb5_error_code (*get_default_name)(krb5_context, char **);
- krb5_error_code (*set_default)(krb5_context, krb5_ccache);
- krb5_error_code (*lastchange)(krb5_context, krb5_ccache, krb5_timestamp *);
- krb5_error_code (*set_kdc_offset)(krb5_context, krb5_ccache, krb5_deltat);
- krb5_error_code (*get_kdc_offset)(krb5_context, krb5_ccache, krb5_deltat *);
+ const char* (KRB5_CALLCONV * get_name)(krb5_context, krb5_ccache);
+ krb5_error_code (KRB5_CALLCONV * resolve)(krb5_context, krb5_ccache *, const char *);
+ krb5_error_code (KRB5_CALLCONV * gen_new)(krb5_context, krb5_ccache *);
+ krb5_error_code (KRB5_CALLCONV * init)(krb5_context, krb5_ccache, krb5_principal);
+ krb5_error_code (KRB5_CALLCONV * destroy)(krb5_context, krb5_ccache);
+ krb5_error_code (KRB5_CALLCONV * close)(krb5_context, krb5_ccache);
+ krb5_error_code (KRB5_CALLCONV * store)(krb5_context, krb5_ccache, krb5_creds*);
+ krb5_error_code (KRB5_CALLCONV * retrieve)(krb5_context, krb5_ccache,
+ krb5_flags, const krb5_creds*, krb5_creds *);
+ krb5_error_code (KRB5_CALLCONV * get_princ)(krb5_context, krb5_ccache, krb5_principal*);
+ krb5_error_code (KRB5_CALLCONV * get_first)(krb5_context, krb5_ccache, krb5_cc_cursor *);
+ krb5_error_code (KRB5_CALLCONV * get_next)(krb5_context, krb5_ccache,
+ krb5_cc_cursor*, krb5_creds*);
+ krb5_error_code (KRB5_CALLCONV * end_get)(krb5_context, krb5_ccache, krb5_cc_cursor*);
+ krb5_error_code (KRB5_CALLCONV * remove_cred)(krb5_context, krb5_ccache,
+ krb5_flags, krb5_creds*);
+ krb5_error_code (KRB5_CALLCONV * set_flags)(krb5_context, krb5_ccache, krb5_flags);
+ int (KRB5_CALLCONV * get_version)(krb5_context, krb5_ccache);
+ krb5_error_code (KRB5_CALLCONV * get_cache_first)(krb5_context, krb5_cc_cursor *);
+ krb5_error_code (KRB5_CALLCONV * get_cache_next)(krb5_context, krb5_cc_cursor,
+ krb5_ccache *);
+ krb5_error_code (KRB5_CALLCONV * end_cache_get)(krb5_context, krb5_cc_cursor);
+ krb5_error_code (KRB5_CALLCONV * move)(krb5_context, krb5_ccache, krb5_ccache);
+ krb5_error_code (KRB5_CALLCONV * get_default_name)(krb5_context, char **);
+ krb5_error_code (KRB5_CALLCONV * set_default)(krb5_context, krb5_ccache);
+ krb5_error_code (KRB5_CALLCONV * lastchange)(krb5_context, krb5_ccache, krb5_timestamp *);
+ krb5_error_code (KRB5_CALLCONV * set_kdc_offset)(krb5_context, krb5_ccache, krb5_deltat);
+ krb5_error_code (KRB5_CALLCONV * get_kdc_offset)(krb5_context, krb5_ccache, krb5_deltat *);
} krb5_cc_ops;
struct krb5_log_facility;
@@ -523,18 +534,18 @@ typedef struct krb5_keytab_data *krb5_keytab;
struct krb5_keytab_data {
const char *prefix;
- krb5_error_code (*resolve)(krb5_context, const char*, krb5_keytab);
- krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t);
- krb5_error_code (*close)(krb5_context, krb5_keytab);
- krb5_error_code (*destroy)(krb5_context, krb5_keytab);
- krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal,
- krb5_kvno, krb5_enctype, krb5_keytab_entry*);
- krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
- krb5_error_code (*next_entry)(krb5_context, krb5_keytab,
- krb5_keytab_entry*, krb5_kt_cursor*);
- krb5_error_code (*end_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
- krb5_error_code (*add)(krb5_context, krb5_keytab, krb5_keytab_entry*);
- krb5_error_code (*remove)(krb5_context, krb5_keytab, krb5_keytab_entry*);
+ krb5_error_code (KRB5_CALLCONV * resolve)(krb5_context, const char*, krb5_keytab);
+ krb5_error_code (KRB5_CALLCONV * get_name)(krb5_context, krb5_keytab, char*, size_t);
+ krb5_error_code (KRB5_CALLCONV * close)(krb5_context, krb5_keytab);
+ krb5_error_code (KRB5_CALLCONV * destroy)(krb5_context, krb5_keytab);
+ krb5_error_code (KRB5_CALLCONV * get)(krb5_context, krb5_keytab, krb5_const_principal,
+ krb5_kvno, krb5_enctype, krb5_keytab_entry*);
+ krb5_error_code (KRB5_CALLCONV * start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
+ krb5_error_code (KRB5_CALLCONV * next_entry)(krb5_context, krb5_keytab,
+ krb5_keytab_entry*, krb5_kt_cursor*);
+ krb5_error_code (KRB5_CALLCONV * end_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
+ krb5_error_code (KRB5_CALLCONV * add)(krb5_context, krb5_keytab, krb5_keytab_entry*);
+ krb5_error_code (KRB5_CALLCONV * remove)(krb5_context, krb5_keytab, krb5_keytab_entry*);
void *data;
int32_t version;
};
@@ -606,8 +617,8 @@ typedef struct {
extern const char *heimdal_version, *heimdal_long_version;
-typedef void (*krb5_log_log_func_t)(const char*, const char*, void*);
-typedef void (*krb5_log_close_func_t)(void*);
+typedef void (KRB5_CALLCONV * krb5_log_log_func_t)(const char*, const char*, void*);
+typedef void (KRB5_CALLCONV * krb5_log_close_func_t)(void*);
typedef struct krb5_log_facility {
char *program;
@@ -642,28 +653,28 @@ typedef struct _krb5_prompt {
krb5_prompt_type type;
} krb5_prompt;
-typedef int (*krb5_prompter_fct)(krb5_context /*context*/,
- void * /*data*/,
- const char * /*name*/,
- const char * /*banner*/,
- int /*num_prompts*/,
- krb5_prompt /*prompts*/[]);
-typedef krb5_error_code (*krb5_key_proc)(krb5_context /*context*/,
- krb5_enctype /*type*/,
- krb5_salt /*salt*/,
- krb5_const_pointer /*keyseed*/,
- krb5_keyblock ** /*key*/);
-typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context /*context*/,
- krb5_keyblock * /*key*/,
- krb5_key_usage /*usage*/,
- krb5_const_pointer /*decrypt_arg*/,
- krb5_kdc_rep * /*dec_rep*/);
-typedef krb5_error_code (*krb5_s2k_proc)(krb5_context /*context*/,
- krb5_enctype /*type*/,
- krb5_const_pointer /*keyseed*/,
- krb5_salt /*salt*/,
- krb5_data * /*s2kparms*/,
- krb5_keyblock ** /*key*/);
+typedef int (KRB5_CALLCONV * krb5_prompter_fct)(krb5_context /*context*/,
+ void * /*data*/,
+ const char * /*name*/,
+ const char * /*banner*/,
+ int /*num_prompts*/,
+ krb5_prompt /*prompts*/[]);
+typedef krb5_error_code (KRB5_CALLCONV * krb5_key_proc)(krb5_context /*context*/,
+ krb5_enctype /*type*/,
+ krb5_salt /*salt*/,
+ krb5_const_pointer /*keyseed*/,
+ krb5_keyblock ** /*key*/);
+typedef krb5_error_code (KRB5_CALLCONV * krb5_decrypt_proc)(krb5_context /*context*/,
+ krb5_keyblock * /*key*/,
+ krb5_key_usage /*usage*/,
+ krb5_const_pointer /*decrypt_arg*/,
+ krb5_kdc_rep * /*dec_rep*/);
+typedef krb5_error_code (KRB5_CALLCONV * krb5_s2k_proc)(krb5_context /*context*/,
+ krb5_enctype /*type*/,
+ krb5_const_pointer /*keyseed*/,
+ krb5_salt /*salt*/,
+ krb5_data * /*s2kparms*/,
+ krb5_keyblock ** /*key*/);
struct _krb5_get_init_creds_opt_private;
@@ -698,6 +709,9 @@ typedef struct _krb5_get_init_creds_opt krb5_get_init_creds_opt;
#define KRB5_GET_INIT_CREDS_OPT_ANONYMOUS 0x0100
#define KRB5_GET_INIT_CREDS_OPT_DISABLE_TRANSITED_CHECK 0x0200
+/* krb5_init_creds_step flags argument */
+#define KRB5_INIT_CREDS_STEP_FLAG_CONTINUE 0x0001
+
typedef struct _krb5_verify_init_creds_opt {
krb5_flags flags;
int ap_req_nofail;
@@ -757,12 +771,9 @@ enum {
KRB5_KRBHST_FLAGS_LARGE_MSG = 2
};
-typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context,
- void *,
- krb5_krbhst_info *,
- time_t,
- const krb5_data *,
- krb5_data *);
+typedef krb5_error_code
+(KRB5_CALLCONV * krb5_send_to_kdc_func)(krb5_context, void *, krb5_krbhst_info *, time_t,
+ const krb5_data *, krb5_data *);
/** flags for krb5_parse_name_flags */
enum {
@@ -784,7 +795,9 @@ typedef struct krb5_sendto_ctx_data *krb5_sendto_ctx;
#define KRB5_SENDTO_RESTART 1
#define KRB5_SENDTO_CONTINUE 2
-typedef krb5_error_code (*krb5_sendto_ctx_func)(krb5_context, krb5_sendto_ctx, void *, const krb5_data *, int *);
+typedef krb5_error_code
+(KRB5_CALLCONV * krb5_sendto_ctx_func)(krb5_context, krb5_sendto_ctx, void *,
+ const krb5_data *, int *);
struct krb5_plugin;
enum krb5_plugin_type {
@@ -828,7 +841,7 @@ typedef struct {
} krb5_last_req_entry;
typedef krb5_error_code
-(*krb5_gic_process_last_req)(krb5_context, krb5_last_req_entry **, void *);
+(KRB5_CALLCONV * krb5_gic_process_last_req)(krb5_context, krb5_last_req_entry **, void *);
/*
*
@@ -854,8 +867,6 @@ extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_wrfkt_ops;
extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_javakt_ops;
extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_mkt_ops;
extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_akf_ops;
-extern KRB5_LIB_VARIABLE const krb5_kt_ops krb4_fkt_ops;
-extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_srvtab_fkt_ops;
extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_any_ops;
extern KRB5_LIB_VARIABLE const char *krb5_cc_type_api;
diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h
index 6acaa2c66b..2fdb76d757 100644
--- a/source4/heimdal/lib/krb5/krb5_locl.h
+++ b/source4/heimdal/lib/krb5/krb5_locl.h
@@ -274,6 +274,7 @@ typedef struct krb5_context_data {
#define KRB5_CTX_F_CHECK_PAC 2
#define KRB5_CTX_F_HOMEDIR_ACCESS 4
#define KRB5_CTX_F_SOCKETS_INITIALIZED 8
+#define KRB5_CTX_F_RD_REQ_IGNORE 16
struct send_to_kdc *send_to_kdc;
#ifdef PKINIT
hx509_context hx509ctx;
diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c
index ec0c8b738e..d8646f0537 100644
--- a/source4/heimdal/lib/krb5/krbhst.c
+++ b/source4/heimdal/lib/krb5/krbhst.c
@@ -481,7 +481,7 @@ static krb5_error_code
fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
const char *serv_string, int port, int proto)
{
- char *host;
+ char *host = NULL;
int ret;
struct addrinfo *ai;
struct addrinfo hints;
@@ -500,12 +500,12 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
}
if(kd->fallback_count == 0)
- asprintf(&host, "%s.%s.", serv_string, kd->realm);
+ ret = asprintf(&host, "%s.%s.", serv_string, kd->realm);
else
- asprintf(&host, "%s-%d.%s.",
- serv_string, kd->fallback_count, kd->realm);
+ ret = asprintf(&host, "%s-%d.%s.",
+ serv_string, kd->fallback_count, kd->realm);
- if (host == NULL)
+ if (ret < 0 || host == NULL)
return ENOMEM;
make_hints(&hints, proto);
diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c
index 55c70fc96a..ca0756fdb9 100644
--- a/source4/heimdal/lib/krb5/log.c
+++ b/source4/heimdal/lib/krb5/log.c
@@ -165,7 +165,7 @@ struct _heimdal_syslog_data{
int priority;
};
-static void
+static void KRB5_CALLCONV
log_syslog(const char *timestr,
const char *msg,
void *data)
@@ -175,7 +175,7 @@ log_syslog(const char *timestr,
syslog(s->priority, "%s", msg);
}
-static void
+static void KRB5_CALLCONV
close_syslog(void *data)
{
free(data);
@@ -215,7 +215,7 @@ struct file_data{
int keep_open;
};
-static void
+static void KRB5_CALLCONV
log_file(const char *timestr,
const char *msg,
void *data)
@@ -241,7 +241,7 @@ log_file(const char *timestr,
}
}
-static void
+static void KRB5_CALLCONV
close_file(void *data)
{
struct file_data *f = data;
@@ -428,8 +428,8 @@ krb5_vlog_msg(krb5_context context,
krb5_format_time(context, t, buf, sizeof(buf), TRUE);
}
if(actual == NULL) {
- vasprintf(&msg, fmt, ap);
- if(msg == NULL)
+ int ret = vasprintf(&msg, fmt, ap);
+ if(ret < 0 || msg == NULL)
actual = fmt;
else
actual = msg;
diff --git a/source4/heimdal/lib/krb5/mcache.c b/source4/heimdal/lib/krb5/mcache.c
index cdafc67bae..19e6b2345e 100644
--- a/source4/heimdal/lib/krb5/mcache.c
+++ b/source4/heimdal/lib/krb5/mcache.c
@@ -56,26 +56,27 @@ static struct krb5_mcache *mcc_head;
#define MISDEAD(X) ((X)->dead)
-static const char*
+static const char* KRB5_CALLCONV
mcc_get_name(krb5_context context,
krb5_ccache id)
{
return MCACHE(id)->name;
}
-static krb5_mcache *
+static krb5_mcache * KRB5_CALLCONV
mcc_alloc(const char *name)
{
krb5_mcache *m, *m_c;
+ int ret = 0;
ALLOC(m, 1);
if(m == NULL)
return NULL;
if(name == NULL)
- asprintf(&m->name, "%p", m);
+ ret = asprintf(&m->name, "%p", m);
else
m->name = strdup(name);
- if(m->name == NULL) {
+ if(ret < 0 || m->name == NULL) {
free(m);
return NULL;
}
@@ -103,7 +104,7 @@ mcc_alloc(const char *name)
return m;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
{
krb5_mcache *m;
@@ -135,7 +136,7 @@ mcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_gen_new(krb5_context context, krb5_ccache *id)
{
krb5_mcache *m;
@@ -154,7 +155,7 @@ mcc_gen_new(krb5_context context, krb5_ccache *id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_initialize(krb5_context context,
krb5_ccache id,
krb5_principal primary_principal)
@@ -180,7 +181,7 @@ mcc_close_internal(krb5_mcache *m)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_close(krb5_context context,
krb5_ccache id)
{
@@ -189,7 +190,7 @@ mcc_close(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_destroy(krb5_context context,
krb5_ccache id)
{
@@ -230,7 +231,7 @@ mcc_destroy(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_store_cred(krb5_context context,
krb5_ccache id,
krb5_creds *creds)
@@ -261,7 +262,7 @@ mcc_store_cred(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_get_principal(krb5_context context,
krb5_ccache id,
krb5_principal *principal)
@@ -275,7 +276,7 @@ mcc_get_principal(krb5_context context,
principal);
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_get_first (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
@@ -289,7 +290,7 @@ mcc_get_first (krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_get_next (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor,
@@ -311,7 +312,7 @@ mcc_get_next (krb5_context context,
return KRB5_CC_END;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_end_get (krb5_context context,
krb5_ccache id,
krb5_cc_cursor *cursor)
@@ -319,7 +320,7 @@ mcc_end_get (krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_remove_cred(krb5_context context,
krb5_ccache id,
krb5_flags which,
@@ -339,7 +340,7 @@ mcc_remove_cred(krb5_context context,
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_set_flags(krb5_context context,
krb5_ccache id,
krb5_flags flags)
@@ -351,7 +352,7 @@ struct mcache_iter {
krb5_mcache *cache;
};
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
{
struct mcache_iter *iter;
@@ -373,7 +374,7 @@ mcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
{
struct mcache_iter *iter = cursor;
@@ -400,7 +401,7 @@ mcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
{
struct mcache_iter *iter = cursor;
@@ -412,7 +413,7 @@ mcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
{
krb5_mcache *mfrom = MCACHE(from), *mto = MCACHE(to);
@@ -447,7 +448,7 @@ mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_default_name(krb5_context context, char **str)
{
*str = strdup("MEMORY:");
@@ -459,14 +460,14 @@ mcc_default_name(krb5_context context, char **str)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime)
{
*mtime = MCACHE(id)->mtime;
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat kdc_offset)
{
krb5_mcache *m = MCACHE(id);
@@ -474,7 +475,7 @@ mcc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat kdc_offset)
return 0;
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
mcc_get_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat *kdc_offset)
{
krb5_mcache *m = MCACHE(id);
diff --git a/source4/heimdal/lib/krb5/mit_glue.c b/source4/heimdal/lib/krb5/mit_glue.c
index 0ff3d7f3c6..7ed91b0768 100644
--- a/source4/heimdal/lib/krb5/mit_glue.c
+++ b/source4/heimdal/lib/krb5/mit_glue.c
@@ -378,6 +378,12 @@ krb5_c_prf(krb5_context context,
return ret;
}
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_c_random_make_octets(krb5_context context, krb5_data * data)
+{
+ return krb5_generate_random_keyblock(context, data->length, data->data);
+}
+
/**
* MIT compat glue
*
@@ -392,4 +398,38 @@ krb5_cc_copy_creds(krb5_context context,
return krb5_cc_copy_cache(context, from, to);
}
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_auth_con_getsendsubkey(krb5_context context, krb5_auth_context auth_context,
+ krb5_keyblock **keyblock)
+{
+ return krb5_auth_con_getlocalsubkey(context, auth_context, keyblock);
+}
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_auth_con_getrecvsubkey(krb5_context context, krb5_auth_context auth_context,
+ krb5_keyblock **keyblock)
+{
+ return krb5_auth_con_getremotesubkey(context, auth_context, keyblock);
+}
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_auth_con_setsendsubkey(krb5_context context, krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ return krb5_auth_con_setlocalsubkey(context, auth_context, keyblock);
+}
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_auth_con_setrecvsubkey(krb5_context context, krb5_auth_context auth_context,
+ krb5_keyblock *keyblock)
+{
+ return krb5_auth_con_setremotesubkey(context, auth_context, keyblock);
+}
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_free_default_realm(krb5_context context, krb5_realm realm)
+{
+ return krb5_xfree(realm);
+}
+
#endif /* HEIMDAL_SMALLER */
diff --git a/source4/heimdal/lib/krb5/pcache.c b/source4/heimdal/lib/krb5/pcache.c
new file mode 100644
index 0000000000..e7f7a61ec4
--- /dev/null
+++ b/source4/heimdal/lib/krb5/pcache.c
@@ -0,0 +1,66 @@
+/***********************************************************************
+ * Copyright (c) 2010, Secure Endpoints Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 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 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ **********************************************************************/
+
+#include "krb5_locl.h"
+#include "ccache_plugin.h"
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+#include <assert.h>
+
+krb5_error_code
+_krb5_load_ccache_plugins(krb5_context context)
+{
+ struct krb5_plugin * plist = NULL;
+ struct krb5_plugin *p;
+ krb5_error_code code;
+
+ code = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, KRB5_PLUGIN_CCACHE,
+ &plist);
+ if (code)
+ return code;
+
+ for (p = plist; p != NULL; p = _krb5_plugin_get_next(p)) {
+ krb5_cc_ops * ccops;
+ krb5_error_code c_load;
+
+ ccops = _krb5_plugin_get_symbol(p);
+ if (ccops != NULL && ccops->version == KRB5_CC_OPS_VERSION) {
+ c_load = krb5_cc_register(context, ccops, FALSE);
+ if (c_load != 0)
+ code = c_load;
+ }
+ }
+
+ _krb5_plugin_free(plist);
+
+ return code;
+}
diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c
index 6711c7702f..92c1200f06 100644
--- a/source4/heimdal/lib/krb5/pkinit.c
+++ b/source4/heimdal/lib/krb5/pkinit.c
@@ -1416,10 +1416,7 @@ pk_rd_pa_reply_dh(krb5_context context,
}
- dh_gen_keylen = DH_size(ctx->u.dh);
- size = BN_num_bytes(ctx->u.dh->p);
- if (size < dh_gen_keylen)
- size = dh_gen_keylen;
+ size = DH_size(ctx->u.dh);
dh_gen_key = malloc(size);
if (dh_gen_key == NULL) {
@@ -1427,10 +1424,8 @@ pk_rd_pa_reply_dh(krb5_context context,
krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
goto out;
}
- memset(dh_gen_key, 0, size - dh_gen_keylen);
- dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
- kdc_dh_pubkey, ctx->u.dh);
+ dh_gen_keylen = DH_compute_key(dh_gen_key, kdc_dh_pubkey, ctx->u.dh);
if (dh_gen_keylen == -1) {
ret = KRB5KRB_ERR_GENERIC;
dh_gen_keylen = 0;
@@ -1438,6 +1433,12 @@ pk_rd_pa_reply_dh(krb5_context context,
N_("PKINIT: Can't compute Diffie-Hellman key", ""));
goto out;
}
+ if (dh_gen_keylen < size) {
+ size -= dh_gen_keylen;
+ memmove(dh_gen_key + size, dh_gen_key, dh_gen_keylen);
+ memset(dh_gen_key, 0, size);
+ }
+
} else {
#ifdef HAVE_OPENSSL
const EC_GROUP *group;
diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c
index aa71e29b39..e19ba4a27c 100644
--- a/source4/heimdal/lib/krb5/plugin.c
+++ b/source4/heimdal/lib/krb5/plugin.c
@@ -201,8 +201,19 @@ load_plugins(krb5_context context)
dirs = rk_UNCONST(sysplugin_dirs);
for (di = dirs; *di != NULL; di++) {
+#ifdef KRB5_USE_PATH_TOKENS
+ {
+ char * dir = NULL;
+ if (_krb5_expand_path_tokens(context, *di, &dir))
+ continue;
+ d = opendir(dir);
+
+ free(dir);
+ }
+#else
d = opendir(*di);
+#endif
if (d == NULL)
continue;
rk_cloexec_dir(d);
@@ -215,17 +226,18 @@ load_plugins(krb5_context context)
continue;
path = NULL;
+ ret = 0;
#ifdef __APPLE__
{ /* support loading bundles on MacOS */
size_t len = strlen(n);
if (len > 7 && strcmp(&n[len - 7], ".bundle") == 0)
- asprintf(&path, "%s/%s/Contents/MacOS/%.*s", *di, n, (int)(len - 7), n);
+ ret = asprintf(&path, "%s/%s/Contents/MacOS/%.*s", *di, n, (int)(len - 7), n);
}
#endif
- if (path == NULL)
- asprintf(&path, "%s/%s", *di, n);
+ if (ret < 0 || path == NULL)
+ ret = asprintf(&path, "%s/%s", *di, n);
- if (path == NULL) {
+ if (ret < 0 || path == NULL) {
ret = ENOMEM;
krb5_set_error_message(context, ret, "malloc: out of memory");
return ret;
diff --git a/source4/heimdal/lib/krb5/prompter_posix.c b/source4/heimdal/lib/krb5/prompter_posix.c
index 875fd99c40..1bf748c512 100644
--- a/source4/heimdal/lib/krb5/prompter_posix.c
+++ b/source4/heimdal/lib/krb5/prompter_posix.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-KRB5_LIB_FUNCTION int
+KRB5_LIB_FUNCTION int KRB5_CALLCONV
krb5_prompter_posix (krb5_context context,
void *data,
const char *name,
diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c
index 6b2ffbdaac..8ce6570de2 100644
--- a/source4/heimdal/lib/krb5/rd_req.c
+++ b/source4/heimdal/lib/krb5/rd_req.c
@@ -926,7 +926,7 @@ krb5_rd_req_ctx(krb5_context context,
&o->keyblock);
if (ret) {
/* If caller specified a server, fail. */
- if (service == NULL)
+ if (service == NULL && (context->flags & KRB5_CTX_F_RD_REQ_IGNORE) == 0)
goto out;
/* Otherwise, fall back to iterating over the keytab. This
* have serious performace issues for larger keytab.
diff --git a/source4/heimdal/lib/krb5/replay.c b/source4/heimdal/lib/krb5/replay.c
index f4eb9032d7..375a4aaba6 100644
--- a/source4/heimdal/lib/krb5/replay.c
+++ b/source4/heimdal/lib/krb5/replay.c
@@ -308,12 +308,12 @@ krb5_get_server_rcache(krb5_context context,
}
strvisx(tmp, piece->data, piece->length, VIS_WHITE | VIS_OCTAL);
#ifdef HAVE_GETEUID
- asprintf(&name, "FILE:rc_%s_%u", tmp, (unsigned)geteuid());
+ ret = asprintf(&name, "FILE:rc_%s_%u", tmp, (unsigned)geteuid());
#else
- asprintf(&name, "FILE:rc_%s", tmp);
+ ret = asprintf(&name, "FILE:rc_%s", tmp);
#endif
free(tmp);
- if(name == NULL) {
+ if(ret < 0 || name == NULL) {
krb5_set_error_message(context, ENOMEM,
N_("malloc: out of memory", ""));
return ENOMEM;
diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c
index 9ff52fa545..2ae8153c8d 100644
--- a/source4/heimdal/lib/krb5/send_to_kdc.c
+++ b/source4/heimdal/lib/krb5/send_to_kdc.c
@@ -183,16 +183,16 @@ send_and_recv_http(krb5_socket_t fd,
const krb5_data *req,
krb5_data *rep)
{
- char *request;
+ char *request = NULL;
char *str;
int ret;
int len = base64_encode(req->data, req->length, &str);
if(len < 0)
return -1;
- asprintf(&request, "GET %s%s HTTP/1.0\r\n\r\n", prefix, str);
+ ret = asprintf(&request, "GET %s%s HTTP/1.0\r\n\r\n", prefix, str);
free(str);
- if (request == NULL)
+ if (ret < 0 || request == NULL)
return -1;
ret = net_write (fd, request, strlen(request));
free (request);
@@ -261,7 +261,7 @@ send_via_proxy (krb5_context context,
{
char *proxy2 = strdup(context->http_proxy);
char *proxy = proxy2;
- char *prefix;
+ char *prefix = NULL;
char *colon;
struct addrinfo hints;
struct addrinfo *ai, *a;
@@ -304,8 +304,8 @@ send_via_proxy (krb5_context context,
}
freeaddrinfo (ai);
- asprintf(&prefix, "http://%s/", hi->hostname);
- if(prefix == NULL) {
+ ret = asprintf(&prefix, "http://%s/", hi->hostname);
+ if(ret < 0 || prefix == NULL) {
close(s);
return 1;
}
@@ -648,7 +648,7 @@ krb5_sendto_context(krb5_context context,
return ret;
}
-krb5_error_code
+krb5_error_code KRB5_CALLCONV
_krb5_kdc_retry(krb5_context context, krb5_sendto_ctx ctx, void *data,
const krb5_data *reply, int *action)
{
diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c
index e7d4d9532d..45c97284bf 100644
--- a/source4/heimdal/lib/krb5/ticket.c
+++ b/source4/heimdal/lib/krb5/ticket.c
@@ -602,7 +602,7 @@ noreferral:
}
-static krb5_error_code
+static krb5_error_code KRB5_CALLCONV
decrypt_tkt (krb5_context context,
krb5_keyblock *key,
krb5_key_usage usage,
diff --git a/source4/heimdal/lib/krb5/v4_glue.c b/source4/heimdal/lib/krb5/v4_glue.c
index 01cf323d37..d47a1288ed 100644
--- a/source4/heimdal/lib/krb5/v4_glue.c
+++ b/source4/heimdal/lib/krb5/v4_glue.c
@@ -120,7 +120,7 @@ get_krb4_cc_name(const char *tkfile, char **cc)
}
#ifdef HAVE_GETUID
if(*cc == NULL)
- if (asprintf(cc, "%s%u", TKT_ROOT, (unsigned)getuid()) < 0)
+ if (asprintf(cc, "%s%u", TKT_ROOT, (unsigned)getuid()) < 0 || *cc == NULL)
return errno;
#elif defined(KRB5_USE_PATH_TOKENS)
if(*cc == NULL)
diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c
index a4c633936f..63994dfca7 100644
--- a/source4/heimdal/lib/krb5/warn.c
+++ b/source4/heimdal/lib/krb5/warn.c
@@ -46,6 +46,7 @@ _warnerr(krb5_context context, int do_errtext,
const char *args[2], **arg;
char *msg = NULL;
const char *err_str = NULL;
+ krb5_error_code ret;
args[0] = args[1] = NULL;
arg = args;
@@ -53,8 +54,8 @@ _warnerr(krb5_context context, int do_errtext,
strlcat(xfmt, "%s", sizeof(xfmt));
if(do_errtext)
strlcat(xfmt, ": ", sizeof(xfmt));
- vasprintf(&msg, fmt, ap);
- if(msg == NULL)
+ ret = vasprintf(&msg, fmt, ap);
+ if(ret < 0 || msg == NULL)
return ENOMEM;
*arg++ = msg;
}
diff --git a/source4/heimdal/lib/ntlm/ntlm.c b/source4/heimdal/lib/ntlm/ntlm.c
index 71f96bfce2..8390d79acc 100644
--- a/source4/heimdal/lib/ntlm/ntlm.c
+++ b/source4/heimdal/lib/ntlm/ntlm.c
@@ -222,8 +222,6 @@ ret_string(krb5_storage *sp, int ucs2, struct sec_buffer *desc, char **s)
ret = 0;
out:
return ret;
-
- return 0;
}
static krb5_error_code
@@ -485,6 +483,10 @@ heim_ntlm_encode_type1(const struct ntlm_type1 *type1, struct ntlm_buf *data)
domain.offset = base;
domain.length = len_string(0, type1->domain);
domain.allocated = domain.length;
+ } else {
+ domain.offset = 0;
+ domain.length = 0;
+ domain.allocated = 0;
}
if (type1->hostname) {
hostname.offset = domain.allocated + domain.offset;
diff --git a/source4/heimdal/lib/roken/base64.c b/source4/heimdal/lib/roken/base64.c
index 4c06bd2d1f..394e9841c7 100644
--- a/source4/heimdal/lib/roken/base64.c
+++ b/source4/heimdal/lib/roken/base64.c
@@ -93,7 +93,7 @@ base64_encode(const void *data, int size, char **str)
}
*p = 0;
*str = s;
- return strlen(s);
+ return (int) strlen(s);
}
#define DECODE_ERROR 0xffffffff
diff --git a/source4/heimdal/lib/roken/getarg.c b/source4/heimdal/lib/roken/getarg.c
index d182f0019e..e7dc74b7bc 100644
--- a/source4/heimdal/lib/roken/getarg.c
+++ b/source4/heimdal/lib/roken/getarg.c
@@ -223,7 +223,7 @@ arg_printusage_i18n (struct getargs *args,
const char *usage,
const char *progname,
const char *extra_string,
- char *(i18n)(const char *))
+ char *(*i18n)(const char *))
{
size_t i, max_len = 0;
char buf[128];
@@ -475,9 +475,6 @@ arg_match_long(struct getargs *args, size_t num_args,
abort ();
UNREACHABLE(return 0);
}
-
- /* not reached */
- return ARG_ERR_NO_MATCH;
}
static int
diff --git a/source4/heimdal/lib/roken/getarg.h b/source4/heimdal/lib/roken/getarg.h
index 79573a0ea4..1065c7c661 100644
--- a/source4/heimdal/lib/roken/getarg.h
+++ b/source4/heimdal/lib/roken/getarg.h
@@ -104,7 +104,7 @@ arg_printusage_i18n (struct getargs *args,
const char *usage,
const char *progname,
const char *extra_string,
- char *(i18n)(const char *));
+ char *(*i18n)(const char *));
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
free_getarg_strings (getarg_strings *);
diff --git a/source4/heimdal/lib/roken/inet_ntop.c b/source4/heimdal/lib/roken/inet_ntop.c
index 0c72b27fc6..b3c327cc3e 100644
--- a/source4/heimdal/lib/roken/inet_ntop.c
+++ b/source4/heimdal/lib/roken/inet_ntop.c
@@ -83,6 +83,7 @@ inet_ntop_v6 (const void *src, char *dst, size_t size)
const struct in6_addr *addr = (struct in6_addr *)src;
const u_char *ptr = addr->s6_addr;
const char *orig_dst = dst;
+ int compressed = 0;
if (size < INET6_ADDRSTRLEN) {
errno = ENOSPC;
@@ -91,6 +92,26 @@ inet_ntop_v6 (const void *src, char *dst, size_t size)
for (i = 0; i < 8; ++i) {
int non_zerop = 0;
+ if (compressed == 0 &&
+ ptr[0] == 0 && ptr[1] == 0 &&
+ i <= 5 &&
+ ptr[2] == 0 && ptr[3] == 0 &&
+ ptr[4] == 0 && ptr[5] == 0) {
+
+ compressed = 1;
+
+ if (i == 0)
+ *dst++ = ':';
+ *dst++ = ':';
+
+ for (ptr += 6, i += 3;
+ i < 8 && ptr[0] == 0 && ptr[1] == 0;
+ ++i, ptr += 2);
+
+ if (i >= 8)
+ break;
+ }
+
if (non_zerop || (ptr[0] >> 4)) {
*dst++ = xdigits[ptr[0] >> 4];
non_zerop = 1;
diff --git a/source4/heimdal/lib/roken/inet_pton.c b/source4/heimdal/lib/roken/inet_pton.c
index 3db1f49f22..e44fb1925a 100644
--- a/source4/heimdal/lib/roken/inet_pton.c
+++ b/source4/heimdal/lib/roken/inet_pton.c
@@ -38,8 +38,15 @@
#ifdef HAVE_WINSOCK
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-inet_pton(int af, const char *src, void *dst)
+inet_pton(int af, const char *csrc, void *dst)
{
+ char * src;
+
+ if (csrc == NULL || (src = strdup(csrc)) == NULL) {
+ _set_errno( ENOMEM );
+ return 0;
+ }
+
switch (af) {
case AF_INET:
{
@@ -49,6 +56,8 @@ inet_pton(int af, const char *src, void *dst)
si4.sin_family = AF_INET;
r = WSAStringToAddress(src, AF_INET, NULL, (LPSOCKADDR) &si4, &s);
+ free(src);
+ src = NULL;
if (r == 0) {
memcpy(dst, &si4.sin_addr, sizeof(si4.sin_addr));
@@ -65,6 +74,8 @@ inet_pton(int af, const char *src, void *dst)
si6.sin6_family = AF_INET6;
r = WSAStringToAddress(src, AF_INET6, NULL, (LPSOCKADDR) &si6, &s);
+ free(src);
+ src = NULL;
if (r == 0) {
memcpy(dst, &si6.sin6_addr, sizeof(si6.sin6_addr));
diff --git a/source4/heimdal/lib/roken/net_read.c b/source4/heimdal/lib/roken/net_read.c
index b57dda3dda..df1ac53def 100644
--- a/source4/heimdal/lib/roken/net_read.c
+++ b/source4/heimdal/lib/roken/net_read.c
@@ -73,8 +73,28 @@ net_read(rk_socket_t sock, void *buf, size_t nbytes)
ssize_t count;
size_t rem = nbytes;
+#ifdef SOCKET_IS_NOT_AN_FD
+ int use_read = 0;
+#endif
+
while (rem > 0) {
+#ifdef SOCKET_IS_NOT_AN_FD
+ if (use_read)
+ count = _read (sock, cbuf, rem);
+ else
+ count = recv (sock, cbuf, rem, 0);
+
+ if (use_read == 0 &&
+ rk_IS_SOCKET_ERROR(count) &&
+ (rk_SOCK_ERRNO == WSANOTINITIALISED ||
+ rk_SOCK_ERRNO == WSAENOTSOCK)) {
+ use_read = 1;
+
+ count = _read (sock, cbuf, rem);
+ }
+#else
count = recv (sock, cbuf, rem, 0);
+#endif
if (count < 0) {
/* With WinSock, the error EINTR (WSAEINTR), is used to
diff --git a/source4/heimdal/lib/roken/net_write.c b/source4/heimdal/lib/roken/net_write.c
index 94c9df1c38..e1cfa99074 100644
--- a/source4/heimdal/lib/roken/net_write.c
+++ b/source4/heimdal/lib/roken/net_write.c
@@ -70,9 +70,28 @@ net_write(rk_socket_t sock, const void *buf, size_t nbytes)
const char *cbuf = (const char *)buf;
ssize_t count;
size_t rem = nbytes;
+#ifdef SOCKET_IS_NOT_AN_FD
+ int use_write = 0;
+#endif
while (rem > 0) {
+#ifdef SOCKET_IS_NOT_AN_FD
+ if (use_write)
+ count = _write (sock, cbuf, rem);
+ else
+ count = send (sock, cbuf, rem, 0);
+
+ if (use_write == 0 &&
+ rk_IS_SOCKET_ERROR(count) &&
+ (rk_SOCK_ERRNO == WSANOTINITIALISED ||
+ rk_SOCK_ERRNO == WSAENOTSOCK)) {
+ use_write = 1;
+
+ count = _write (sock, cbuf, rem);
+ }
+#else
count = send (sock, cbuf, rem, 0);
+#endif
if (count < 0) {
if (errno == EINTR)
continue;
diff --git a/source4/heimdal/lib/roken/resolve.c b/source4/heimdal/lib/roken/resolve.c
index e112274a68..97edda471b 100644
--- a/source4/heimdal/lib/roken/resolve.c
+++ b/source4/heimdal/lib/roken/resolve.c
@@ -98,7 +98,7 @@ rk_dns_type_to_string(int type)
return NULL;
}
-#if (defined(HAVE_RES_SEARCH) || defined(HAVE_RES_NSEARCH)) && defined(HAVE_DN_EXPAND)
+#if ((defined(HAVE_RES_SEARCH) || defined(HAVE_RES_NSEARCH)) && defined(HAVE_DN_EXPAND)) || defined(HAVE_WINDNS)
static void
dns_free_rr(struct rk_resource_record *rr)
@@ -124,6 +124,8 @@ rk_dns_free_data(struct rk_dns_reply *r)
free (r);
}
+#ifndef HAVE_WINDNS
+
static int
parse_record(const unsigned char *data, const unsigned char *end_data,
const unsigned char **pp, struct rk_resource_record **ret_rr)
@@ -605,6 +607,8 @@ rk_dns_lookup(const char *domain, const char *type_name)
return dns_lookup_int(domain, rk_ns_c_in, type);
}
+#endif /* !HAVE_WINDNS */
+
static int
compare_srv(const void *a, const void *b)
{
@@ -708,6 +712,218 @@ rk_dns_srv_order(struct rk_dns_reply *r)
return;
}
+#ifdef HAVE_WINDNS
+
+#include <WinDNS.h>
+
+static struct rk_resource_record *
+parse_dns_record(PDNS_RECORD pRec)
+{
+ struct rk_resource_record * rr;
+
+ if (pRec == NULL)
+ return NULL;
+
+ rr = calloc(1, sizeof(*rr));
+
+ rr->domain = strdup(pRec->pName);
+ rr->type = pRec->wType;
+ rr->class = 0;
+ rr->ttl = pRec->dwTtl;
+ rr->size = 0;
+
+ switch (rr->type) {
+ case rk_ns_t_ns:
+ case rk_ns_t_cname:
+ case rk_ns_t_ptr:
+ rr->u.txt = strdup(pRec->Data.NS.pNameHost);
+ if(rr->u.txt == NULL) {
+ dns_free_rr(rr);
+ return NULL;
+ }
+ break;
+
+ case rk_ns_t_mx:
+ case rk_ns_t_afsdb:{
+ size_t hostlen = strnlen(pRec->Data.MX.pNameExchange, DNS_MAX_NAME_LENGTH);
+
+ rr->u.mx = (struct mx_record *)malloc(sizeof(struct mx_record) +
+ hostlen);
+ if (rr->u.mx == NULL) {
+ dns_free_rr(rr);
+ return NULL;
+ }
+
+ strcpy_s(rr->u.mx->domain, hostlen + 1, pRec->Data.MX.pNameExchange);
+ rr->u.mx->preference = pRec->Data.MX.wPreference;
+ break;
+ }
+
+ case rk_ns_t_srv:{
+ size_t hostlen = strnlen(pRec->Data.SRV.pNameTarget, DNS_MAX_NAME_LENGTH);
+
+ rr->u.srv =
+ (struct srv_record*)malloc(sizeof(struct srv_record) +
+ hostlen);
+ if(rr->u.srv == NULL) {
+ dns_free_rr(rr);
+ return NULL;
+ }
+
+ rr->u.srv->priority = pRec->Data.SRV.wPriority;
+ rr->u.srv->weight = pRec->Data.SRV.wWeight;
+ rr->u.srv->port = pRec->Data.SRV.wPort;
+ strcpy_s(rr->u.srv->target, hostlen + 1, pRec->Data.SRV.pNameTarget);
+
+ break;
+ }
+
+ case rk_ns_t_txt:{
+ size_t len;
+
+ if (pRec->Data.TXT.dwStringCount == 0) {
+ rr->u.txt = strdup("");
+ break;
+ }
+
+ len = strnlen(pRec->Data.TXT.pStringArray[0], DNS_MAX_TEXT_STRING_LENGTH);
+
+ rr->u.txt = (char *)malloc(len + 1);
+ strcpy_s(rr->u.txt, len + 1, pRec->Data.TXT.pStringArray[0]);
+
+ break;
+ }
+
+ case rk_ns_t_key : {
+ size_t key_len;
+
+ if (pRec->wDataLength < 4) {
+ dns_free_rr(rr);
+ return NULL;
+ }
+
+ key_len = pRec->wDataLength - 4;
+ rr->u.key = malloc (sizeof(*rr->u.key) + key_len - 1);
+ if (rr->u.key == NULL) {
+ dns_free_rr(rr);
+ return NULL;
+ }
+
+ rr->u.key->flags = pRec->Data.KEY.wFlags;
+ rr->u.key->protocol = pRec->Data.KEY.chProtocol;
+ rr->u.key->algorithm = pRec->Data.KEY.chAlgorithm;
+ rr->u.key->key_len = key_len;
+ memcpy_s (rr->u.key->key_data, key_len,
+ pRec->Data.KEY.Key, key_len);
+ break;
+ }
+
+ case rk_ns_t_sig : {
+ size_t sig_len, hostlen;
+
+ if(pRec->wDataLength <= 18) {
+ dns_free_rr(rr);
+ return NULL;
+ }
+
+ sig_len = pRec->wDataLength;
+
+ hostlen = strnlen(pRec->Data.SIG.pNameSigner, DNS_MAX_NAME_LENGTH);
+
+ rr->u.sig = malloc(sizeof(*rr->u.sig)
+ + hostlen + sig_len);
+ if (rr->u.sig == NULL) {
+ dns_free_rr(rr);
+ return NULL;
+ }
+ rr->u.sig->type = pRec->Data.SIG.wTypeCovered;
+ rr->u.sig->algorithm = pRec->Data.SIG.chAlgorithm;
+ rr->u.sig->labels = pRec->Data.SIG.chLabelCount;
+ rr->u.sig->orig_ttl = pRec->Data.SIG.dwOriginalTtl;
+ rr->u.sig->sig_expiration = pRec->Data.SIG.dwExpiration;
+ rr->u.sig->sig_inception = pRec->Data.SIG.dwTimeSigned;
+ rr->u.sig->key_tag = pRec->Data.SIG.wKeyTag;
+ rr->u.sig->sig_len = sig_len;
+ memcpy_s (rr->u.sig->sig_data, sig_len,
+ pRec->Data.SIG.Signature, sig_len);
+ rr->u.sig->signer = &rr->u.sig->sig_data[sig_len];
+ strcpy_s(rr->u.sig->signer, hostlen + 1, pRec->Data.SIG.pNameSigner);
+ break;
+ }
+
+#ifdef DNS_TYPE_DS
+ case rk_ns_t_ds: {
+ rr->u.ds = malloc (sizeof(*rr->u.ds) + pRec->Data.DS.wDigestLength - 1);
+ if (rr->u.ds == NULL) {
+ dns_free_rr(rr);
+ return NULL;
+ }
+
+ rr->u.ds->key_tag = pRec->Data.DS.wKeyTag;
+ rr->u.ds->algorithm = pRec->Data.DS.chAlgorithm;
+ rr->u.ds->digest_type = pRec->Data.DS.chDigestType;
+ rr->u.ds->digest_len = pRec->Data.DS.wDigestLength;
+ memcpy_s (rr->u.ds->digest_data, pRec->Data.DS.wDigestLength,
+ pRec->Data.DS.Digest, pRec->Data.DS.wDigestLength);
+ break;
+ }
+#endif
+
+ default:
+ dns_free_rr(rr);
+ return NULL;
+ }
+
+ rr->next = parse_dns_record(pRec->pNext);
+ return rr;
+}
+
+ROKEN_LIB_FUNCTION struct rk_dns_reply * ROKEN_LIB_CALL
+rk_dns_lookup(const char *domain, const char *type_name)
+{
+ DNS_STATUS status;
+ int type;
+ PDNS_RECORD pRec = NULL;
+ struct rk_dns_reply * r = NULL;
+
+ __try {
+
+ type = rk_dns_string_to_type(type_name);
+ if(type == -1) {
+ if(_resolve_debug)
+ fprintf(stderr, "dns_lookup: unknown resource type: `%s'\n",
+ type_name);
+ return NULL;
+ }
+
+ status = DnsQuery_UTF8(domain, type, DNS_QUERY_STANDARD, NULL,
+ &pRec, NULL);
+ if (status != ERROR_SUCCESS)
+ return NULL;
+
+ r = calloc(1, sizeof(*r));
+ r->q.domain = strdup(domain);
+ r->q.type = type;
+ r->q.class = 0;
+
+ r->head = parse_dns_record(pRec);
+
+ if (r->head == NULL) {
+ rk_dns_free_data(r);
+ return NULL;
+ } else {
+ return r;
+ }
+
+ } __finally {
+
+ if (pRec)
+ DnsRecordListFree(pRec, DnsFreeRecordList);
+
+ }
+}
+#endif /* HAVE_WINDNS */
+
#else /* NOT defined(HAVE_RES_SEARCH) && defined(HAVE_DN_EXPAND) */
ROKEN_LIB_FUNCTION struct rk_dns_reply * ROKEN_LIB_CALL
diff --git a/source4/heimdal/lib/roken/resolve.h b/source4/heimdal/lib/roken/resolve.h
index adec8084b8..fc1e97fc63 100644
--- a/source4/heimdal/lib/roken/resolve.h
+++ b/source4/heimdal/lib/roken/resolve.h
@@ -153,7 +153,7 @@ struct rk_sig_record {
unsigned sig_inception;
unsigned key_tag;
char *signer;
- unsigned sig_len;
+ size_t sig_len;
char sig_data[1]; /* also includes signer */
};
@@ -176,7 +176,7 @@ struct rk_ds_record {
unsigned key_tag;
unsigned algorithm;
unsigned digest_type;
- unsigned digest_len;
+ size_t digest_len;
u_char digest_data[1];
};
diff --git a/source4/heimdal/lib/roken/roken.h.in b/source4/heimdal/lib/roken/roken.h.in
index 76b083c797..d6e9024bd0 100644
--- a/source4/heimdal/lib/roken/roken.h.in
+++ b/source4/heimdal/lib/roken/roken.h.in
@@ -68,7 +68,8 @@ typedef SOCKET rk_socket_t;
#define rk_IS_BAD_SOCKET(s) ((s) == INVALID_SOCKET)
#define rk_IS_SOCKET_ERROR(rv) ((rv) == SOCKET_ERROR)
#define rk_SOCK_ERRNO WSAGetLastError()
-#define rk_SOCK_IOCTL(s,c,a) ioctlsocket((s),(c),(a))
+
+ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_SOCK_IOCTL(SOCKET s, long cmd, int * argp);
#define ETIMEDOUT WSAETIMEDOUT
#define EWOULDBLOCK WSAEWOULDBLOCK
@@ -124,6 +125,32 @@ typedef uint64_t u_int64_t;
#define UNREACHABLE(x) x
#define UNUSED_ARGUMENT(x) ((void) x)
+#define RETSIGTYPE void
+
+#define VOID_RETSIGTYPE 1
+
+#ifdef VOID_RETSIGTYPE
+#define SIGRETURN(x) return
+#else
+#define SIGRETURN(x) return (RETSIGTYPE)(x)
+#endif
+
+#ifndef CPP_ONLY
+
+typedef int pid_t;
+
+typedef unsigned int gid_t;
+
+typedef unsigned int uid_t;
+
+typedef unsigned short mode_t;
+
+#endif
+
+#ifndef __cplusplus
+#define inline __inline
+#endif
+
#else
#define UNREACHABLE(x)
@@ -315,6 +342,32 @@ rk_vsnprintf (char *str, size_t sz, const char *format, va_list args);
#endif /* _MSC_VER */
+#ifdef HAVE_WINSOCK
+
+/* While we are at it, define WinSock specific scatter gather socket
+ I/O. */
+
+#define iovec _WSABUF
+#define iov_base buf
+#define iov_len len
+
+struct msghdr {
+ void *msg_name;
+ socklen_t msg_namelen;
+ struct iovec *msg_iov;
+ size_t msg_iovlen;
+ void *msg_control;
+ socklen_t msg_controllen;
+ int msg_flags;
+};
+
+#define sendmsg sendmsg_w32
+
+ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
+sendmsg_w32(rk_socket_t s, const struct msghdr * msg, int flags);
+
+#endif /* HAVE_WINSOCK */
+
#ifndef HAVE_PUTENV
#define putenv rk_putenv
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL putenv(const char *);
@@ -563,6 +616,12 @@ ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL initgroups(const char *, gid_t);
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL fchown(int, uid_t, gid_t);
#endif
+#ifdef RENAME_DOES_NOT_UNLINK
+ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL rk_rename(const char *, const char *);
+#else
+#define rk_rename(__rk_rn_from,__rk_rn_to) rename(__rk_rn_from,__rk_rn_to)
+#endif
+
#if !defined(HAVE_DAEMON) || defined(NEED_DAEMON_PROTO)
#ifndef HAVE_DAEMON
#define daemon rk_daemon
@@ -824,32 +883,6 @@ ROKEN_LIB_FUNCTION const char * ROKEN_LIB_CALL
gai_strerror(int);
#endif
-#ifdef HAVE_WINSOCK
-
-/* While we are at it, define WinSock specific scatter gather socket
- I/O. */
-
-#define iovec _WSABUF
-#define iov_base buf
-#define iov_len len
-
-struct msghdr {
- void *msg_name;
- socklen_t msg_namelen;
- struct iovec *msg_iov;
- size_t msg_iovlen;
- void *msg_control;
- socklen_t msg_controllen;
- int msg_flags;
-};
-
-#define sendmsg sendmsg_w32
-
-ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
-sendmsg_w32(rk_socket_t s, const struct msghdr * msg, int flags);
-
-#endif
-
#ifdef NO_SLEEP
ROKEN_LIB_FUNCTION unsigned int ROKEN_LIB_CALL
@@ -1039,7 +1072,7 @@ void
rk_qsort(void *, size_t, size_t, int (*)(const void *, const void *));
#endif
-#if defined(__linux__) && SOCK_CLOEXEC && !defined(SOCKET_WRAPPER_REPLACE)
+#if defined(__linux__) && defined(SOCK_CLOEXEC) && !defined(SOCKET_WRAPPER_REPLACE)
#undef socket
#define socket(_fam,_type,_prot) rk_socket(_fam,_type,_prot)
int ROKEN_LIB_FUNCTION rk_socket(int, int, int);
diff --git a/source4/heimdal/lib/roken/roken_gethostby.c b/source4/heimdal/lib/roken/roken_gethostby.c
index c99596c536..1d6c8ffe8a 100644
--- a/source4/heimdal/lib/roken/roken_gethostby.c
+++ b/source4/heimdal/lib/roken/roken_gethostby.c
@@ -66,11 +66,13 @@ setup_int(const char *proxy_host, short proxy_port,
memset(&dns_addr, 0, sizeof(dns_addr));
if(dns_req)
free(dns_req);
+ dns_req = NULL;
if(proxy_host) {
if(make_address(proxy_host, &dns_addr.sin_addr) != 0)
return -1;
dns_addr.sin_port = htons(proxy_port);
- asprintf(&dns_req, "http://%s:%d%s", dns_host, dns_port, dns_path);
+ if (asprintf(&dns_req, "http://%s:%d%s", dns_host, dns_port, dns_path) < 0)
+ return -1;
} else {
if(make_address(dns_host, &dns_addr.sin_addr) != 0)
return -1;
@@ -135,7 +137,7 @@ roken_gethostby(const char *hostname)
{
int s;
struct sockaddr_in addr;
- char *request;
+ char *request = NULL;
char buf[1024];
int offset = 0;
int n;
@@ -144,7 +146,8 @@ roken_gethostby(const char *hostname)
if(dns_addr.sin_family == 0)
return NULL; /* no configured host */
addr = dns_addr;
- asprintf(&request, "GET %s?%s HTTP/1.0\r\n\r\n", dns_req, hostname);
+ if (asprintf(&request, "GET %s?%s HTTP/1.0\r\n\r\n", dns_req, hostname) < 0)
+ return NULL;
if(request == NULL)
return NULL;
s = socket(AF_INET, SOCK_STREAM, 0);
diff --git a/source4/heimdal/lib/roken/socket.c b/source4/heimdal/lib/roken/socket.c
index bd800ac5a1..ef594ffd0d 100644
--- a/source4/heimdal/lib/roken/socket.c
+++ b/source4/heimdal/lib/roken/socket.c
@@ -316,6 +316,19 @@ socket_to_fd(rk_socket_t sock, int flags)
#endif
}
+#ifdef HAVE_WINSOCK
+ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
+rk_SOCK_IOCTL(SOCKET s, long cmd, int * argp) {
+ u_long ul = (argp)? *argp : 0;
+ int rv;
+
+ rv = ioctlsocket(s, cmd, &ul);
+ if (argp)
+ *argp = (int) ul;
+ return rv;
+}
+#endif
+
#ifndef HEIMDAL_SMALLER
#undef socket
diff --git a/source4/heimdal/lib/roken/strerror_r.c b/source4/heimdal/lib/roken/strerror_r.c
index 5155c28cb5..85271ecaf5 100644
--- a/source4/heimdal/lib/roken/strerror_r.c
+++ b/source4/heimdal/lib/roken/strerror_r.c
@@ -72,7 +72,7 @@ rk_strerror_r(int eno, char *strerrbuf, size_t buflen)
return 0;
#else
int ret;
- ret = strlcpy(strerrbuf, buflen, strerror(eno));
+ ret = strlcpy(strerrbuf, strerror(eno), buflen);
if (ret > buflen)
return ERANGE;
return 0;
diff --git a/source4/heimdal/lib/wind/errorlist.c b/source4/heimdal/lib/wind/errorlist.c
index b2e2210493..c2907832a2 100644
--- a/source4/heimdal/lib/wind/errorlist.c
+++ b/source4/heimdal/lib/wind/errorlist.c
@@ -49,7 +49,7 @@ error_entry_cmp(const void *a, const void *b)
}
int
-_wind_stringprep_error(uint32_t cp, wind_profile_flags flags)
+_wind_stringprep_error(const uint32_t cp, wind_profile_flags flags)
{
struct error_entry ee = {cp};
const struct error_entry *s;
diff --git a/source4/heimdal/lib/wind/normalize.c b/source4/heimdal/lib/wind/normalize.c
index 102c577e66..3c68ea8660 100644
--- a/source4/heimdal/lib/wind/normalize.c
+++ b/source4/heimdal/lib/wind/normalize.c
@@ -164,13 +164,32 @@ compat_decomp(const uint32_t *in, size_t in_len,
return 0;
}
-static int
-cc_cmp(const void *a, const void *b)
+static void
+swap_char(uint32_t * a, uint32_t * b)
+{
+ uint32_t t;
+ t = *a;
+ *a = *b;
+ *b = t;
+}
+
+/* Unicode 5.2.0 D109 Canonical Ordering for a sequence of code points
+ * that all have Canonical_Combining_Class > 0 */
+static void
+canonical_reorder_sequence(uint32_t * a, size_t len)
{
- const uint32_t *ua = (const uint32_t *)a;
- const uint32_t *ub = (const uint32_t *)b;
+ size_t i, j;
- return _wind_combining_class(*ua) - _wind_combining_class(*ub);
+ if (len <= 1)
+ return;
+
+ for (i = 1; i < len; i++) {
+ for (j = i;
+ j > 0 &&
+ _wind_combining_class(a[j]) < _wind_combining_class(a[j-1]);
+ j--)
+ swap_char(&a[j], &a[j-1]);
+ }
}
static void
@@ -186,7 +205,7 @@ canonical_reorder(uint32_t *tmp, size_t tmp_len)
j < tmp_len && _wind_combining_class(tmp[j]);
++j)
;
- qsort(&tmp[i], j - i, sizeof(tmp[0]), cc_cmp);
+ canonical_reorder_sequence(&tmp[i], j - i);
i = j;
}
}
diff --git a/source4/heimdal/lib/wind/stringprep.py b/source4/heimdal/lib/wind/stringprep.py
index d64686a252..249b1dc2a1 100644
--- a/source4/heimdal/lib/wind/stringprep.py
+++ b/source4/heimdal/lib/wind/stringprep.py
@@ -46,7 +46,8 @@ ldap_error = ['A.1', 'C.3', 'C.4', 'C.5', 'C.8', 'rfc4518-error' ]
sasl_error = ['C.1.2', 'C.2.1', 'C.2.2', 'C.3', 'C.4', 'C.5', 'C.6', 'C.7', 'C.8', 'C.9']
name_map = ['B.1', 'B.2']
-ldap_map = ['rfc4518-map', 'B.2']
+ldap_map = ['rfc4518-map']
+ldap_case_map = ['rfc4518-map', 'B.2']
sasl_map = ['C.1.2', 'B.1']
def symbols(tabledict, tables):
@@ -69,6 +70,7 @@ def get_maplist():
d = dict()
_merge_table(d, dict(map(lambda x: [x, ['name']], name_map)))
_merge_table(d, dict(map(lambda x: [x, ['ldap']], ldap_map)))
+ _merge_table(d, dict(map(lambda x: [x, ['ldap_case']], ldap_case_map)))
_merge_table(d, dict(map(lambda x: [x, ['sasl']], sasl_map)))
return d
diff --git a/source4/heimdal/lib/wind/wind.h b/source4/heimdal/lib/wind/wind.h
index e890bebeee..dd55ea35db 100644
--- a/source4/heimdal/lib/wind/wind.h
+++ b/source4/heimdal/lib/wind/wind.h
@@ -46,6 +46,7 @@ typedef unsigned int wind_profile_flags;
#define WIND_PROFILE_NAME 0x00000001
#define WIND_PROFILE_SASL 0x00000002
#define WIND_PROFILE_LDAP 0x00000004
+#define WIND_PROFILE_LDAP_CASE 0x00000008
#define WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE 0x00010000
#define WIND_PROFILE_LDAP_CASE_EXACT_ASSERTION 0x00020000