mpi/ec: fix when 'unsigned long' is 32-bit but limb size is 64-bit
[libgcrypt.git] / tests / t-secmem.c
index b464d02..baf013d 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <unistd.h>
 
-#define PGMNAME "t-secmem"
+#define PGM "t-secmem"
 
 #include "t-common.h"
 #include "../src/gcrypt-testapi.h"
 
 
+#define DEFAULT_PAGE_SIZE 4096
+#define MINIMUM_POOL_SIZE 16384
+static size_t pool_size;
+static size_t chunk_size;
+
 static void
 test_secmem (void)
 {
@@ -42,12 +48,12 @@ test_secmem (void)
   memset (a, 0, sizeof a);
 
   /* Allocating 28*512=14k should work in the default 16k pool even
-   * with extrem alignment requirements.  */
+   * with extra alignment requirements.  */
   for (i=0; i < DIM(a); i++)
-    a[i] = gcry_xmalloc_secure (512);
+    a[i] = gcry_xmalloc_secure (chunk_size);
 
   /* Allocating another 2k should fail for the default 16k pool.  */
-  b = gcry_malloc_secure (2048);
+  b = gcry_malloc_secure (chunk_size*4);
   if (b)
     fail ("allocation did not fail as expected\n");
 
@@ -57,6 +63,31 @@ test_secmem (void)
 }
 
 
+static void
+test_secmem_overflow (void)
+{
+  void *a[150];
+  int i;
+
+  memset (a, 0, sizeof a);
+
+  /* Allocating 150*512=75k should require more than one overflow buffer.  */
+  for (i=0; i < DIM(a); i++)
+    {
+      a[i] = gcry_xmalloc_secure (chunk_size);
+      if (verbose && !(i %40))
+        xgcry_control (GCRYCTL_DUMP_SECMEM_STATS, 0 , 0);
+    }
+
+  if (debug)
+    xgcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
+  if (verbose)
+    xgcry_control (GCRYCTL_DUMP_SECMEM_STATS, 0 , 0);
+  for (i=0; i < DIM(a); i++)
+    xfree (a[i]);
+}
+
+
 /* This function is called when we ran out of core and there is no way
  * to return that error to the caller (xmalloc or mpi allocation).  */
 static int
@@ -72,7 +103,7 @@ outofcore_handler (void *opaque, size_t req_n, unsigned int flags)
   been_here = 1;
 
   info ("outofcore handler invoked");
-  gcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
+  xgcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
   fail ("out of core%s while allocating %lu bytes",
        (flags & 1)?" in secure memory":"", (unsigned long)req_n);
 
@@ -86,6 +117,20 @@ int
 main (int argc, char **argv)
 {
   int last_argc = -1;
+  long int pgsize_val = -1;
+  size_t pgsize;
+
+#if HAVE_MMAP
+# if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+  pgsize_val = sysconf (_SC_PAGESIZE);
+# elif defined(HAVE_GETPAGESIZE)
+  pgsize_val = getpagesize ();
+# endif
+#endif
+  pgsize = (pgsize_val > 0)? pgsize_val : DEFAULT_PAGE_SIZE;
+
+  pool_size = (MINIMUM_POOL_SIZE + pgsize - 1) & ~(pgsize - 1);
+  chunk_size = pool_size / 32;
 
   if (argc)
     { argc--; argv++; }
@@ -100,7 +145,7 @@ main (int argc, char **argv)
         }
       else if (!strcmp (*argv, "--help"))
         {
-          fputs ("usage: " PGMNAME " [options]\n"
+          fputs ("usage: " PGM " [options]\n"
                  "Options:\n"
                  "  --verbose       print timings etc.\n"
                  "  --debug         flyswatter\n"
@@ -126,16 +171,31 @@ main (int argc, char **argv)
     die ("version mismatch; pgm=%s, library=%s\n",
          GCRYPT_VERSION, gcry_check_version (NULL));
   if (debug)
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
-  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
-  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+    xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+  xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  xgcry_control (GCRYCTL_INIT_SECMEM, pool_size, 0);
   gcry_set_outofcore_handler (outofcore_handler, NULL);
-  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+  xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+  /* Libgcrypt prints a warning when the first overflow is allocated;
+   * we do not want to see that.  */
+  if (!verbose)
+    xgcry_control (GCRYCTL_DISABLE_SECMEM_WARN, 0);
+
 
   test_secmem ();
+  test_secmem_overflow ();
+  /* FIXME: We need to improve the tests, for example by registering
+   * our own log handler and comparing the output of
+   * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern.  */
 
   if (verbose)
-    gcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
-  info ("All tests completed.  Errors: %d\n", errorcount);
-  return !!errorcount;
+    {
+      xgcry_control (PRIV_CTL_DUMP_SECMEM_STATS, 0 , 0);
+      xgcry_control (GCRYCTL_DUMP_SECMEM_STATS, 0 , 0);
+    }
+
+  info ("All tests completed.  Errors: %d\n", error_count);
+  xgcry_control (GCRYCTL_TERM_SECMEM, 0 , 0);
+  return !!error_count;
 }