diff options
Diffstat (limited to 'source4')
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(", USED(mp))) != MP_OKAY) +    return res; + +  USED(") = USED(mp); /* so clamping will work below */ +  qp = DIGITS("); + +  /* 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("); +  mp_exch(", mp); +  mp_clear("); + +  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(", 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(", 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(", 0) = q; +  } + +  /* Denormalize remainder                */ +  if(d != 0)  +    s_mp_div_2d(&rem, d); + +  s_mp_clamp("); +  s_mp_clamp(&rem); + +  /* Copy quotient back to output         */ +  s_mp_exch(", a); +   +  /* Copy remainder back to output        */ +  s_mp_exch(&rem, b); + +CLEANUP: +  mp_clear(&rem); +REM: +  mp_clear(&t); +T: +  mp_clear("); + +  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 Binary files differnew file mode 100644 index 0000000000..7414dbb276 --- /dev/null +++ b/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.sxd diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.tif b/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.tif Binary files differnew file mode 100644 index 0000000000..4a0c012d56 --- /dev/null +++ b/source4/heimdal/lib/hcrypto/libtommath/pics/design_process.tif diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.sxd b/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.sxd Binary files differnew file mode 100644 index 0000000000..6518404d5f --- /dev/null +++ b/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.sxd diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.tif b/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.tif Binary files differnew file mode 100644 index 0000000000..cb06e8edf1 --- /dev/null +++ b/source4/heimdal/lib/hcrypto/libtommath/pics/expt_state.tif 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 Binary files differnew file mode 100644 index 0000000000..76d6be3fac --- /dev/null +++ b/source4/heimdal/lib/hcrypto/libtommath/pics/primality.tif diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/radix.sxd b/source4/heimdal/lib/hcrypto/libtommath/pics/radix.sxd Binary files differnew file mode 100644 index 0000000000..b9eb9a032d --- /dev/null +++ b/source4/heimdal/lib/hcrypto/libtommath/pics/radix.sxd diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.sxd b/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.sxd Binary files differnew file mode 100644 index 0000000000..91e7c0d9f4 --- /dev/null +++ b/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.sxd diff --git a/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.tif b/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.tif Binary files differnew file mode 100644 index 0000000000..bb4cb96ebf --- /dev/null +++ b/source4/heimdal/lib/hcrypto/libtommath/pics/sliding_window.tif 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, ©); @@ -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  | 
