If memory debugging enabled return error on leaks.
[openssl.git] / test / exptest.c
index 97b74d9..5cd79e2 100644 (file)
@@ -1,4 +1,3 @@
-/* crypto/bn/exptest.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 #include <openssl/rand.h>
 #include <openssl/err.h>
 
 #include <openssl/rand.h>
 #include <openssl/err.h>
 
-#define NUM_BITS        (BN_BITS*2)
+#define NUM_BITS        (BN_BITS2 * 4)
 
 static const char rnd_seed[] =
     "string to make the random number generator think it has entropy";
 
 
 static const char rnd_seed[] =
     "string to make the random number generator think it has entropy";
 
+/*
+ * Test that r == 0 in test_exp_mod_zero(). Returns one on success,
+ * returns zero and prints debug output otherwise.
+ */
+static int a_is_zero_mod_one(const char *method, const BIGNUM *r,
+                             const BIGNUM *a) {
+    if (!BN_is_zero(r)) {
+        fprintf(stderr, "%s failed:\n", method);
+        fprintf(stderr, "a ** 0 mod 1 = r (should be 0)\n");
+        fprintf(stderr, "a = ");
+        BN_print_fp(stderr, a);
+        fprintf(stderr, "\nr = ");
+        BN_print_fp(stderr, r);
+        fprintf(stderr, "\n");
+        return 0;
+    }
+    return 1;
+}
+
 /*
  * test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success.
  */
 /*
  * test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success.
  */
@@ -79,8 +97,9 @@ static int test_exp_mod_zero()
 {
     BIGNUM *a = NULL, *p = NULL, *m = NULL;
     BIGNUM *r = NULL;
 {
     BIGNUM *a = NULL, *p = NULL, *m = NULL;
     BIGNUM *r = NULL;
+    BN_ULONG one_word = 1;
     BN_CTX *ctx = BN_CTX_new();
     BN_CTX *ctx = BN_CTX_new();
-    int ret = 1;
+    int ret = 1, failed = 0;
 
     m = BN_new();
     if (!m)
 
     m = BN_new();
     if (!m)
@@ -100,22 +119,65 @@ static int test_exp_mod_zero()
     r = BN_new();
     if (!r)
         goto err;
     r = BN_new();
     if (!r)
         goto err;
-    BN_mod_exp(r, a, p, m, ctx);
-    BN_CTX_free(ctx);
 
 
-    if (BN_is_zero(r))
-        ret = 0;
-    else {
-        printf("1**0 mod 1 = ");
-        BN_print_fp(stdout, r);
-        printf(", should be 0\n");
+    if (!BN_rand(a, 1024, 0, 0))
+        goto err;
+
+    if (!BN_mod_exp(r, a, p, m, ctx))
+        goto err;
+
+    if (!a_is_zero_mod_one("BN_mod_exp", r, a))
+        failed = 1;
+
+    if (!BN_mod_exp_recp(r, a, p, m, ctx))
+        goto err;
+
+    if (!a_is_zero_mod_one("BN_mod_exp_recp", r, a))
+        failed = 1;
+
+    if (!BN_mod_exp_simple(r, a, p, m, ctx))
+        goto err;
+
+    if (!a_is_zero_mod_one("BN_mod_exp_simple", r, a))
+        failed = 1;
+
+    if (!BN_mod_exp_mont(r, a, p, m, ctx, NULL))
+        goto err;
+
+    if (!a_is_zero_mod_one("BN_mod_exp_mont", r, a))
+        failed = 1;
+
+    if (!BN_mod_exp_mont_consttime(r, a, p, m, ctx, NULL)) {
+        goto err;
     }
 
     }
 
+    if (!a_is_zero_mod_one("BN_mod_exp_mont_consttime", r, a))
+        failed = 1;
+
+    /*
+     * A different codepath exists for single word multiplication
+     * in non-constant-time only.
+     */
+    if (!BN_mod_exp_mont_word(r, one_word, p, m, ctx, NULL))
+        goto err;
+
+    if (!BN_is_zero(r)) {
+        fprintf(stderr, "BN_mod_exp_mont_word failed:\n");
+        fprintf(stderr, "1 ** 0 mod 1 = r (should be 0)\n");
+        fprintf(stderr, "r = ");
+        BN_print_fp(stderr, r);
+        fprintf(stderr, "\n");
+        return 0;
+    }
+
+    ret = failed;
+
  err:
     BN_free(r);
     BN_free(a);
     BN_free(p);
     BN_free(m);
  err:
     BN_free(r);
     BN_free(a);
     BN_free(p);
     BN_free(m);
+    BN_CTX_free(ctx);
 
     return ret;
 }
 
     return ret;
 }
@@ -237,7 +299,10 @@ int main(int argc, char *argv[])
     BN_free(m);
     BN_CTX_free(ctx);
     ERR_remove_thread_state(NULL);
     BN_free(m);
     BN_CTX_free(ctx);
     ERR_remove_thread_state(NULL);
-    CRYPTO_mem_leaks(out);
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    if (CRYPTO_mem_leaks(out) <= 0)
+        goto err;
+#endif
     BIO_free(out);
     printf("\n");
 
     BIO_free(out);
     printf("\n");