diff --git a/tests/t-convert.c b/tests/t-convert.c index ec566777..121039c7 100644 --- a/tests/t-convert.c +++ b/tests/t-convert.c @@ -1,530 +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 . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #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", buflen); + 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", buflen); + 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", buflen); + 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", buflen); + 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; } diff --git a/tests/t-ed25519.c b/tests/t-ed25519.c index 2f59a890..73628a81 100644 --- a/tests/t-ed25519.c +++ b/tests/t-ed25519.c @@ -1,497 +1,497 @@ /* t-ed25519.c - Check the Ed25519 crypto * 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 . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include "stopwatch.h" #define PGM "t-ed25519" #include "t-common.h" #define N_TESTS 1026 static int sign_with_pk; static int no_verify; static int custom_data_file; static void show_note (const char *format, ...) { va_list arg_ptr; if (!verbose && getenv ("srcdir")) fputs (" ", stderr); /* To align above "PASS: ". */ else fprintf (stderr, "%s: ", PGM); va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); if (*format && format[strlen(format)-1] != '\n') putc ('\n', stderr); va_end (arg_ptr); } static void show_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; fprintf (stderr, "%s: ", PGM); if (prefix) fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = xmalloc (size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); gcry_free (buf); } /* Prepend FNAME with the srcdir environment variable's value and - retrun an allocated filename. */ + * return an allocated filename. */ char * prepend_srcdir (const char *fname) { static const char *srcdir; char *result; if (!srcdir && !(srcdir = getenv ("srcdir"))) srcdir = "."; result = xmalloc (strlen (srcdir) + 1 + strlen (fname) + 1); strcpy (result, srcdir); strcat (result, "/"); strcat (result, fname); return result; } /* Read next line but skip over empty and comment lines. Caller must xfree the result. */ static char * read_textline (FILE *fp, int *lineno) { char line[4096]; char *p; do { if (!fgets (line, sizeof line, fp)) { if (feof (fp)) return NULL; die ("error reading input line: %s\n", strerror (errno)); } ++*lineno; p = strchr (line, '\n'); if (!p) die ("input line %d not terminated or too long\n", *lineno); *p = 0; for (p--;p > line && my_isascii (*p) && isspace (*p); p--) *p = 0; } while (!*line || *line == '#'); /* if (debug) */ /* info ("read line: '%s'\n", line); */ return xstrdup (line); } /* Copy the data after the tag to BUFFER. BUFFER will be allocated as needed. */ static void copy_data (char **buffer, const char *line, int lineno) { const char *s; xfree (*buffer); *buffer = NULL; s = strchr (line, ':'); if (!s) { fail ("syntax error at input line %d", lineno); return; } for (s++; my_isascii (*s) && isspace (*s); s++) ; *buffer = xstrdup (s); } /* Convert STRING consisting of hex characters into its binary representation and return it as an allocated buffer. The valid length of the buffer is returned at R_LENGTH. The string is delimited by end of string. The function returns NULL on error. */ static void * hex2buffer (const char *string, size_t *r_length) { const char *s; unsigned char *buffer; size_t length; buffer = xmalloc (strlen(string)/2+1); length = 0; for (s=string; *s; s +=2 ) { if (!hexdigitp (s) || !hexdigitp (s+1)) return NULL; /* Invalid hex digits. */ ((unsigned char*)buffer)[length++] = xtoi_2 (s); } *r_length = length; return buffer; } static void hexdowncase (char *string) { char *p; for (p=string; *p; p++) if (my_isascii (*p)) *p = tolower (*p); } static void one_test (int testno, const char *sk, const char *pk, const char *msg, const char *sig) { gpg_error_t err; int i; char *p; void *buffer = NULL; void *buffer2 = NULL; size_t buflen, buflen2; gcry_sexp_t s_tmp, s_tmp2; gcry_sexp_t s_sk = NULL; gcry_sexp_t s_pk = NULL; gcry_sexp_t s_msg= NULL; gcry_sexp_t s_sig= NULL; unsigned char *sig_r = NULL; unsigned char *sig_s = NULL; char *sig_rs_string = NULL; size_t sig_r_len, sig_s_len; if (verbose > 1) info ("Running test %d\n", testno); if (!(buffer = hex2buffer (sk, &buflen))) { fail ("error building s-exp for test %d, %s: %s", testno, "sk", "invalid hex string"); goto leave; } if (!(buffer2 = hex2buffer (pk, &buflen2))) { fail ("error building s-exp for test %d, %s: %s", testno, "pk", "invalid hex string"); goto leave; } if (sign_with_pk) err = gcry_sexp_build (&s_sk, NULL, "(private-key" " (ecc" " (curve \"Ed25519\")" " (flags eddsa)" " (q %b)" " (d %b)))", (int)buflen2, buffer2, (int)buflen, buffer); else err = gcry_sexp_build (&s_sk, NULL, "(private-key" " (ecc" " (curve \"Ed25519\")" " (flags eddsa)" " (d %b)))", (int)buflen, buffer); if (err) { fail ("error building s-exp for test %d, %s: %s", testno, "sk", gpg_strerror (err)); goto leave; } if ((err = gcry_sexp_build (&s_pk, NULL, "(public-key" " (ecc" " (curve \"Ed25519\")" " (flags eddsa)" " (q %b)))", (int)buflen2, buffer2))) { fail ("error building s-exp for test %d, %s: %s", testno, "pk", gpg_strerror (err)); goto leave; } xfree (buffer); if (!(buffer = hex2buffer (msg, &buflen))) { fail ("error building s-exp for test %d, %s: %s", testno, "msg", "invalid hex string"); goto leave; } if ((err = gcry_sexp_build (&s_msg, NULL, "(data" " (flags eddsa)" " (hash-algo sha512)" " (value %b))", (int)buflen, buffer))) { fail ("error building s-exp for test %d, %s: %s", testno, "msg", gpg_strerror (err)); goto leave; } if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); if (debug) show_sexp ("sig=", s_sig); s_tmp2 = NULL; s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0); if (s_tmp) { s_tmp2 = s_tmp; s_tmp = gcry_sexp_find_token (s_tmp2, "eddsa", 0); if (s_tmp) { gcry_sexp_release (s_tmp2); s_tmp2 = s_tmp; s_tmp = gcry_sexp_find_token (s_tmp2, "r", 0); if (s_tmp) { sig_r = gcry_sexp_nth_buffer (s_tmp, 1, &sig_r_len); gcry_sexp_release (s_tmp); } s_tmp = gcry_sexp_find_token (s_tmp2, "s", 0); if (s_tmp) { sig_s = gcry_sexp_nth_buffer (s_tmp, 1, &sig_s_len); gcry_sexp_release (s_tmp); } } } gcry_sexp_release (s_tmp2); s_tmp2 = NULL; if (!sig_r || !sig_s) fail ("gcry_pk_sign failed for test %d: %s", testno, "r or s missing"); else { sig_rs_string = xmalloc (2*(sig_r_len + sig_s_len)+1); p = sig_rs_string; *p = 0; for (i=0; i < sig_r_len; i++, p += 2) snprintf (p, 3, "%02x", sig_r[i]); for (i=0; i < sig_s_len; i++, p += 2) snprintf (p, 3, "%02x", sig_s[i]); if (strcmp (sig_rs_string, sig)) { fail ("gcry_pk_sign failed for test %d: %s", testno, "wrong value returned"); info (" expected: '%s'", sig); info (" got: '%s'", sig_rs_string); } } if (!no_verify) if ((err = gcry_pk_verify (s_sig, s_msg, s_pk))) fail ("gcry_pk_verify failed for test %d: %s", testno, gpg_strerror (err)); leave: gcry_sexp_release (s_sig); gcry_sexp_release (s_sk); gcry_sexp_release (s_pk); gcry_sexp_release (s_msg); xfree (buffer); xfree (buffer2); xfree (sig_r); xfree (sig_s); xfree (sig_rs_string); } static void check_ed25519 (const char *fname) { FILE *fp; int lineno, ntests; char *line; int testno; char *sk, *pk, *msg, *sig; info ("Checking Ed25519.\n"); fp = fopen (fname, "r"); if (!fp) die ("error opening '%s': %s\n", fname, strerror (errno)); testno = 0; sk = pk = msg = sig = NULL; lineno = ntests = 0; while ((line = read_textline (fp, &lineno))) { if (!strncmp (line, "TST:", 4)) testno = atoi (line+4); else if (!strncmp (line, "SK:", 3)) copy_data (&sk, line, lineno); else if (!strncmp (line, "PK:", 3)) copy_data (&pk, line, lineno); else if (!strncmp (line, "MSG:", 4)) copy_data (&msg, line, lineno); else if (!strncmp (line, "SIG:", 4)) copy_data (&sig, line, lineno); else fail ("unknown tag at input line %d", lineno); xfree (line); if (testno && sk && pk && msg && sig) { hexdowncase (sig); one_test (testno, sk, pk, msg, sig); ntests++; if (!(ntests % 256)) show_note ("%d of %d tests done\n", ntests, N_TESTS); xfree (pk); pk = NULL; xfree (sk); sk = NULL; xfree (msg); msg = NULL; xfree (sig); sig = NULL; } } xfree (pk); xfree (sk); xfree (msg); xfree (sig); if (ntests != N_TESTS && !custom_data_file) fail ("did %d tests but expected %d", ntests, N_TESTS); else if ((ntests % 256)) show_note ("%d tests done\n", ntests); fclose (fp); } int main (int argc, char **argv) { int last_argc = -1; char *fname = NULL; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--help")) { fputs ("usage: " PGM " [options]\n" "Options:\n" " --verbose print timings etc.\n" " --debug flyswatter\n" " --sign-with-pk also use the public key for signing\n" " --no-verify skip the verify test\n" " --data FNAME take test data from file FNAME\n", stdout); exit (0); } else if (!strcmp (*argv, "--verbose")) { verbose++; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { verbose += 2; debug++; argc--; argv++; } else if (!strcmp (*argv, "--sign-with-pk")) { sign_with_pk = 1; argc--; argv++; } else if (!strcmp (*argv, "--no-verify")) { no_verify = 1; argc--; argv++; } else if (!strcmp (*argv, "--data")) { argc--; argv++; if (argc) { xfree (fname); fname = xstrdup (*argv); argc--; argv++; } } else if (!strncmp (*argv, "--", 2)) die ("unknown option '%s'", *argv); } if (!fname) fname = prepend_srcdir ("t-ed25519.inp"); else custom_data_file = 1; xgcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); if (debug) xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); /* Ed25519 isn't supported in fips mode */ if (gcry_fips_mode_active()) return 77; start_timer (); check_ed25519 (fname); stop_timer (); xfree (fname); info ("All tests completed in %s. Errors: %d\n", elapsed_time (1), error_count); return !!error_count; }