os/ossrv/ssl/libcrypto/src/crypto/bn/bn_exp.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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