summaryrefslogtreecommitdiffstats
path: root/comm/third_party/libgcrypt/tests/t-convert.c
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/libgcrypt/tests/t-convert.c')
-rw-r--r--comm/third_party/libgcrypt/tests/t-convert.c534
1 files changed, 534 insertions, 0 deletions
diff --git a/comm/third_party/libgcrypt/tests/t-convert.c b/comm/third_party/libgcrypt/tests/t-convert.c
new file mode 100644
index 0000000000..4450a9e3fe
--- /dev/null
+++ b/comm/third_party/libgcrypt/tests/t-convert.c
@@ -0,0 +1,534 @@
+/* t-convert.c - Tests for mpi print and scna functions
+ * Copyright (C) 2013 g10 Code GmbH
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#define PGM "t-convert"
+#include "t-common.h"
+
+
+static void
+showhex (const char *prefix, const void *buffer, size_t buflen)
+{
+ const unsigned char *s;
+
+ if (!verbose)
+ return;
+ fprintf (stderr, "%s: %s ", PGM, prefix);
+ for (s= buffer; buflen; buflen--, s++)
+ fprintf (stderr, "%02x", *s);
+ putc ('\n', stderr);
+}
+
+
+/* Allocate a bit string consisting of '0' and '1' from the MPI A. Do
+ not return any leading zero bits. Caller needs to gcry_free the
+ result. */
+static char *
+mpi2bitstr_nlz (gcry_mpi_t a)
+{
+ char *p, *buf;
+ size_t length = gcry_mpi_get_nbits (a);
+
+ if (!length)
+ {
+ buf = p = xmalloc (3);
+ *p++ = ' ';
+ *p++ = '0';
+ }
+ else
+ {
+ buf = p = xmalloc (length + 1 + 1);
+ *p++ = gcry_mpi_is_neg (a)? '-':' ';
+ while (length-- > 1)
+ *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
+ *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0';
+ }
+ *p = 0;
+ return buf;
+}
+
+
+static void
+showmpi (const char *prefix, gcry_mpi_t a)
+{
+ char *bitstr;
+
+ if (!verbose)
+ return;
+ bitstr = mpi2bitstr_nlz (a);
+ fprintf (stderr, "%s: %s%s\n", PGM, prefix, bitstr);
+ xfree (bitstr);
+}
+
+
+/* Check that mpi_print does not return a negative zero. */
+static void
+negative_zero (void)
+{
+ gpg_error_t err;
+ gcry_mpi_t a;
+ char *buf;
+ void *bufaddr = &buf;
+ struct { const char *name; enum gcry_mpi_format format; } fmts[] =
+ {
+ { "STD", GCRYMPI_FMT_STD },
+ { "PGP", GCRYMPI_FMT_PGP },
+ { "SSH", GCRYMPI_FMT_SSH },
+ { "HEX", GCRYMPI_FMT_HEX },
+ { "USG", GCRYMPI_FMT_USG },
+ { NULL, 0 }
+ };
+ int i;
+
+ if (debug)
+ info ("negative zero printing\n");
+
+ a = gcry_mpi_new (0);
+ for (i=0; fmts[i].name; i++)
+ {
+ err = gcry_mpi_aprint (fmts[i].format, bufaddr, NULL, a);
+ if (err)
+ fail ("error printing a zero as %s: %s\n",
+ fmts[i].name,gpg_strerror (err) );
+ else
+ gcry_free (buf);
+ }
+
+ /* With the current version of libgcrypt the next two statements
+ should set a to -0. */
+ gcry_mpi_sub_ui (a, a, 1);
+ gcry_mpi_add_ui (a, a, 1);
+
+ for (i=0; fmts[i].name; i++)
+ {
+ err = gcry_mpi_aprint (fmts[i].format, bufaddr, NULL, a);
+ if (err)
+ fail ("error printing a negative zero as %s: %s\n",
+ fmts[i].name,gpg_strerror (err) );
+ else
+ gcry_free (buf);
+ }
+
+ gcry_mpi_release (a);
+}
+
+
+static void
+check_formats (void)
+{
+ static struct {
+ int value;
+ struct {
+ const char *hex;
+ size_t stdlen;
+ const char *std;
+ size_t sshlen;
+ const char *ssh;
+ size_t usglen;
+ const char *usg;
+ size_t pgplen;
+ const char *pgp;
+ } a;
+ } data[] = {
+ { 0, { "00",
+ 0, "",
+ 4, "\x00\x00\x00\x00",
+ 0, "",
+ 2, "\x00\x00"}
+ },
+ { 1, { "01",
+ 1, "\x01",
+ 5, "\x00\x00\x00\x01\x01",
+ 1, "\x01",
+ 3, "\x00\x01\x01" }
+ },
+ { 2, { "02",
+ 1, "\x02",
+ 5, "\x00\x00\x00\x01\x02",
+ 1, "\x02",
+ 3, "\x00\x02\x02" }
+ },
+ { 127, { "7F",
+ 1, "\x7f",
+ 5, "\x00\x00\x00\x01\x7f",
+ 1, "\x7f",
+ 3, "\x00\x07\x7f" }
+ },
+ { 128, { "0080",
+ 2, "\x00\x80",
+ 6, "\x00\x00\x00\x02\x00\x80",
+ 1, "\x80",
+ 3, "\x00\x08\x80" }
+ },
+ { 129, { "0081",
+ 2, "\x00\x81",
+ 6, "\x00\x00\x00\x02\x00\x81",
+ 1, "\x81",
+ 3, "\x00\x08\x81" }
+ },
+ { 255, { "00FF",
+ 2, "\x00\xff",
+ 6, "\x00\x00\x00\x02\x00\xff",
+ 1, "\xff",
+ 3, "\x00\x08\xff" }
+ },
+ { 256, { "0100",
+ 2, "\x01\x00",
+ 6, "\x00\x00\x00\x02\x01\x00",
+ 2, "\x01\x00",
+ 4, "\x00\x09\x01\x00" }
+ },
+ { 257, { "0101",
+ 2, "\x01\x01",
+ 6, "\x00\x00\x00\x02\x01\x01",
+ 2, "\x01\x01",
+ 4, "\x00\x09\x01\x01" }
+ },
+ { -1, { "-01",
+ 1, "\xff",
+ 5, "\x00\x00\x00\x01\xff",
+ 1,"\x01" }
+ },
+ { -2, { "-02",
+ 1, "\xfe",
+ 5, "\x00\x00\x00\x01\xfe",
+ 1, "\x02" }
+ },
+ { -127, { "-7F",
+ 1, "\x81",
+ 5, "\x00\x00\x00\x01\x81",
+ 1, "\x7f" }
+ },
+ { -128, { "-0080",
+ 1, "\x80",
+ 5, "\x00\x00\x00\x01\x80",
+ 1, "\x80" }
+ },
+ { -129, { "-0081",
+ 2, "\xff\x7f",
+ 6, "\x00\x00\x00\x02\xff\x7f",
+ 1, "\x81" }
+ },
+ { -255, { "-00FF",
+ 2, "\xff\x01",
+ 6, "\x00\x00\x00\x02\xff\x01",
+ 1, "\xff" }
+ },
+ { -256, { "-0100",
+ 2, "\xff\x00",
+ 6, "\x00\x00\x00\x02\xff\x00",
+ 2, "\x01\x00" }
+ },
+ { -257, { "-0101",
+ 2, "\xfe\xff",
+ 6, "\x00\x00\x00\x02\xfe\xff",
+ 2, "\x01\x01" }
+ },
+ { 65535, { "00FFFF",
+ 3, "\x00\xff\xff",
+ 7, "\x00\x00\x00\x03\x00\xff\xff",
+ 2, "\xff\xff",
+ 4, "\x00\x10\xff\xff" }
+ },
+ { 65536, { "010000",
+ 3, "\x01\00\x00",
+ 7, "\x00\x00\x00\x03\x01\x00\x00",
+ 3, "\x01\x00\x00",
+ 5, "\x00\x11\x01\x00\x00 "}
+ },
+ { 65537, { "010001",
+ 3, "\x01\00\x01",
+ 7, "\x00\x00\x00\x03\x01\x00\x01",
+ 3, "\x01\x00\x01",
+ 5, "\x00\x11\x01\x00\x01" }
+ },
+ { -65537, { "-010001",
+ 3, "\xfe\xff\xff",
+ 7, "\x00\x00\x00\x03\xfe\xff\xff",
+ 3, "\x01\x00\x01" }
+ },
+ { -65536, { "-010000",
+ 3, "\xff\x00\x00",
+ 7, "\x00\x00\x00\x03\xff\x00\x00",
+ 3, "\x01\x00\x00" }
+ },
+ { -65535, { "-00FFFF",
+ 3, "\xff\x00\x01",
+ 7, "\x00\x00\x00\x03\xff\x00\x01",
+ 2, "\xff\xff" }
+ }
+ };
+ gpg_error_t err;
+ gcry_mpi_t a, b;
+ char *buf;
+ void *bufaddr = &buf;
+ int idx;
+ size_t buflen;
+
+ a = gcry_mpi_new (0);
+ for (idx=0; idx < DIM(data); idx++)
+ {
+ if (debug)
+ info ("print test %d\n", data[idx].value);
+
+ if (data[idx].value < 0)
+ {
+ gcry_mpi_set_ui (a, -data[idx].value);
+ gcry_mpi_neg (a, a);
+ }
+ else
+ gcry_mpi_set_ui (a, data[idx].value);
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+ if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "HEX", gpg_strerror (err));
+ else
+ {
+ if (strcmp (buf, data[idx].a.hex))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "HEX", "wrong result");
+ info ("expected: '%s'\n", data[idx].a.hex);
+ info (" got: '%s'\n", buf);
+ }
+ gcry_free (buf);
+ }
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_STD, bufaddr, &buflen, a);
+ if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "STD", gpg_strerror (err));
+ else
+ {
+ if (buflen != data[idx].a.stdlen
+ || memcmp (buf, data[idx].a.std, data[idx].a.stdlen))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "STD", "wrong result");
+ showhex ("expected:", data[idx].a.std, data[idx].a.stdlen);
+ showhex (" got:", buf, buflen);
+ }
+ gcry_free (buf);
+ }
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_SSH, bufaddr, &buflen, a);
+ if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "SSH", gpg_strerror (err));
+ else
+ {
+ if (buflen != data[idx].a.sshlen
+ || memcmp (buf, data[idx].a.ssh, data[idx].a.sshlen))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "SSH", "wrong result");
+ showhex ("expected:", data[idx].a.ssh, data[idx].a.sshlen);
+ showhex (" got:", buf, buflen);
+ }
+ gcry_free (buf);
+ }
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufaddr, &buflen, a);
+ if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "USG", gpg_strerror (err));
+ else
+ {
+ if (buflen != data[idx].a.usglen
+ || memcmp (buf, data[idx].a.usg, data[idx].a.usglen))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "USG", "wrong result");
+ showhex ("expected:", data[idx].a.usg, data[idx].a.usglen);
+ showhex (" got:", buf, buflen);
+ }
+ gcry_free (buf);
+ }
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_PGP, bufaddr, &buflen, a);
+ if (gcry_mpi_is_neg (a))
+ {
+ if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "PGP", "Expected error not returned");
+ }
+ else if (err)
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "PGP", gpg_strerror (err));
+ else
+ {
+ if (buflen != data[idx].a.pgplen
+ || memcmp (buf, data[idx].a.pgp, data[idx].a.pgplen))
+ {
+ fail ("error printing value %d as %s: %s\n",
+ data[idx].value, "PGP", "wrong result");
+ showhex ("expected:", data[idx].a.pgp, data[idx].a.pgplen);
+ showhex (" got:", buf, buflen);
+ }
+ gcry_free (buf);
+ }
+ }
+
+
+ /* Now for the other direction. */
+ for (idx=0; idx < DIM(data); idx++)
+ {
+ if (debug)
+ info ("scan test %d\n", data[idx].value);
+
+ if (data[idx].value < 0)
+ {
+ gcry_mpi_set_ui (a, -data[idx].value);
+ gcry_mpi_neg (a, a);
+ }
+ else
+ gcry_mpi_set_ui (a, data[idx].value);
+
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_HEX, data[idx].a.hex, 0, &buflen);
+ if (err)
+ fail ("error scanning value %d from %s: %s\n",
+ data[idx].value, "HEX", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_cmp (a, b))
+ {
+ fail ("error scanning value %d from %s: %s\n",
+ data[idx].value, "HEX", "wrong result");
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_STD,
+ data[idx].a.std, data[idx].a.stdlen, &buflen);
+ if (err)
+ fail ("error scanning value %d as %s: %s\n",
+ data[idx].value, "STD", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_cmp (a, b) || data[idx].a.stdlen != buflen)
+ {
+ fail ("error scanning value %d from %s: %s (%lu)\n",
+ data[idx].value, "STD", "wrong result",
+ (long unsigned int)buflen);
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_SSH,
+ data[idx].a.ssh, data[idx].a.sshlen, &buflen);
+ if (err)
+ fail ("error scanning value %d as %s: %s\n",
+ data[idx].value, "SSH", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_cmp (a, b) || data[idx].a.sshlen != buflen)
+ {
+ fail ("error scanning value %d from %s: %s (%lu)\n",
+ data[idx].value, "SSH", "wrong result",
+ (long unsigned int)buflen);
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_USG,
+ data[idx].a.usg, data[idx].a.usglen, &buflen);
+ if (err)
+ fail ("error scanning value %d as %s: %s\n",
+ data[idx].value, "USG", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_is_neg (a))
+ gcry_mpi_neg (b, b);
+ if (gcry_mpi_cmp (a, b) || data[idx].a.usglen != buflen)
+ {
+ fail ("error scanning value %d from %s: %s (%lu)\n",
+ data[idx].value, "USG", "wrong result",
+ (long unsigned int)buflen);
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+
+ /* Negative values are not supported by PGP, thus we don't have
+ an samples. */
+ if (!gcry_mpi_is_neg (a))
+ {
+ err = gcry_mpi_scan (&b, GCRYMPI_FMT_PGP,
+ data[idx].a.pgp, data[idx].a.pgplen, &buflen);
+ if (err)
+ fail ("error scanning value %d as %s: %s\n",
+ data[idx].value, "PGP", gpg_strerror (err));
+ else
+ {
+ if (gcry_mpi_cmp (a, b) || data[idx].a.pgplen != buflen)
+ {
+ fail ("error scanning value %d from %s: %s (%lu)\n",
+ data[idx].value, "PGP", "wrong result",
+ (long unsigned int)buflen);
+ showmpi ("expected:", a);
+ showmpi (" got:", b);
+ }
+ gcry_mpi_release (b);
+ }
+ }
+ }
+
+ gcry_mpi_release (a);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0));
+ xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0));
+ if (debug)
+ xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0));
+ xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0));
+
+ negative_zero ();
+ check_formats ();
+
+ info ("All tests completed. Errors: %d\n", error_count);
+ return error_count ? 1 : 0;
+}