summary refs log tree commit diff stats
path: root/libotr/libgcrypt-1.8.7/tests/pkbench.c
diff options
context:
space:
mode:
authorSoniEx2 <endermoneymod@gmail.com>2021-04-09 07:19:03 -0300
committerSoniEx2 <endermoneymod@gmail.com>2021-04-09 07:19:03 -0300
commit0e752a6e215aee21dc73da097c3225495d54a5b6 (patch)
treeb81be02cbf2f06aebf322ac4a5d014b44176bba5 /libotr/libgcrypt-1.8.7/tests/pkbench.c
parent7754076c715285173311a1b6811ce377950e18a6 (diff)
Add libotr/etc sources
Diffstat (limited to 'libotr/libgcrypt-1.8.7/tests/pkbench.c')
-rw-r--r--libotr/libgcrypt-1.8.7/tests/pkbench.c485
1 files changed, 485 insertions, 0 deletions
diff --git a/libotr/libgcrypt-1.8.7/tests/pkbench.c b/libotr/libgcrypt-1.8.7/tests/pkbench.c
new file mode 100644
index 0000000..e458b42
--- /dev/null
+++ b/libotr/libgcrypt-1.8.7/tests/pkbench.c
@@ -0,0 +1,485 @@
+/* pkbench.c - Pubkey menchmarking
+ * Copyright (C) 2004, 2005, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <gcrypt.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#ifndef HAVE_W32_SYSTEM
+# include <sys/times.h>
+#endif /*HAVE_W32_SYSTEM*/
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+
+#define PGM "pkbench"
+#include "t-common.h"
+
+
+typedef struct context
+{
+  gcry_sexp_t key_secret;
+  gcry_sexp_t key_public;
+  gcry_sexp_t data;
+  gcry_sexp_t data_encrypted;
+  gcry_sexp_t data_signed;
+} *context_t;
+
+typedef int (*work_t) (context_t context, unsigned int final);
+
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+  char *buf;
+  size_t size;
+
+  fputs (prefix, stderr);
+  size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  buf = gcry_xmalloc (size);
+
+  gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+  fprintf (stderr, "%.*s", (int)size, buf);
+  gcry_free (buf);
+}
+
+
+static void *
+read_file (const char *fname, size_t *r_length)
+{
+  FILE *fp;
+  struct stat st;
+  char *buf;
+  size_t buflen;
+
+  fp = fopen (fname, "rb");
+  if (!fp)
+    {
+      fail ("can't open `%s': %s\n", fname, strerror (errno));
+      return NULL;
+    }
+
+  if (fstat (fileno(fp), &st))
+    {
+      fail ("can't stat `%s': %s\n", fname, strerror (errno));
+      fclose (fp);
+      return NULL;
+    }
+
+  buflen = st.st_size;
+  buf = gcry_xmalloc (buflen+1);
+  if (fread (buf, buflen, 1, fp) != 1)
+    {
+      fail ("error reading `%s': %s\n", fname, strerror (errno));
+      fclose (fp);
+      gcry_free (buf);
+      return NULL;
+    }
+  fclose (fp);
+
+  if (r_length)
+    *r_length = buflen;
+  return buf;
+}
+
+
+
+static void
+benchmark (work_t worker, context_t context)
+{
+  clock_t timer_start, timer_stop;
+  unsigned int loop = 10;
+  unsigned int i = 0;
+  struct tms timer;
+  int ret = 0;
+
+#ifdef HAVE_W32_SYSTEM
+  timer_start = clock ();
+#else
+  times (&timer);
+  timer_start = timer.tms_utime;
+#endif
+  for (i = 0; i < loop; i++)
+    {
+      ret = (*worker) (context, (i + 1) == loop);
+      if (! ret)
+	break;
+    }
+#ifdef HAVE_W32_SYSTEM
+  timer_stop = clock ();
+#else
+  times (&timer);
+  timer_stop = timer.tms_utime;
+#endif
+
+  if (ret)
+    printf ("%.0f ms\n",
+	    (((double) ((timer_stop - timer_start) / loop)) / CLOCKS_PER_SEC)
+	    * 10000000);
+  else
+    printf ("[skipped]\n");
+}
+
+static int
+work_encrypt (context_t context, unsigned int final)
+{
+  gcry_error_t err = GPG_ERR_NO_ERROR;
+  gcry_sexp_t data_encrypted = NULL;
+  int ret = 1;
+
+  err = gcry_pk_encrypt (&data_encrypted,
+			 context->data, context->key_public);
+  if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
+    {
+      err = GPG_ERR_NO_ERROR;
+      ret = 0;
+    }
+  else
+    {
+      assert (! err);
+
+      if (final)
+	context->data_encrypted = data_encrypted;
+      else
+	gcry_sexp_release (data_encrypted);
+    }
+
+  return ret;
+}
+
+static int
+work_decrypt (context_t context, unsigned int final)
+{
+  gcry_error_t err = GPG_ERR_NO_ERROR;
+  int ret = 1;
+
+  if (! context->data_encrypted)
+    ret = 0;
+  else
+    {
+      gcry_sexp_t data_decrypted = NULL;
+
+      err = gcry_pk_decrypt (&data_decrypted,
+			     context->data_encrypted,
+			     context->key_secret);
+      assert (! err);
+      if (final)
+	{
+	  gcry_sexp_release (context->data_encrypted);
+	  context->data_encrypted = NULL;
+	}
+      gcry_sexp_release (data_decrypted);
+    }
+
+  return ret;
+}
+
+static int
+work_sign (context_t context, unsigned int final)
+{
+  gcry_error_t err = GPG_ERR_NO_ERROR;
+  gcry_sexp_t data_signed = NULL;
+  int ret = 1;
+
+  err = gcry_pk_sign (&data_signed,
+		      context->data, context->key_secret);
+  if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
+    {
+      err = GPG_ERR_NO_ERROR;
+      ret = 0;
+    }
+  else if (err)
+    {
+      fail ("pk_sign failed: %s\n", gpg_strerror (err));
+      ret = 0;
+    }
+  else
+    {
+      if (final)
+	context->data_signed = data_signed;
+      else
+	gcry_sexp_release (data_signed);
+    }
+
+  return ret;
+}
+
+static int
+work_verify (context_t context, unsigned int final)
+{
+  gcry_error_t err = GPG_ERR_NO_ERROR;
+  int ret = 1;
+
+  if (!context->data_signed)
+    return 0;
+
+  err = gcry_pk_verify (context->data_signed,
+                        context->data,
+                        context->key_public);
+  if (err)
+    {
+      show_sexp ("data_signed:\n", context->data_signed);
+      show_sexp ("data:\n", context->data);
+      fail ("pk_verify failed: %s\n", gpg_strerror (err));
+      ret = 0;
+    }
+  else if (final)
+    {
+      gcry_sexp_release (context->data_signed);
+      context->data_signed = NULL;
+    }
+
+  return ret;
+}
+
+static void
+process_key_pair (context_t context)
+{
+  struct
+  {
+    work_t worker;
+    const char *identifier;
+  } worker_functions[] = { { work_encrypt, "encrypt" },
+			   { work_decrypt, "decrypt" },
+			   { work_sign,    "sign"    },
+			   { work_verify,  "verify"  } };
+  unsigned int i = 0;
+
+  for (i = 0; i < (sizeof (worker_functions) / sizeof (*worker_functions)); i++)
+    {
+      printf ("%s: ", worker_functions[i].identifier);
+      benchmark (worker_functions[i].worker, context);
+    }
+}
+
+static void
+context_init (context_t context, gcry_sexp_t key_secret, gcry_sexp_t key_public)
+{
+  gcry_error_t err = GPG_ERR_NO_ERROR;
+  unsigned int key_size = 0;
+  gcry_mpi_t data = NULL;
+  gcry_sexp_t data_sexp = NULL;
+
+  key_size = gcry_pk_get_nbits (key_secret);
+  assert (key_size);
+
+  data = gcry_mpi_new (key_size);
+  assert (data);
+
+  gcry_mpi_randomize (data, key_size, GCRY_STRONG_RANDOM);
+  gcry_mpi_clear_bit (data, key_size - 1);
+  err = gcry_sexp_build (&data_sexp, NULL,
+			 "(data (flags raw) (value %m))",
+			 data);
+  assert (! err);
+  gcry_mpi_release (data);
+
+  context->key_secret = key_secret;
+  context->key_public = key_public;
+  context->data = data_sexp;
+  context->data_encrypted = NULL;
+  context->data_signed = NULL;
+}
+
+static void
+context_destroy (context_t context)
+{
+  gcry_sexp_release (context->key_secret);
+  gcry_sexp_release (context->key_public);
+  gcry_sexp_release (context->data);
+}
+
+static void
+process_key_pair_file (const char *key_pair_file)
+{
+  gcry_error_t err = GPG_ERR_NO_ERROR;
+  void *key_pair_buffer = NULL;
+  gcry_sexp_t key_pair_sexp = NULL;
+  gcry_sexp_t key_secret_sexp = NULL;
+  gcry_sexp_t key_public_sexp = NULL;
+  struct context context = { NULL };
+  size_t file_length;
+
+  key_pair_buffer = read_file (key_pair_file, &file_length);
+  if (!key_pair_buffer)
+    die ("failed to open `%s'\n", key_pair_file);
+
+  err = gcry_sexp_sscan (&key_pair_sexp, NULL,
+			 key_pair_buffer, file_length);
+  if (err)
+    die ("gcry_sexp_sscan failed\n");
+
+  key_secret_sexp = gcry_sexp_find_token (key_pair_sexp, "private-key", 0);
+  assert (key_secret_sexp);
+  key_public_sexp = gcry_sexp_find_token (key_pair_sexp, "public-key", 0);
+  assert (key_public_sexp);
+
+  gcry_sexp_release (key_pair_sexp);
+
+  context_init (&context, key_secret_sexp, key_public_sexp);
+
+  printf ("Key file: %s\n", key_pair_file);
+  process_key_pair (&context);
+  printf ("\n");
+
+  context_destroy (&context);
+  gcry_free (key_pair_buffer);
+}
+
+
+static void
+generate_key (const char *algorithm, const char *key_size)
+{
+  gcry_error_t err = GPG_ERR_NO_ERROR;
+  size_t key_pair_buffer_size = 0;
+  char *key_pair_buffer = NULL;
+  gcry_sexp_t key_spec = NULL;
+  gcry_sexp_t key_pair = NULL;
+
+  if (isdigit ((unsigned int)*key_size))
+    err = gcry_sexp_build (&key_spec, NULL,
+                           "(genkey (%s (nbits %s)))",
+                           algorithm, key_size);
+  else
+    err = gcry_sexp_build (&key_spec, NULL,
+                           "(genkey (%s (curve %s)))",
+                           algorithm, key_size);
+  if (err)
+    die ("sexp_build failed: %s\n", gpg_strerror (err));
+
+  err = gcry_pk_genkey (&key_pair, key_spec);
+  if (err)
+    {
+      show_sexp ("request:\n", key_spec);
+      die ("pk_genkey failed: %s\n", gpg_strerror (err));
+    }
+
+  key_pair_buffer_size = gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED,
+					   NULL, 0);
+  key_pair_buffer = gcry_xmalloc (key_pair_buffer_size);
+
+  gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED,
+		    key_pair_buffer, key_pair_buffer_size);
+
+  printf ("%.*s", (int)key_pair_buffer_size, key_pair_buffer);
+  gcry_free (key_pair_buffer);
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+  int genkey_mode = 0;
+  int fips_mode = 0;
+
+  if (argc)
+    { argc--; argv++; }
+
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          puts ("Usage: " PGM " [OPTIONS] [FILES]\n"
+                "Various public key tests:\n\n"
+                "  Default is to process all given key files\n\n"
+                "  --genkey ALGONAME SIZE  Generate a public key\n"
+                "\n"
+                "  --verbose    enable extra informational output\n"
+                "  --debug      enable additional debug output\n"
+                "  --help       display this help and exit\n\n");
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose++;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose = debug = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--genkey"))
+        {
+          genkey_mode = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--fips"))
+        {
+          fips_mode = 1;
+          argc--; argv++;
+        }
+    }
+
+  xgcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+
+  if (fips_mode)
+    xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
+
+  xgcry_control (GCRYCTL_DISABLE_SECMEM);
+  if (!gcry_check_version (GCRYPT_VERSION))
+    {
+      fprintf (stderr, PGM ": version mismatch\n");
+      exit (1);
+    }
+
+  if (genkey_mode)
+    {
+      /* No valuable keys are create, so we can speed up our RNG. */
+      xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+    }
+  if (debug)
+    xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+  xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+
+  if (genkey_mode && argc == 2)
+    {
+      generate_key (argv[0], argv[1]);
+    }
+  else if (!genkey_mode && argc)
+    {
+      int i;
+
+      for (i = 0; i < argc; i++)
+	process_key_pair_file (argv[i]);
+    }
+  else
+    {
+      fprintf (stderr, "usage: " PGM
+               " [OPTIONS] [FILES] (try --help for more information)\n");
+      exit (1);
+    }
+
+  return error_count ? 1 : 0;
+}