#include <openssl/x509.h>
#include <openssl/err.h>
+#include "../crypto/bn/bn_lcl.h"
+
const int num0 = 100; /* number of tests */
const int num1 = 50; /* additional tests for some functions */
const int num2 = 5; /* number of tests for slow functions */
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);
int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
int test_kron(BIO *bp,BN_CTX *ctx);
int test_sqrt(BIO *bp,BN_CTX *ctx);
+int test_small_prime(BIO *bp,BN_CTX *ctx);
+int test_probable_prime_coprime(BIO *bp,BN_CTX *ctx);
int rand_neg(void);
static int results=0;
message(out,"BN_add");
if (!test_add(out)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_sub");
if (!test_sub(out)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_lshift1");
if (!test_lshift1(out)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_lshift (fixed)");
if (!test_lshift(out,ctx,BN_bin2bn(lst,sizeof(lst)-1,NULL)))
goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_lshift");
if (!test_lshift(out,ctx,NULL)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_rshift1");
if (!test_rshift1(out)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_rshift");
if (!test_rshift(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_sqr");
if (!test_sqr(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_mul");
if (!test_mul(out)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_div");
if (!test_div(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_div_word");
if (!test_div_word(out)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_div_recp");
if (!test_div_recp(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_mod");
if (!test_mod(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_mod_mul");
if (!test_mod_mul(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_mont");
if (!test_mont(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_mod_exp");
if (!test_mod_exp(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_mod_exp_mont_consttime");
if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
- BIO_flush(out);
+ if (!test_mod_exp_mont5(out,ctx)) goto err;
+ (void)BIO_flush(out);
message(out,"BN_exp");
if (!test_exp(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_kronecker");
if (!test_kron(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_mod_sqrt");
if (!test_sqrt(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
+
+ message(out,"Small prime generation");
+ if (!test_small_prime(out,ctx)) goto err;
+ (void)BIO_flush(out);
+#ifdef OPENSSL_SYS_WIN32
+ message(out,"Probable prime generation with coprimes disabled");
+#else
+ message(out,"Probable prime generation with coprimes");
+ if (!test_probable_prime_coprime(out,ctx)) goto err;
+#endif
+ (void)BIO_flush(out);
+
+#ifndef OPENSSL_NO_EC2M
message(out,"BN_GF2m_add");
if (!test_gf2m_add(out)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_GF2m_mod");
if (!test_gf2m_mod(out)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_GF2m_mod_mul");
if (!test_gf2m_mod_mul(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_GF2m_mod_sqr");
if (!test_gf2m_mod_sqr(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_GF2m_mod_inv");
if (!test_gf2m_mod_inv(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_GF2m_mod_div");
if (!test_gf2m_mod_div(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_GF2m_mod_exp");
if (!test_gf2m_mod_exp(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_GF2m_mod_sqrt");
if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
- BIO_flush(out);
+ (void)BIO_flush(out);
message(out,"BN_GF2m_mod_solve_quad");
if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
- BIO_flush(out);
-
+ (void)BIO_flush(out);
+#endif
BN_CTX_free(ctx);
BIO_free(out);
err:
BIO_puts(out,"1\n"); /* make sure the Perl script fed by bc notices
* the failure, see test_bn in test/Makefile.ssl*/
- BIO_flush(out);
+ (void)BIO_flush(out);
ERR_load_crypto_strings();
ERR_print_errors_fp(stderr);
EXIT(1);
BN_init(&n);
mont=BN_MONT_CTX_new();
+ if (mont == NULL)
+ return 0;
BN_bntest_rand(&a,100,0,0); /**/
BN_bntest_rand(&b,100,0,0); /**/
BN_bntest_rand(b,2+i,0,0); /**/
if (!BN_mod_exp(d,a,b,c,ctx))
- return(00);
+ return(0);
if (bp != NULL)
{
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;
+
+ 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;
BN_bntest_rand(a,20+i*5,0,0); /**/
BN_bntest_rand(b,2+i,0,0); /**/
- if (!BN_exp(d,a,b,ctx))
- return(00);
+ if (BN_exp(d,a,b,ctx) <= 0)
+ return(0);
if (bp != NULL)
{
BN_free(one);
return(1);
}
-
+#ifndef OPENSSL_NO_EC2M
int test_gf2m_add(BIO *bp)
{
BIGNUM a,b,c;
{
BIGNUM *a,*b[2],*c,*d,*e;
int i, j, ret = 0;
- unsigned int p0[] = {163,7,6,3,0};
- unsigned int p1[] = {193,15,0};
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
a=BN_new();
b[0]=BN_new();
{
BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
int i, j, ret = 0;
- unsigned int p0[] = {163,7,6,3,0};
- unsigned int p1[] = {193,15,0};
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
a=BN_new();
b[0]=BN_new();
{
BIGNUM *a,*b[2],*c,*d;
int i, j, ret = 0;
- unsigned int p0[] = {163,7,6,3,0};
- unsigned int p1[] = {193,15,0};
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
a=BN_new();
b[0]=BN_new();
{
BIGNUM *a,*b[2],*c,*d;
int i, j, ret = 0;
- unsigned int p0[] = {163,7,6,3,0};
- unsigned int p1[] = {193,15,0};
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
a=BN_new();
b[0]=BN_new();
{
BIGNUM *a,*b[2],*c,*d,*e,*f;
int i, j, ret = 0;
- unsigned int p0[] = {163,7,6,3,0};
- unsigned int p1[] = {193,15,0};
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
a=BN_new();
b[0]=BN_new();
{
BIGNUM *a,*b[2],*c,*d,*e,*f;
int i, j, ret = 0;
- unsigned int p0[] = {163,7,6,3,0};
- unsigned int p1[] = {193,15,0};
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
a=BN_new();
b[0]=BN_new();
{
BIGNUM *a,*b[2],*c,*d,*e,*f;
int i, j, ret = 0;
- unsigned int p0[] = {163,7,6,3,0};
- unsigned int p1[] = {193,15,0};
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
a=BN_new();
b[0]=BN_new();
{
BIGNUM *a,*b[2],*c,*d,*e;
int i, j, s = 0, t, ret = 0;
- unsigned int p0[] = {163,7,6,3,0};
- unsigned int p1[] = {193,15,0};
+ int p0[] = {163,7,6,3,0,-1};
+ int p1[] = {193,15,0,-1};
a=BN_new();
b[0]=BN_new();
BN_free(e);
return ret;
}
-
+#endif
static int genprime_cb(int p, int n, BN_GENCB *arg)
{
char c='*';
return ret;
}
+int test_small_prime(BIO *bp,BN_CTX *ctx)
+ {
+ static const int bits = 10;
+ int ret = 0;
+ BIGNUM r;
+
+ BN_init(&r);
+ if (!BN_generate_prime_ex(&r, bits, 0, NULL, NULL, NULL))
+ goto err;
+ if (BN_num_bits(&r) != bits)
+ {
+ BIO_printf(bp, "Expected %d bit prime, got %d bit number\n", bits, BN_num_bits(&r));
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ BN_clear(&r);
+ return ret;
+ }
+#ifndef OPENSSL_SYS_WIN32
+int test_probable_prime_coprime(BIO *bp, BN_CTX *ctx)
+ {
+ int i, j, ret = 0;
+ BIGNUM r;
+ BN_ULONG primes[5] = { 2, 3, 5, 7, 11 };
+
+ BN_init(&r);
+
+ for (i = 0; i < 1000; i++)
+ {
+ if (!bn_probable_prime_dh_coprime(&r, 1024, ctx)) goto err;
+
+ for (j = 0; j < 5; j++)
+ {
+ if (BN_mod_word(&r, primes[j]) == 0)
+ {
+ BIO_printf(bp, "Number generated is not coprime to %ld:\n", primes[j]);
+ BN_print_fp(stdout, &r);
+ BIO_printf(bp, "\n");
+ goto err;
+ }
+ }
+ }
+
+ ret = 1;
+
+err:
+ BN_clear(&r);
+ return ret;
+ }
+#endif
int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
{
BIGNUM *a,*b,*c,*d;