ssl/libcrypto/src/crypto/bn/bn_exp.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* crypto/bn/bn_exp.c */
       
     2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       
     3  * All rights reserved.
       
     4  *
       
     5  * This package is an SSL implementation written
       
     6  * by Eric Young (eay@cryptsoft.com).
       
     7  * The implementation was written so as to conform with Netscapes SSL.
       
     8  * 
       
     9  * This library is free for commercial and non-commercial use as long as
       
    10  * the following conditions are aheared to.  The following conditions
       
    11  * apply to all code found in this distribution, be it the RC4, RSA,
       
    12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
       
    13  * included with this distribution is covered by the same copyright terms
       
    14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
       
    15  * 
       
    16  * Copyright remains Eric Young's, and as such any Copyright notices in
       
    17  * the code are not to be removed.
       
    18  * If this package is used in a product, Eric Young should be given attribution
       
    19  * as the author of the parts of the library used.
       
    20  * This can be in the form of a textual message at program startup or
       
    21  * in documentation (online or textual) provided with the package.
       
    22  * 
       
    23  * Redistribution and use in source and binary forms, with or without
       
    24  * modification, are permitted provided that the following conditions
       
    25  * are met:
       
    26  * 1. Redistributions of source code must retain the copyright
       
    27  *    notice, this list of conditions and the following disclaimer.
       
    28  * 2. Redistributions in binary form must reproduce the above copyright
       
    29  *    notice, this list of conditions and the following disclaimer in the
       
    30  *    documentation and/or other materials provided with the distribution.
       
    31  * 3. All advertising materials mentioning features or use of this software
       
    32  *    must display the following acknowledgement:
       
    33  *    "This product includes cryptographic software written by
       
    34  *     Eric Young (eay@cryptsoft.com)"
       
    35  *    The word 'cryptographic' can be left out if the rouines from the library
       
    36  *    being used are not cryptographic related :-).
       
    37  * 4. If you include any Windows specific code (or a derivative thereof) from 
       
    38  *    the apps directory (application code) you must include an acknowledgement:
       
    39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
       
    40  * 
       
    41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
       
    42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       
    44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
       
    45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
       
    46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
       
    47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
    48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
       
    49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
    50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
       
    51  * SUCH DAMAGE.
       
    52  * 
       
    53  * The licence and distribution terms for any publically available version or
       
    54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
       
    55  * copied and put under another distribution licence
       
    56  * [including the GNU Public Licence.]
       
    57  */
       
    58 /* ====================================================================
       
    59  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
       
    60  *
       
    61  * Redistribution and use in source and binary forms, with or without
       
    62  * modification, are permitted provided that the following conditions
       
    63  * are met:
       
    64  *
       
    65  * 1. Redistributions of source code must retain the above copyright
       
    66  *    notice, this list of conditions and the following disclaimer. 
       
    67  *
       
    68  * 2. Redistributions in binary form must reproduce the above copyright
       
    69  *    notice, this list of conditions and the following disclaimer in
       
    70  *    the documentation and/or other materials provided with the
       
    71  *    distribution.
       
    72  *
       
    73  * 3. All advertising materials mentioning features or use of this
       
    74  *    software must display the following acknowledgment:
       
    75  *    "This product includes software developed by the OpenSSL Project
       
    76  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
       
    77  *
       
    78  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
       
    79  *    endorse or promote products derived from this software without
       
    80  *    prior written permission. For written permission, please contact
       
    81  *    openssl-core@openssl.org.
       
    82  *
       
    83  * 5. Products derived from this software may not be called "OpenSSL"
       
    84  *    nor may "OpenSSL" appear in their names without prior written
       
    85  *    permission of the OpenSSL Project.
       
    86  *
       
    87  * 6. Redistributions of any form whatsoever must retain the following
       
    88  *    acknowledgment:
       
    89  *    "This product includes software developed by the OpenSSL Project
       
    90  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
       
    91  *
       
    92  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
       
    93  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    94  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    95  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
       
    96  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    97  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
       
    98  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    99  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
       
   100  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
       
   101  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
       
   102  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
       
   103  * OF THE POSSIBILITY OF SUCH DAMAGE.
       
   104  * ====================================================================
       
   105  *
       
   106  * This product includes cryptographic software written by Eric Young
       
   107  * (eay@cryptsoft.com).  This product includes software written by Tim
       
   108  * Hudson (tjh@cryptsoft.com).
       
   109  *
       
   110  */
       
   111 
       
   112 
       
   113 #include "cryptlib.h"
       
   114 #include "bn_lcl.h"
       
   115 
       
   116 /* maximum precomputation table size for *variable* sliding windows */
       
   117 #define TABLE_SIZE	32
       
   118 
       
   119 /* this one works - simple but works */
       
   120 EXPORT_C int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
       
   121 	{
       
   122 	int i,bits,ret=0;
       
   123 	BIGNUM *v,*rr;
       
   124 
       
   125 	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
       
   126 		{
       
   127 		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
       
   128 		BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
       
   129 		return -1;
       
   130 		}
       
   131 
       
   132 	BN_CTX_start(ctx);
       
   133 	if ((r == a) || (r == p))
       
   134 		rr = BN_CTX_get(ctx);
       
   135 	else
       
   136 		rr = r;
       
   137 	if ((v = BN_CTX_get(ctx)) == NULL) goto err;
       
   138 
       
   139 	if (BN_copy(v,a) == NULL) goto err;
       
   140 	bits=BN_num_bits(p);
       
   141 
       
   142 	if (BN_is_odd(p))
       
   143 		{ if (BN_copy(rr,a) == NULL) goto err; }
       
   144 	else	{ if (!BN_one(rr)) goto err; }
       
   145 
       
   146 	for (i=1; i<bits; i++)
       
   147 		{
       
   148 		if (!BN_sqr(v,v,ctx)) goto err;
       
   149 		if (BN_is_bit_set(p,i))
       
   150 			{
       
   151 			if (!BN_mul(rr,rr,v,ctx)) goto err;
       
   152 			}
       
   153 		}
       
   154 	ret=1;
       
   155 err:
       
   156 	if (r != rr) BN_copy(r,rr);
       
   157 	BN_CTX_end(ctx);
       
   158 	bn_check_top(r);
       
   159 	return(ret);
       
   160 	}
       
   161 
       
   162 
       
   163 EXPORT_C int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
       
   164 	       BN_CTX *ctx)
       
   165 	{
       
   166 	int ret;
       
   167 
       
   168 	bn_check_top(a);
       
   169 	bn_check_top(p);
       
   170 	bn_check_top(m);
       
   171 
       
   172 	/* For even modulus  m = 2^k*m_odd,  it might make sense to compute
       
   173 	 * a^p mod m_odd  and  a^p mod 2^k  separately (with Montgomery
       
   174 	 * exponentiation for the odd part), using appropriate exponent
       
   175 	 * reductions, and combine the results using the CRT.
       
   176 	 *
       
   177 	 * For now, we use Montgomery only if the modulus is odd; otherwise,
       
   178 	 * exponentiation using the reciprocal-based quick remaindering
       
   179 	 * algorithm is used.
       
   180 	 *
       
   181 	 * (Timing obtained with expspeed.c [computations  a^p mod m
       
   182 	 * where  a, p, m  are of the same length: 256, 512, 1024, 2048,
       
   183 	 * 4096, 8192 bits], compared to the running time of the
       
   184 	 * standard algorithm:
       
   185 	 *
       
   186 	 *   BN_mod_exp_mont   33 .. 40 %  [AMD K6-2, Linux, debug configuration]
       
   187          *                     55 .. 77 %  [UltraSparc processor, but
       
   188 	 *                                  debug-solaris-sparcv8-gcc conf.]
       
   189 	 * 
       
   190 	 *   BN_mod_exp_recp   50 .. 70 %  [AMD K6-2, Linux, debug configuration]
       
   191 	 *                     62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
       
   192 	 *
       
   193 	 * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
       
   194 	 * at 2048 and more bits, but at 512 and 1024 bits, it was
       
   195 	 * slower even than the standard algorithm!
       
   196 	 *
       
   197 	 * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
       
   198 	 * should be obtained when the new Montgomery reduction code
       
   199 	 * has been integrated into OpenSSL.)
       
   200 	 */
       
   201 
       
   202 #define MONT_MUL_MOD
       
   203 #define MONT_EXP_WORD
       
   204 #define RECP_MUL_MOD
       
   205 
       
   206 #ifdef MONT_MUL_MOD
       
   207 	/* I have finally been able to take out this pre-condition of
       
   208 	 * the top bit being set.  It was caused by an error in BN_div
       
   209 	 * with negatives.  There was also another problem when for a^b%m
       
   210 	 * a >= m.  eay 07-May-97 */
       
   211 /*	if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
       
   212 
       
   213 	if (BN_is_odd(m))
       
   214 		{
       
   215 #  ifdef MONT_EXP_WORD
       
   216 		if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0))
       
   217 			{
       
   218 			BN_ULONG A = a->d[0];
       
   219 			ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
       
   220 			}
       
   221 		else
       
   222 #  endif
       
   223 			ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL);
       
   224 		}
       
   225 	else
       
   226 #endif
       
   227 #ifdef RECP_MUL_MOD
       
   228 		{ ret=BN_mod_exp_recp(r,a,p,m,ctx); }
       
   229 #else
       
   230 		{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }
       
   231 #endif
       
   232 
       
   233 	bn_check_top(r);
       
   234 	return(ret);
       
   235 	}
       
   236 
       
   237 
       
   238 EXPORT_C int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
       
   239 		    const BIGNUM *m, BN_CTX *ctx)
       
   240 	{
       
   241 	int i,j,bits,ret=0,wstart,wend,window,wvalue;
       
   242 	int start=1;
       
   243 	BIGNUM *aa;
       
   244 	/* Table of variables obtained from 'ctx' */
       
   245 	BIGNUM *val[TABLE_SIZE];
       
   246 	BN_RECP_CTX recp;
       
   247 
       
   248 	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
       
   249 		{
       
   250 		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
       
   251 		BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
       
   252 		return -1;
       
   253 		}
       
   254 
       
   255 	bits=BN_num_bits(p);
       
   256 
       
   257 	if (bits == 0)
       
   258 		{
       
   259 		ret = BN_one(r);
       
   260 		return ret;
       
   261 		}
       
   262 
       
   263 	BN_CTX_start(ctx);
       
   264 	aa = BN_CTX_get(ctx);
       
   265 	val[0] = BN_CTX_get(ctx);
       
   266 	if(!aa || !val[0]) goto err;
       
   267 
       
   268 	BN_RECP_CTX_init(&recp);
       
   269 	if (m->neg)
       
   270 		{
       
   271 		/* ignore sign of 'm' */
       
   272 		if (!BN_copy(aa, m)) goto err;
       
   273 		aa->neg = 0;
       
   274 		if (BN_RECP_CTX_set(&recp,aa,ctx) <= 0) goto err;
       
   275 		}
       
   276 	else
       
   277 		{
       
   278 		if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
       
   279 		}
       
   280 
       
   281 	if (!BN_nnmod(val[0],a,m,ctx)) goto err;		/* 1 */
       
   282 	if (BN_is_zero(val[0]))
       
   283 		{
       
   284 		BN_zero(r);
       
   285 		ret = 1;
       
   286 		goto err;
       
   287 		}
       
   288 
       
   289 	window = BN_window_bits_for_exponent_size(bits);
       
   290 	if (window > 1)
       
   291 		{
       
   292 		if (!BN_mod_mul_reciprocal(aa,val[0],val[0],&recp,ctx))
       
   293 			goto err;				/* 2 */
       
   294 		j=1<<(window-1);
       
   295 		for (i=1; i<j; i++)
       
   296 			{
       
   297 			if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
       
   298 					!BN_mod_mul_reciprocal(val[i],val[i-1],
       
   299 						aa,&recp,ctx))
       
   300 				goto err;
       
   301 			}
       
   302 		}
       
   303 		
       
   304 	start=1;	/* This is used to avoid multiplication etc
       
   305 			 * when there is only the value '1' in the
       
   306 			 * buffer. */
       
   307 	wvalue=0;	/* The 'value' of the window */
       
   308 	wstart=bits-1;	/* The top bit of the window */
       
   309 	wend=0;		/* The bottom bit of the window */
       
   310 
       
   311 	if (!BN_one(r)) goto err;
       
   312 
       
   313 	for (;;)
       
   314 		{
       
   315 		if (BN_is_bit_set(p,wstart) == 0)
       
   316 			{
       
   317 			if (!start)
       
   318 				if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
       
   319 				goto err;
       
   320 			if (wstart == 0) break;
       
   321 			wstart--;
       
   322 			continue;
       
   323 			}
       
   324 		/* We now have wstart on a 'set' bit, we now need to work out
       
   325 		 * how bit a window to do.  To do this we need to scan
       
   326 		 * forward until the last set bit before the end of the
       
   327 		 * window */
       
   328 		j=wstart;
       
   329 		wvalue=1;
       
   330 		wend=0;
       
   331 		for (i=1; i<window; i++)
       
   332 			{
       
   333 			if (wstart-i < 0) break;
       
   334 			if (BN_is_bit_set(p,wstart-i))
       
   335 				{
       
   336 				wvalue<<=(i-wend);
       
   337 				wvalue|=1;
       
   338 				wend=i;
       
   339 				}
       
   340 			}
       
   341 
       
   342 		/* wend is the size of the current window */
       
   343 		j=wend+1;
       
   344 		/* add the 'bytes above' */
       
   345 		if (!start)
       
   346 			for (i=0; i<j; i++)
       
   347 				{
       
   348 				if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
       
   349 					goto err;
       
   350 				}
       
   351 		
       
   352 		/* wvalue will be an odd number < 2^window */
       
   353 		if (!BN_mod_mul_reciprocal(r,r,val[wvalue>>1],&recp,ctx))
       
   354 			goto err;
       
   355 
       
   356 		/* move the 'window' down further */
       
   357 		wstart-=wend+1;
       
   358 		wvalue=0;
       
   359 		start=0;
       
   360 		if (wstart < 0) break;
       
   361 		}
       
   362 	ret=1;
       
   363 err:
       
   364 	BN_CTX_end(ctx);
       
   365 	BN_RECP_CTX_free(&recp);
       
   366 	bn_check_top(r);
       
   367 	return(ret);
       
   368 	}
       
   369 
       
   370 
       
   371 EXPORT_C int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
       
   372 		    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
       
   373 	{
       
   374 	int i,j,bits,ret=0,wstart,wend,window,wvalue;
       
   375 	int start=1;
       
   376 	BIGNUM *d,*r;
       
   377 	const BIGNUM *aa;
       
   378 	/* Table of variables obtained from 'ctx' */
       
   379 	BIGNUM *val[TABLE_SIZE];
       
   380 	BN_MONT_CTX *mont=NULL;
       
   381 
       
   382 	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
       
   383 		{
       
   384 		return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
       
   385 		}
       
   386 
       
   387 	bn_check_top(a);
       
   388 	bn_check_top(p);
       
   389 	bn_check_top(m);
       
   390 
       
   391 	if (!BN_is_odd(m))
       
   392 		{
       
   393 		BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
       
   394 		return(0);
       
   395 		}
       
   396 	bits=BN_num_bits(p);
       
   397 	if (bits == 0)
       
   398 		{
       
   399 		ret = BN_one(rr);
       
   400 		return ret;
       
   401 		}
       
   402 
       
   403 	BN_CTX_start(ctx);
       
   404 	d = BN_CTX_get(ctx);
       
   405 	r = BN_CTX_get(ctx);
       
   406 	val[0] = BN_CTX_get(ctx);
       
   407 	if (!d || !r || !val[0]) goto err;
       
   408 
       
   409 	/* If this is not done, things will break in the montgomery
       
   410 	 * part */
       
   411 
       
   412 	if (in_mont != NULL)
       
   413 		mont=in_mont;
       
   414 	else
       
   415 		{
       
   416 		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
       
   417 		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
       
   418 		}
       
   419 
       
   420 	if (a->neg || BN_ucmp(a,m) >= 0)
       
   421 		{
       
   422 		if (!BN_nnmod(val[0],a,m,ctx))
       
   423 			goto err;
       
   424 		aa= val[0];
       
   425 		}
       
   426 	else
       
   427 		aa=a;
       
   428 	if (BN_is_zero(aa))
       
   429 		{
       
   430 		BN_zero(rr);
       
   431 		ret = 1;
       
   432 		goto err;
       
   433 		}
       
   434 	if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */
       
   435 
       
   436 	window = BN_window_bits_for_exponent_size(bits);
       
   437 	if (window > 1)
       
   438 		{
       
   439 		if (!BN_mod_mul_montgomery(d,val[0],val[0],mont,ctx)) goto err; /* 2 */
       
   440 		j=1<<(window-1);
       
   441 		for (i=1; i<j; i++)
       
   442 			{
       
   443 			if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
       
   444 					!BN_mod_mul_montgomery(val[i],val[i-1],
       
   445 						d,mont,ctx))
       
   446 				goto err;
       
   447 			}
       
   448 		}
       
   449 
       
   450 	start=1;	/* This is used to avoid multiplication etc
       
   451 			 * when there is only the value '1' in the
       
   452 			 * buffer. */
       
   453 	wvalue=0;	/* The 'value' of the window */
       
   454 	wstart=bits-1;	/* The top bit of the window */
       
   455 	wend=0;		/* The bottom bit of the window */
       
   456 
       
   457 	if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
       
   458 	for (;;)
       
   459 		{
       
   460 		if (BN_is_bit_set(p,wstart) == 0)
       
   461 			{
       
   462 			if (!start)
       
   463 				{
       
   464 				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
       
   465 				goto err;
       
   466 				}
       
   467 			if (wstart == 0) break;
       
   468 			wstart--;
       
   469 			continue;
       
   470 			}
       
   471 		/* We now have wstart on a 'set' bit, we now need to work out
       
   472 		 * how bit a window to do.  To do this we need to scan
       
   473 		 * forward until the last set bit before the end of the
       
   474 		 * window */
       
   475 		j=wstart;
       
   476 		wvalue=1;
       
   477 		wend=0;
       
   478 		for (i=1; i<window; i++)
       
   479 			{
       
   480 			if (wstart-i < 0) break;
       
   481 			if (BN_is_bit_set(p,wstart-i))
       
   482 				{
       
   483 				wvalue<<=(i-wend);
       
   484 				wvalue|=1;
       
   485 				wend=i;
       
   486 				}
       
   487 			}
       
   488 
       
   489 		/* wend is the size of the current window */
       
   490 		j=wend+1;
       
   491 		/* add the 'bytes above' */
       
   492 		if (!start)
       
   493 			for (i=0; i<j; i++)
       
   494 				{
       
   495 				if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))
       
   496 					goto err;
       
   497 				}
       
   498 		
       
   499 		/* wvalue will be an odd number < 2^window */
       
   500 		if (!BN_mod_mul_montgomery(r,r,val[wvalue>>1],mont,ctx))
       
   501 			goto err;
       
   502 
       
   503 		/* move the 'window' down further */
       
   504 		wstart-=wend+1;
       
   505 		wvalue=0;
       
   506 		start=0;
       
   507 		if (wstart < 0) break;
       
   508 		}
       
   509 	if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
       
   510 	ret=1;
       
   511 err:
       
   512 	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
       
   513 	BN_CTX_end(ctx);
       
   514 	bn_check_top(rr);
       
   515 	return(ret);
       
   516 	}
       
   517 
       
   518 
       
   519 /* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout
       
   520  * so that accessing any of these table values shows the same access pattern as far
       
   521  * as cache lines are concerned.  The following functions are used to transfer a BIGNUM
       
   522  * from/to that table. */
       
   523 
       
   524 static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
       
   525 	{
       
   526 	size_t i, j;
       
   527 
       
   528 	if (bn_wexpand(b, top) == NULL)
       
   529 		return 0;
       
   530 	while (b->top < top)
       
   531 		{
       
   532 		b->d[b->top++] = 0;
       
   533 		}
       
   534 	
       
   535 	for (i = 0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
       
   536 		{
       
   537 		buf[j] = ((unsigned char*)b->d)[i];
       
   538 		}
       
   539 
       
   540 	bn_correct_top(b);
       
   541 	return 1;
       
   542 	}
       
   543 
       
   544 static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
       
   545 	{
       
   546 	size_t i, j;
       
   547 
       
   548 	if (bn_wexpand(b, top) == NULL)
       
   549 		return 0;
       
   550 
       
   551 	for (i=0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
       
   552 		{
       
   553 		((unsigned char*)b->d)[i] = buf[j];
       
   554 		}
       
   555 
       
   556 	b->top = top;
       
   557 	bn_correct_top(b);
       
   558 	return 1;
       
   559 	}	
       
   560 
       
   561 /* Given a pointer value, compute the next address that is a cache line multiple. */
       
   562 #define MOD_EXP_CTIME_ALIGN(x_) \
       
   563 	((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((BN_ULONG)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
       
   564 
       
   565 /* This variant of BN_mod_exp_mont() uses fixed windows and the special
       
   566  * precomputation memory layout to limit data-dependency to a minimum
       
   567  * to protect secret exponents (cf. the hyper-threading timing attacks
       
   568  * pointed out by Colin Percival,
       
   569  * http://www.daemonology.net/hyperthreading-considered-harmful/)
       
   570  */
       
   571 EXPORT_C int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
       
   572 		    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
       
   573 	{
       
   574 	int i,bits,ret=0,idx,window,wvalue;
       
   575 	int top;
       
   576  	BIGNUM *r;
       
   577 	const BIGNUM *aa;
       
   578 	BN_MONT_CTX *mont=NULL;
       
   579 
       
   580 	int numPowers;
       
   581 	unsigned char *powerbufFree=NULL;
       
   582 	int powerbufLen = 0;
       
   583 	unsigned char *powerbuf=NULL;
       
   584 	BIGNUM *computeTemp=NULL, *am=NULL;
       
   585 
       
   586 	bn_check_top(a);
       
   587 	bn_check_top(p);
       
   588 	bn_check_top(m);
       
   589 
       
   590 	top = m->top;
       
   591 
       
   592 	if (!(m->d[0] & 1))
       
   593 		{
       
   594 		BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME,BN_R_CALLED_WITH_EVEN_MODULUS);
       
   595 		return(0);
       
   596 		}
       
   597 	bits=BN_num_bits(p);
       
   598 	if (bits == 0)
       
   599 		{
       
   600 		ret = BN_one(rr);
       
   601 		return ret;
       
   602 		}
       
   603 
       
   604  	/* Initialize BIGNUM context and allocate intermediate result */
       
   605 	BN_CTX_start(ctx);
       
   606 	r = BN_CTX_get(ctx);
       
   607 	if (r == NULL) goto err;
       
   608 
       
   609 	/* Allocate a montgomery context if it was not supplied by the caller.
       
   610 	 * If this is not done, things will break in the montgomery part.
       
   611  	 */
       
   612 	if (in_mont != NULL)
       
   613 		mont=in_mont;
       
   614 	else
       
   615 		{
       
   616 		if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
       
   617 		if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
       
   618 		}
       
   619 
       
   620 	/* Get the window size to use with size of p. */
       
   621 	window = BN_window_bits_for_ctime_exponent_size(bits);
       
   622 
       
   623 	/* Allocate a buffer large enough to hold all of the pre-computed
       
   624 	 * powers of a.
       
   625 	 */
       
   626 	numPowers = 1 << window;
       
   627 	powerbufLen = sizeof(m->d[0])*top*numPowers;
       
   628 	if ((powerbufFree=(unsigned char*)OPENSSL_malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
       
   629 		goto err;
       
   630 		
       
   631 	powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
       
   632 	memset(powerbuf, 0, powerbufLen);
       
   633 
       
   634  	/* Initialize the intermediate result. Do this early to save double conversion,
       
   635 	 * once each for a^0 and intermediate result.
       
   636 	 */
       
   637  	if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
       
   638 	if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, numPowers)) goto err;
       
   639 
       
   640 	/* Initialize computeTemp as a^1 with montgomery precalcs */
       
   641 	computeTemp = BN_CTX_get(ctx);
       
   642 	am = BN_CTX_get(ctx);
       
   643 	if (computeTemp==NULL || am==NULL) goto err;
       
   644 
       
   645 	if (a->neg || BN_ucmp(a,m) >= 0)
       
   646 		{
       
   647 		if (!BN_mod(am,a,m,ctx))
       
   648 			goto err;
       
   649 		aa= am;
       
   650 		}
       
   651 	else
       
   652 		aa=a;
       
   653 	if (!BN_to_montgomery(am,aa,mont,ctx)) goto err;
       
   654 	if (!BN_copy(computeTemp, am)) goto err;
       
   655 	if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, numPowers)) goto err;
       
   656 
       
   657 	/* If the window size is greater than 1, then calculate
       
   658 	 * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
       
   659 	 * (even powers could instead be computed as (a^(i/2))^2
       
   660 	 * to use the slight performance advantage of sqr over mul).
       
   661 	 */
       
   662 	if (window > 1)
       
   663 		{
       
   664 		for (i=2; i<numPowers; i++)
       
   665 			{
       
   666 			/* Calculate a^i = a^(i-1) * a */
       
   667 			if (!BN_mod_mul_montgomery(computeTemp,am,computeTemp,mont,ctx))
       
   668 				goto err;
       
   669 			if (!MOD_EXP_CTIME_COPY_TO_PREBUF(computeTemp, top, powerbuf, i, numPowers)) goto err;
       
   670 			}
       
   671 		}
       
   672 
       
   673  	/* Adjust the number of bits up to a multiple of the window size.
       
   674  	 * If the exponent length is not a multiple of the window size, then
       
   675  	 * this pads the most significant bits with zeros to normalize the
       
   676  	 * scanning loop to there's no special cases.
       
   677  	 *
       
   678  	 * * NOTE: Making the window size a power of two less than the native
       
   679 	 * * word size ensures that the padded bits won't go past the last
       
   680  	 * * word in the internal BIGNUM structure. Going past the end will
       
   681  	 * * still produce the correct result, but causes a different branch
       
   682  	 * * to be taken in the BN_is_bit_set function.
       
   683  	 */
       
   684  	bits = ((bits+window-1)/window)*window;
       
   685  	idx=bits-1;	/* The top bit of the window */
       
   686 
       
   687  	/* Scan the exponent one window at a time starting from the most
       
   688  	 * significant bits.
       
   689  	 */
       
   690  	while (idx >= 0)
       
   691   		{
       
   692  		wvalue=0; /* The 'value' of the window */
       
   693  		
       
   694  		/* Scan the window, squaring the result as we go */
       
   695  		for (i=0; i<window; i++,idx--)
       
   696  			{
       
   697 			if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))	goto err;
       
   698 			wvalue = (wvalue<<1)+BN_is_bit_set(p,idx);
       
   699   			}
       
   700  		
       
   701 		/* Fetch the appropriate pre-computed value from the pre-buf */
       
   702 		if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(computeTemp, top, powerbuf, wvalue, numPowers)) goto err;
       
   703 
       
   704  		/* Multiply the result into the intermediate result */
       
   705  		if (!BN_mod_mul_montgomery(r,r,computeTemp,mont,ctx)) goto err;
       
   706   		}
       
   707 
       
   708  	/* Convert the final result from montgomery to standard format */
       
   709 	if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
       
   710 	ret=1;
       
   711 err:
       
   712 	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
       
   713 	if (powerbuf!=NULL)
       
   714 		{
       
   715 		OPENSSL_cleanse(powerbuf,powerbufLen);
       
   716 		OPENSSL_free(powerbufFree);
       
   717 		}
       
   718  	if (am!=NULL) BN_clear(am);
       
   719  	if (computeTemp!=NULL) BN_clear(computeTemp);
       
   720 	BN_CTX_end(ctx);
       
   721 	return(ret);
       
   722 	}
       
   723 
       
   724 EXPORT_C int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
       
   725                          const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
       
   726 	{
       
   727 	BN_MONT_CTX *mont = NULL;
       
   728 	int b, bits, ret=0;
       
   729 	int r_is_one;
       
   730 	BN_ULONG w, next_w;
       
   731 	BIGNUM *d, *r, *t;
       
   732 	BIGNUM *swap_tmp;
       
   733 #define BN_MOD_MUL_WORD(r, w, m) \
       
   734 		(BN_mul_word(r, (w)) && \
       
   735 		(/* BN_ucmp(r, (m)) < 0 ? 1 :*/  \
       
   736 			(BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
       
   737 		/* BN_MOD_MUL_WORD is only used with 'w' large,
       
   738 		 * so the BN_ucmp test is probably more overhead
       
   739 		 * than always using BN_mod (which uses BN_copy if
       
   740 		 * a similar test returns true). */
       
   741 		/* We can use BN_mod and do not need BN_nnmod because our
       
   742 		 * accumulator is never negative (the result of BN_mod does
       
   743 		 * not depend on the sign of the modulus).
       
   744 		 */
       
   745 #define BN_TO_MONTGOMERY_WORD(r, w, mont) \
       
   746 		(BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
       
   747 
       
   748 	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
       
   749 		{
       
   750 		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
       
   751 		BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
       
   752 		return -1;
       
   753 		}
       
   754 
       
   755 	bn_check_top(p);
       
   756 	bn_check_top(m);
       
   757 
       
   758 	if (!BN_is_odd(m))
       
   759 		{
       
   760 		BNerr(BN_F_BN_MOD_EXP_MONT_WORD,BN_R_CALLED_WITH_EVEN_MODULUS);
       
   761 		return(0);
       
   762 		}
       
   763 	if (m->top == 1)
       
   764 		a %= m->d[0]; /* make sure that 'a' is reduced */
       
   765 
       
   766 	bits = BN_num_bits(p);
       
   767 	if (bits == 0)
       
   768 		{
       
   769 		ret = BN_one(rr);
       
   770 		return ret;
       
   771 		}
       
   772 	if (a == 0)
       
   773 		{
       
   774 		BN_zero(rr);
       
   775 		ret = 1;
       
   776 		return ret;
       
   777 		}
       
   778 
       
   779 	BN_CTX_start(ctx);
       
   780 	d = BN_CTX_get(ctx);
       
   781 	r = BN_CTX_get(ctx);
       
   782 	t = BN_CTX_get(ctx);
       
   783 	if (d == NULL || r == NULL || t == NULL) goto err;
       
   784 
       
   785 	if (in_mont != NULL)
       
   786 		mont=in_mont;
       
   787 	else
       
   788 		{
       
   789 		if ((mont = BN_MONT_CTX_new()) == NULL) goto err;
       
   790 		if (!BN_MONT_CTX_set(mont, m, ctx)) goto err;
       
   791 		}
       
   792 
       
   793 	r_is_one = 1; /* except for Montgomery factor */
       
   794 
       
   795 	/* bits-1 >= 0 */
       
   796 
       
   797 	/* The result is accumulated in the product r*w. */
       
   798 	w = a; /* bit 'bits-1' of 'p' is always set */
       
   799 	for (b = bits-2; b >= 0; b--)
       
   800 		{
       
   801 		/* First, square r*w. */
       
   802 		next_w = w*w;
       
   803 		if ((next_w/w) != w) /* overflow */
       
   804 			{
       
   805 			if (r_is_one)
       
   806 				{
       
   807 				if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
       
   808 				r_is_one = 0;
       
   809 				}
       
   810 			else
       
   811 				{
       
   812 				if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
       
   813 				}
       
   814 			next_w = 1;
       
   815 			}
       
   816 		w = next_w;
       
   817 		if (!r_is_one)
       
   818 			{
       
   819 			if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) goto err;
       
   820 			}
       
   821 
       
   822 		/* Second, multiply r*w by 'a' if exponent bit is set. */
       
   823 		if (BN_is_bit_set(p, b))
       
   824 			{
       
   825 			next_w = w*a;
       
   826 			if ((next_w/a) != w) /* overflow */
       
   827 				{
       
   828 				if (r_is_one)
       
   829 					{
       
   830 					if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
       
   831 					r_is_one = 0;
       
   832 					}
       
   833 				else
       
   834 					{
       
   835 					if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
       
   836 					}
       
   837 				next_w = a;
       
   838 				}
       
   839 			w = next_w;
       
   840 			}
       
   841 		}
       
   842 
       
   843 	/* Finally, set r:=r*w. */
       
   844 	if (w != 1)
       
   845 		{
       
   846 		if (r_is_one)
       
   847 			{
       
   848 			if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) goto err;
       
   849 			r_is_one = 0;
       
   850 			}
       
   851 		else
       
   852 			{
       
   853 			if (!BN_MOD_MUL_WORD(r, w, m)) goto err;
       
   854 			}
       
   855 		}
       
   856 
       
   857 	if (r_is_one) /* can happen only if a == 1*/
       
   858 		{
       
   859 		if (!BN_one(rr)) goto err;
       
   860 		}
       
   861 	else
       
   862 		{
       
   863 		if (!BN_from_montgomery(rr, r, mont, ctx)) goto err;
       
   864 		}
       
   865 	ret = 1;
       
   866 err:
       
   867 	if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
       
   868 	BN_CTX_end(ctx);
       
   869 	bn_check_top(rr);
       
   870 	return(ret);
       
   871 	}
       
   872 
       
   873 
       
   874 /* The old fallback, simple version :-) */
       
   875 EXPORT_C int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
       
   876 		const BIGNUM *m, BN_CTX *ctx)
       
   877 	{
       
   878 	int i,j,bits,ret=0,wstart,wend,window,wvalue;
       
   879 	int start=1;
       
   880 	BIGNUM *d;
       
   881 	/* Table of variables obtained from 'ctx' */
       
   882 	BIGNUM *val[TABLE_SIZE];
       
   883 
       
   884 	if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
       
   885 		{
       
   886 		/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
       
   887 		BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
       
   888 		return -1;
       
   889 		}
       
   890 
       
   891 	bits=BN_num_bits(p);
       
   892 
       
   893 	if (bits == 0)
       
   894 		{
       
   895 		ret = BN_one(r);
       
   896 		return ret;
       
   897 		}
       
   898 
       
   899 	BN_CTX_start(ctx);
       
   900 	d = BN_CTX_get(ctx);
       
   901 	val[0] = BN_CTX_get(ctx);
       
   902 	if(!d || !val[0]) goto err;
       
   903 
       
   904 	if (!BN_nnmod(val[0],a,m,ctx)) goto err;		/* 1 */
       
   905 	if (BN_is_zero(val[0]))
       
   906 		{
       
   907 		BN_zero(r);
       
   908 		ret = 1;
       
   909 		goto err;
       
   910 		}
       
   911 
       
   912 	window = BN_window_bits_for_exponent_size(bits);
       
   913 	if (window > 1)
       
   914 		{
       
   915 		if (!BN_mod_mul(d,val[0],val[0],m,ctx))
       
   916 			goto err;				/* 2 */
       
   917 		j=1<<(window-1);
       
   918 		for (i=1; i<j; i++)
       
   919 			{
       
   920 			if(((val[i] = BN_CTX_get(ctx)) == NULL) ||
       
   921 					!BN_mod_mul(val[i],val[i-1],d,m,ctx))
       
   922 				goto err;
       
   923 			}
       
   924 		}
       
   925 
       
   926 	start=1;	/* This is used to avoid multiplication etc
       
   927 			 * when there is only the value '1' in the
       
   928 			 * buffer. */
       
   929 	wvalue=0;	/* The 'value' of the window */
       
   930 	wstart=bits-1;	/* The top bit of the window */
       
   931 	wend=0;		/* The bottom bit of the window */
       
   932 
       
   933 	if (!BN_one(r)) goto err;
       
   934 
       
   935 	for (;;)
       
   936 		{
       
   937 		if (BN_is_bit_set(p,wstart) == 0)
       
   938 			{
       
   939 			if (!start)
       
   940 				if (!BN_mod_mul(r,r,r,m,ctx))
       
   941 				goto err;
       
   942 			if (wstart == 0) break;
       
   943 			wstart--;
       
   944 			continue;
       
   945 			}
       
   946 		/* We now have wstart on a 'set' bit, we now need to work out
       
   947 		 * how bit a window to do.  To do this we need to scan
       
   948 		 * forward until the last set bit before the end of the
       
   949 		 * window */
       
   950 		j=wstart;
       
   951 		wvalue=1;
       
   952 		wend=0;
       
   953 		for (i=1; i<window; i++)
       
   954 			{
       
   955 			if (wstart-i < 0) break;
       
   956 			if (BN_is_bit_set(p,wstart-i))
       
   957 				{
       
   958 				wvalue<<=(i-wend);
       
   959 				wvalue|=1;
       
   960 				wend=i;
       
   961 				}
       
   962 			}
       
   963 
       
   964 		/* wend is the size of the current window */
       
   965 		j=wend+1;
       
   966 		/* add the 'bytes above' */
       
   967 		if (!start)
       
   968 			for (i=0; i<j; i++)
       
   969 				{
       
   970 				if (!BN_mod_mul(r,r,r,m,ctx))
       
   971 					goto err;
       
   972 				}
       
   973 		
       
   974 		/* wvalue will be an odd number < 2^window */
       
   975 		if (!BN_mod_mul(r,r,val[wvalue>>1],m,ctx))
       
   976 			goto err;
       
   977 
       
   978 		/* move the 'window' down further */
       
   979 		wstart-=wend+1;
       
   980 		wvalue=0;
       
   981 		start=0;
       
   982 		if (wstart < 0) break;
       
   983 		}
       
   984 	ret=1;
       
   985 err:
       
   986 	BN_CTX_end(ctx);
       
   987 	bn_check_top(r);
       
   988 	return(ret);
       
   989 	}
       
   990