Commit cdfe0fdd authored by Bodo Möller's avatar Bodo Möller
Browse files

Fix OPENSSL_BN_ASM_MONT5 for corner cases; add a test.

Submitted by: Emilia Kasper
parent 59365214
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -836,6 +836,8 @@ $code.=<<___;
.type	bn_scatter5,\@abi-omnipotent
.align	16
bn_scatter5:
	cmp	\$0, $num
	jz	.Lscatter_epilogue
	lea	($tbl,$idx,8),$tbl
.Lscatter:
	mov	($inp),%rax
@@ -844,6 +846,7 @@ bn_scatter5:
	lea	32*8($tbl),$tbl
	sub	\$1,$num
	jnz	.Lscatter
.Lscatter_epilogue:
	ret
.size	bn_scatter5,.-bn_scatter5
___
+18 −4
Original line number Diff line number Diff line
@@ -693,9 +693,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,

	if (!BN_copy(&computeTemp, am)) goto err;

	if (bn_wexpand(am,top)==NULL ||	bn_wexpand(r,top)==NULL)
		goto err;

#if defined(OPENSSL_BN_ASM_MONT5)
    /* This optimization uses ideas from http://eprint.iacr.org/2011/239,
     * specifically optimization of cache-timing attack countermeasures
@@ -717,6 +714,24 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
	bn_scatter5(am->d,am->top,powerbuf,1);

	acc = computeTemp.d;
	/* bn_mul_mont() and bn_mul_mont_gather5() assume fixed length inputs.
	 * Pad the inputs with zeroes.
	 */
	if (bn_wexpand(am,top)==NULL ||	bn_wexpand(r,top)==NULL ||
	    bn_wexpand(&computeTemp,top)==NULL)
		goto err;
	for (i = am->top; i < top; ++i)
		{
		am->d[i] = 0;
		}
	for (i = computeTemp.top; i < top; ++i)
		{
		computeTemp.d[i] = 0;
		}
	for (i = r->top; i < top; ++i)
		{
		r->d[i] = 0;
		}
#if 0
	for (i=2; i<32; i++)
		{
@@ -1102,4 +1117,3 @@ err:
	bn_check_top(r);
	return(ret);
	}
+77 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ int test_mod(BIO *bp,BN_CTX *ctx);
int test_mod_mul(BIO *bp,BN_CTX *ctx);
int test_mod_exp(BIO *bp,BN_CTX *ctx);
int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx);
int test_exp(BIO *bp,BN_CTX *ctx);
int test_gf2m_add(BIO *bp);
int test_gf2m_mod(BIO *bp);
@@ -249,6 +250,7 @@ int main(int argc, char *argv[])

	message(out,"BN_mod_exp_mont_consttime");
	if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
	if (!test_mod_exp_mont5(out,ctx)) goto err;
	(void)BIO_flush(out);

	message(out,"BN_exp");
@@ -1012,6 +1014,81 @@ int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
	return(1);
	}

/* Test constant-time modular exponentiation with 1024-bit inputs,
 * which on x86_64 cause a different code branch to be taken.
 */
int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM *a,*p,*m,*d,*e;
	int i;

	BN_MONT_CTX *mont;

	a=BN_new();
	p=BN_new();
	m=BN_new();
	d=BN_new();
	e=BN_new();

	mont = BN_MONT_CTX_new();

	BN_bntest_rand(m,1024,0,1); /* must be odd for montgomery */
	/* Zero exponent */
	BN_bntest_rand(a,1024,0,0);
	BN_zero(p);
	if(!BN_mod_exp_mont_consttime(d,a,p,m,ctx,NULL))
		return 0;
	if(!BN_is_one(d))
		{
		fprintf(stderr, "Modular exponentiation test failed!\n");
		return 0;
		}
	/* Zero input */
	BN_bntest_rand(p,1024,0,0);
	BN_zero(a);
	if(!BN_mod_exp_mont_consttime(d,a,p,m,ctx,NULL))
		return 0;
	if(!BN_is_zero(d))
		{
		fprintf(stderr, "Modular exponentiation test failed!\n");
		return 0;
		}
	/* Craft an input whose Montgomery representation is 1,
	 * i.e., shorter than the modulus m, in order to test
	 * the const time precomputation scattering/gathering.
	 */
	BN_one(a);
	BN_MONT_CTX_set(mont,m,ctx);
	if(!BN_from_montgomery(e,a,mont,ctx))
		return 0;
	if(!BN_mod_exp_mont_consttime(d,e,p,m,ctx,NULL))
		return 0;
	if(!BN_mod_exp_simple(a,e,p,m,ctx))
		return 0;
	if(BN_cmp(a,d) != 0)
		{
		fprintf(stderr,"Modular exponentiation test failed!\n");
		return 0;
		}
	/* Finally, some regular test vectors. */
	BN_bntest_rand(e,1024,0,0);
	if(!BN_mod_exp_mont_consttime(d,e,p,m,ctx,NULL))
		return 0;
	if(!BN_mod_exp_simple(a,e,p,m,ctx))
		return 0;
	if(BN_cmp(a,d) != 0)
		{
		fprintf(stderr,"Modular exponentiation test failed!\n");
		return 0;
		}
	BN_free(a);
	BN_free(p);
	BN_free(m);
	BN_free(d);
	BN_free(e);
	return(1);
	}

int test_exp(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM *a,*b,*d,*e,*one;