Pārlūkot izejas kodu

Merge pull request #678 from libtom/some-improvements

Steffen Jaeckel 10 mēneši atpakaļ
vecāks
revīzija
a81dab9970

+ 0 - 4
.ci/build.sh

@@ -69,7 +69,3 @@ if [ -a testok.txt ] && [ -f testok.txt ]; then
    exit 0
 fi
 exit 1
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 0 - 4
.ci/check_source.sh

@@ -9,7 +9,3 @@ echo "checking..."
 ./helper.pl --check-all || exit 1
 
 exit 0
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 0 - 4
.ci/clang-tidy.sh

@@ -45,7 +45,3 @@ portability-* -- -DUSE_LTM -DLTM_DESC -Isrc/headers -I../libtommath || { echo "c
 echo "clang-tidy ok"
 
 exit 0
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 0 - 4
.ci/coverage.sh

@@ -45,7 +45,3 @@ else
 fi
 
 exit 0
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 0 - 4
.ci/coverage_more.sh

@@ -22,7 +22,3 @@ fi
 
 
 exit 0
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 0 - 4
.ci/meta_builds.sh

@@ -110,7 +110,3 @@ echo
 echo "Build full debug..."
 
 make -j$MAKE_JOBS CFLAGS="$2 $CFLAGS $4" EXTRALIBS="$EXTRALIBS" all_test LTC_DEBUG=2 V=1 1>gcc_1.txt 2>gcc_2.txt
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 0 - 4
.ci/printinfo.sh

@@ -18,7 +18,3 @@ then
 fi
 echo "${CC}="`${CC} -dumpversion`
 echo
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 0 - 4
.ci/run.sh

@@ -43,7 +43,3 @@ else
 fi
 
 exit 0
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 0 - 4
.ci/testbuild.sh

@@ -20,7 +20,3 @@ if find testok.txt -type f 1>/dev/null 2>/dev/null ; then
    exit 0
 fi
 exit 1
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 0 - 4
.ci/valgrind.sh

@@ -41,7 +41,3 @@ readonly VALGRIND_EXTRA_OPTS=$(get_suppfile)
 valgrind $VALGRIND_OPTS $VALGRIND_EXTRA_OPTS ./test >test_std.txt 2> >(tee -a test_err.txt >&2) || { kill $alive_pid; echo "Valgrind failed"; exit 1; }
 
 kill $alive_pid
-
-# ref:         $Format:%D$
-# git commit:  $Format:%H$
-# commit time: $Format:%ai$

+ 18 - 24
demos/CMakeLists.txt

@@ -2,12 +2,14 @@
 # Options
 # -----------------------------------------------------------------------------
 option(BUILD_USEFUL_DEMOS "Build useful demos (hashsum)" FALSE)
-option(BUILD_USABLE_DEMOS "Build usable demos (crypt sizes constants pem-info)" FALSE)
-option(BUILD_BROKEN_DEMOS "Build broken demos (aesgcm openssh-privkey openssl-enc timing)" FALSE)
+option(
+    BUILD_USABLE_DEMOS
+    "Build usable demos (aesgcm constants crypt openssh-privkey openssl-enc pem-info sizes timing)"
+    FALSE
+)
 option(BUILD_TEST_DEMOS "Build test demos (small tv_gen)" FALSE)
 
 option(INSTALL_DEMOS "Install enabled demos (USEFUL and/or USABLE) and ltc wrapper script" FALSE)
-option(INSTALL_BROKEN_DEMOS "Install broken demos and ltc wrapper script" FALSE)
 
 # -----------------------------------------------------------------------------
 # Useful demos
@@ -26,30 +28,22 @@ endif()
 #
 # Demos that are usable but only rarely make sense to be installed
 #
-# USEABLE_DEMOS  = crypt sizes constants pem-info
+# USEABLE_DEMOS  = aesgcm constants crypt openssh-privkey openssl-enc pem-info sizes timing
 # -----------------------------------------------------------------------------
 
 if(BUILD_USABLE_DEMOS)
-    list(APPEND USABLE_DEMOS_TARGETS crypt sizes constants pem-info)
-endif()
-
-# -----------------------------------------------------------------------------
-# Broken demos
-#
-# Demos that are kind of useful, but in some way broken
-#
-# * aesgcm          - can't be built with LTC_EASY
-# * openssl-enc     - can't be built with LTC_EASY
-# * openssh-privkey - can't be built with LTC_EASY
-# * timing          - not really broken, but older gcc builds spit warnings
-#
-# BROKEN_DEMOS   = aesgcm openssl-enc openssh-privkey timing
-# -----------------------------------------------------------------------------
-
-if(BUILD_BROKEN_DEMOS AND INSTALL_BROKEN_DEMOS)
-    list(APPEND USABLE_DEMOS_TARGETS aesgcm openssh-privkey openssl-enc timing)
-elseif(BUILD_BROKEN_DEMOS)
-    list(APPEND ALL_DEMOS_TARGETS aesgcm openssh-privkey openssl-enc timing)
+    list(
+        APPEND
+        USABLE_DEMOS_TARGETS
+        aesgcm
+        constants
+        crypt
+        openssh-privkey
+        openssl-enc
+        pem-info
+        sizes
+        timing
+    )
 endif()
 
 # -----------------------------------------------------------------------------

+ 21 - 31
demos/aesgcm.c

@@ -16,10 +16,16 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <string.h>
-#include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 
+#ifndef LTC_GCM_MODE
+int main(void)
+{
+   return -1;
+}
+#else
+
 #include "gcm-file/gcm_filehandle.c"
 #include "gcm-file/gcm_file.c"
 
@@ -58,33 +64,7 @@ OUT:
    return 0;
 }
 
-/* https://stackoverflow.com/a/23898449 */
-static void scan_hex(const char* str, uint8_t* bytes, size_t blen)
-{
-   uint8_t  pos;
-   uint8_t  idx0;
-   uint8_t  idx1;
-
-   const uint8_t hashmap[] =
-   {
-     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */
-     0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */
-     0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* @ABCDEFG */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* HIJKLMNO */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* PQRSTUVW */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ[\]^_ */
-     0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* `abcdefg */
-   };
-
-   for (pos = 0; ((pos < (blen*2)) && (pos < XSTRLEN(str))); pos += 2)
-   {
-      idx0 = (uint8_t)(str[pos+0] & 0x1F) ^ 0x10;
-      idx1 = (uint8_t)(str[pos+1] & 0x1F) ^ 0x10;
-      bytes[pos/2] = (uint8_t)(hashmap[idx0] << 4) | hashmap[idx1];
-   }
-}
-
-static void die(int ret)
+static void LTC_NORETURN die(int ret)
 {
    fprintf(stderr, "Usage: aesgcm <-e|-d> <infile> <outfile> <88|96 char hex-string 'IV | key'>\n");
    exit(ret);
@@ -97,9 +77,14 @@ int main(int argc, char **argv)
    uint8_t keybuf[48] = {0};
    char *out = NULL;
    const char *mode, *in_file, *out_file, *key_string;
-   unsigned long ivlen;
+   unsigned long ivlen, key_len;
 
-   if (argc < 5) die(__LINE__);
+   if (argc < 5) {
+      if (argc > 1 && strstr(argv[1], "-h"))
+         die(0);
+      else
+         die(__LINE__);
+   }
 
    arg = 1;
    mode = argv[arg++];
@@ -116,7 +101,11 @@ int main(int argc, char **argv)
    keylen = XSTRLEN(key_string);
    if (keylen != 88 && keylen != 96) die(__LINE__);
 
-   scan_hex(key_string, keybuf, keylen/2);
+   key_len = sizeof(keybuf);
+   if ((err = base16_decode(key_string, keylen, keybuf, &key_len)) != CRYPT_OK) {
+      fprintf(stderr, "boooh %s\n", error_to_string(err));
+      die(__LINE__);
+   }
 
    register_all_ciphers();
 
@@ -148,3 +137,4 @@ cleanup:
 
    return ret;
 }
+#endif

+ 34 - 22
demos/crypt.c

@@ -12,17 +12,29 @@
 
 #include <tomcrypt.h>
 
-static int LTC_NORETURN usage(char *name)
+static int LTC_NORETURN die(int status)
 {
-   int x;
-
-   printf("Usage encrypt: %s cipher infile outfile\n", name);
-   printf("Usage decrypt: %s -d cipher infile outfile\n", name);
-   printf("Usage test:    %s -t cipher\nCiphers:\n", name);
+   int x, w, tot = 0;
+   FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
+   fprintf(o,
+           "Usage encrypt: crypt <cipher> <infile> <outfile>\n"
+           "Usage decrypt: crypt -d <cipher> <infile> <outfile>\n"
+           "Usage test:    crypt -t <cipher>\n"
+           "This help:     crypt -h\n\nCiphers:\n\t");
    for (x = 0; cipher_descriptor[x].name != NULL; x++) {
-      printf("%s\n",cipher_descriptor[x].name);
+      w = fprintf(o, "%-14s",cipher_descriptor[x].name);
+      if (w < 0) {
+         status = EXIT_FAILURE;
+         break;
+      }
+      tot += w;
+      if (tot >= 70) {
+         fprintf(o, "\n\t");
+         tot = 0;
+      }
    }
-   exit(1);
+   if (tot != 0) fprintf(o, "\n");
+   exit(status);
 }
 
 int main(int argc, char *argv[])
@@ -48,24 +60,24 @@ int main(int argc, char *argv[])
         cipher  = argv[2];
         cipher_idx = find_cipher(cipher);
         if (cipher_idx == -1) {
-          printf("Invalid cipher %s entered on command line.\n", cipher);
-          exit(-1);
+          fprintf(stderr, "Invalid cipher %s entered on command line.\n", cipher);
+          die(EXIT_FAILURE);
         } /* if */
-        if (cipher_descriptor[cipher_idx].test)
-        {
-          if (cipher_descriptor[cipher_idx].test() != CRYPT_OK)
-          {
-            printf("Error when testing cipher %s.\n", cipher);
-            exit(-1);
+        if (cipher_descriptor[cipher_idx].test) {
+          if (cipher_descriptor[cipher_idx].test() != CRYPT_OK) {
+            fprintf(stderr, "Error when testing cipher %s.\n", cipher);
+            die(EXIT_FAILURE);
           }
-          else
-          {
+          else {
             printf("Testing cipher %s succeeded.\n", cipher);
-            exit(0);
-          } /* if ... else */
-        } /* if */
+            exit(EXIT_SUCCESS);
+          }
+        } else {
+          fprintf(stderr, "Cipher %s has no tests.\n", cipher);
+          exit(EXIT_SUCCESS);
+        }
       }
-      return usage(argv[0]);
+      return die(argc > 1 && strstr(argv[1], "-h") != NULL ? EXIT_SUCCESS : EXIT_FAILURE);
    }
 
    if (!strcmp(argv[1], "-d")) {

+ 14 - 9
demos/hashsum.c

@@ -41,10 +41,17 @@ static void die(int status)
 {
    unsigned long w, x;
    FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
-   fprintf(o, "usage: %s -a algorithm [-c] [file...]\n\n", hashsum);
-   fprintf(o, "\t-c\tCheck the hash(es) of the file(s) written in [file].\n");
-   fprintf(o, "\t\t(-a not required)\n");
-   fprintf(o, "\nAlgorithms:\n\t");
+   fprintf(o,
+           "Usage: %s [-a <algorithm>...] [-c|-h] [<file>...]\n\n"
+           "\t-c\tCheck the hash(es) of the file(s) written in <file>.\n"
+           "\t\tNote: -a is not required when checking the hash(es).\n"
+           "\t-h\tThis help\n\n"
+           "Examples:\n"
+           "\t%s -a sha1 file > file.sha1sum\n"
+           "\t%s -c file.sha1sum\n"
+           "\t%s -a sha1 -a sha256 -a sha512-256 file > file.hashsum\n"
+           "\t%s -c file.hashsum\n\n"
+           "Algorithms:\n\t", hashsum, hashsum, hashsum, hashsum, hashsum);
    w = 0;
    for (x = 0; hash_descriptor[x].name != NULL; x++) {
       w += fprintf(o, "%-14s", hash_descriptor[x].name);
@@ -67,7 +74,7 @@ static void printf_hex(unsigned char* hash_buffer, unsigned long w)
 
 static void check_file(int argn, int argc, char **argv)
 {
-   int err, failed, invalid;
+   int err, failed = 0, invalid = 0;
    unsigned char is_buffer[MAXBLOCKSIZE], should_buffer[MAXBLOCKSIZE];
    char buf[PATH_MAX + (MAXBLOCKSIZE * 3)];
    /* iterate through all files */
@@ -82,8 +89,6 @@ static void check_file(int argn, int argc, char **argv)
             perror(argv[argn]);
          exit(EXIT_FAILURE);
       }
-      failed = 0;
-      invalid = 0;
       /* read the file line by line */
       while((s = fgets(buf, sizeof(buf), f)) != NULL)
       {
@@ -163,7 +168,7 @@ ERR:
       }
       argn++;
    }
-   exit(EXIT_SUCCESS);
+   exit(failed == 0 && invalid == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
 int main(int argc, char **argv)
@@ -178,7 +183,7 @@ int main(int argc, char **argv)
    /* You need to register algorithms before using them */
    register_all_ciphers();
    register_all_hashes();
-   if (argc > 1 && (strcmp("-h", argv[1]) == 0 || strcmp("--help", argv[1]) == 0)) {
+   if (argc > 1 && strstr(argv[1], "-h")) {
       die(EXIT_SUCCESS);
    }
    if (argc < 3) {

+ 83 - 56
demos/openssl-enc.c

@@ -24,8 +24,6 @@
  * - OpenSSL-compatible key derivation (in OpenSSL's modified PKCS#5v1 approach)
  * - Grabbing an Initialization Vector from the key generator
  * - Performing simple block encryption using AES
- * - PKCS#7-type padding (which hopefully can get ripped out of this demo and
- *   made a libtomcrypt thing someday).
  *
  * This program is free for all purposes without any express guarantee it
  * works. If you really want to see a license here, assume the WTFPL :-)
@@ -38,22 +36,14 @@
  */
 
 #include <tomcrypt.h>
+#include <termios.h>
 
-#ifndef LTC_RIJNDAEL
-#error Cannot compile this demo; Rijndael (AES) required
-#endif
-#ifndef LTC_CBC_MODE
-#error Cannot compile this demo; CBC mode required
-#endif
-#ifndef LTC_PKCS_5
-#error Cannot compile this demo; PKCS5 required
-#endif
-#ifndef LTC_RNG_GET_BYTES
-#error Cannot compile this demo; random generator required
-#endif
-#ifndef LTC_MD5
-#error Cannot compile this demo; MD5 required
-#endif
+#if !defined(LTC_RIJNDAEL) || !defined(LTC_CBC_MODE) || !defined(LTC_PKCS_5) || !defined(LTC_RNG_GET_BYTES) || !defined(LTC_MD5)
+int main(void)
+{
+   return -1;
+}
+#else
 
 /* OpenSSL by default only runs one hash round */
 #define OPENSSL_ITERATIONS 1
@@ -83,44 +73,33 @@ union paddable {
  * Output:       <no return>
  * Side Effects: print messages and barf (does exit(3))
  */
-void barf(const char *pname, const char *err)
+static void LTC_NORETURN barf(const char *pname, const char *err)
 {
-   printf("Usage: %s <enc|dec> infile outfile passphrase [salt]\n", pname);
-   printf("\n");
-   printf("       # encrypts infile->outfile, random salt\n");
-   printf("       %s enc infile outfile \"passphrase\"\n", pname);
-   printf("\n");
-   printf("       # encrypts infile->outfile, salt from cmdline\n");
-   printf("       %s enc infile outfile pass 0123456789abcdef\n", pname);
-   printf("\n");
-   printf("       # decrypts infile->outfile, pulls salt from infile\n");
-   printf("       %s dec infile outfile pass\n", pname);
-   printf("\n");
-   printf("       # decrypts infile->outfile, salt specified\n");
-   printf("       # (don't try to read the salt from infile)\n");
-   printf("       %s dec infile outfile pass 0123456789abcdef"
-          "\n", pname);
-   printf("\n");
-   printf("Application Error: %s\n", err);
+   FILE* o = err == NULL ? stdout : stderr;
+   fprintf(o,
+            "Usage: %s <enc|dec> infile outfile [passphrase | -] [salt]\n"
+            "\n"
+            "       The passphrase can either be given at the command line\n"
+            "       or if it's passed as '-' it will be read interactively.\n"
+            "\n"
+            "       # encrypts infile->outfile, random salt\n"
+            "       %s enc infile outfile pass\n"
+            "\n"
+            "       # encrypts infile->outfile, salt from cmdline\n"
+            "       %s enc infile outfile pass 0123456789abcdef\n"
+            "\n"
+            "       # decrypts infile->outfile, pulls salt from infile\n"
+            "       %s dec infile outfile pass\n"
+            "\n"
+            "       # decrypts infile->outfile, salt specified\n"
+            "       # (don't try to read the salt from infile)\n"
+            "       %s dec infile outfile pass 0123456789abcdef\n"
+            "\n"
+            "Application Error: %s\n", pname, pname, pname, pname, pname, err ? err : "None");
    if(errno)
-      perror("     System Error");
-   exit(-1);
-}
-
-/*
- * Parse a salt value passed in on the cmdline.
- *
- * Input:        string passed in and a buf to put it in (exactly 8 bytes!)
- * Output:       CRYPT_OK if parsed OK, CRYPT_ERROR if not
- * Side Effects: none
- */
-int parse_hex_salt(unsigned char *in, unsigned char *out)
-{
-   int idx;
-   for(idx=0; idx<SALT_LENGTH; idx++)
-      if(sscanf((char*)in+idx*2, "%02hhx", out+idx) != 1)
-         return CRYPT_ERROR;
-   return CRYPT_OK;
+      perror(
+            "     System Error");
+   exit(err == NULL ? 0 : -1);
 }
 
 /*
@@ -259,8 +238,39 @@ int do_crypt(FILE *infd, FILE *outfd, unsigned char *key, unsigned char *iv,
    return CRYPT_OK;
 }
 
+
+static char* getpassword(const char *prompt, size_t maxlen)
+{
+   char *wr, *end, *pass = XCALLOC(1, maxlen + 1);
+   struct termios tio;
+   tcflag_t c_lflag;
+   if (pass == NULL)
+      return NULL;
+   wr = pass;
+   end = pass + maxlen;
+
+   tcgetattr(0, &tio);
+   c_lflag = tio.c_lflag;
+   tio.c_lflag &= ~ECHO;
+   tcsetattr(0, TCSANOW, &tio);
+
+   printf("%s", prompt);
+   fflush(stdout);
+   while (pass < end) {
+      int c = getchar();
+      if (c == '\r' || c == '\n' || c == -1)
+         break;
+      *wr++ = c;
+   }
+   tio.c_lflag = c_lflag;
+   tcsetattr(0, TCSAFLUSH, &tio);
+   printf("\n");
+   return pass;
+}
+
 /* Convenience macro for the various barfable places below */
 #define BARF(a) { \
+   if(password) free(password); \
    if(infd) fclose(infd); \
    if(outfd) { fclose(outfd); remove(argv[3]); } \
    barf(argv[0], a); \
@@ -278,6 +288,12 @@ int main(int argc, char *argv[]) {
    unsigned char keyiv[KEY_LENGTH + IV_LENGTH];
    unsigned long keyivlen = (KEY_LENGTH + IV_LENGTH);
    unsigned char *key, *iv;
+   const void *pass;
+   char *password = NULL;
+   unsigned long saltlen = sizeof(salt);
+
+   if (argc > 1 && strstr(argv[1], "-h"))
+      barf(argv[0], NULL);
 
    /* Check proper number of cmdline args */
    if(argc < 5 || argc > 6)
@@ -302,9 +318,9 @@ int main(int argc, char *argv[]) {
    /* Get the salt from wherever */
    if(argc == 6) {
       /* User-provided */
-      if(parse_hex_salt((unsigned char*) argv[5], salt) != CRYPT_OK)
+      if(base16_decode(argv[5], strlen(argv[5]), salt, &saltlen) != CRYPT_OK)
          BARF("Bad user-specified salt");
-   } else if(!strncmp(argv[1], "enc", 3)) {
+   } else if(encrypt) {
       /* Encrypting; get from RNG */
       if(rng_get_bytes(salt, sizeof(salt), NULL) != sizeof(salt))
          BARF("Not enough random data");
@@ -324,9 +340,18 @@ int main(int argc, char *argv[]) {
    key = keyiv + 0;      /* key comes first */
    iv = keyiv + KEY_LENGTH;   /* iv comes next */
 
+   if (argv[4] && strcmp(argv[4], "-")) {
+      pass = argv[4];
+   } else {
+      password = getpassword("Enter password: ", 256);
+      if (!password)
+         BARF("Could not get password");
+      pass = password;
+   }
+
    /* Run the key derivation from the provided passphrase.  This gets us
       the key and iv. */
-   ret = pkcs_5_alg1_openssl((unsigned char*)argv[4], XSTRLEN(argv[4]), salt,
+   ret = pkcs_5_alg1_openssl(pass, XSTRLEN(pass), salt,
                              OPENSSL_ITERATIONS, hash, keyiv, &keyivlen );
    if(ret != CRYPT_OK)
       BARF("Could not derive key/iv from passphrase");
@@ -353,6 +378,8 @@ int main(int argc, char *argv[]) {
       BARF("Error during crypt operation");
 
    /* Clean up */
+   if(password) free(password);
    fclose(infd); fclose(outfd);
    return 0;
 }
+#endif

+ 15 - 1
demos/pem-info.c

@@ -69,9 +69,23 @@ static const char *s_map_mode(enum cipher_mode mode)
    exit(1);
 }
 
-int main(void)
+
+static void LTC_NORETURN die(int status)
+{
+   FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
+   fprintf(o,
+         "Usage: pem-info [<-h>]\n\n"
+         "Generate LaTeX tables from the supported PEM resp. SSH ciphers.\n\n"
+         "\t-h\tThe help you're looking at.\n"
+   );
+   exit(status);
+}
+
+int main(int argc, char **argv)
 {
    unsigned long n;
+   if (argc > 1 && strstr(argv[1], "-h"))
+      die(0);
    printf("PEM ciphers:\n\n");
    for (n = 0; n < pem_dek_infos_num; ++n) {
       char nbuf[32] = {0};

+ 44 - 17
demos/timing.c

@@ -1325,7 +1325,21 @@ static void time_encmacs(void)
    time_encmacs_(32);
 }
 
-#define LTC_TEST_FN(f)  { f, #f }
+static void LTC_NORETURN die(int status)
+{
+   FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
+   fprintf(o,
+         "Usage: timing [<-h|-l|alg>] [mpi]\n\n"
+         "Run timing tests of all built-in algorithms, or only the one given in <alg>.\n\n"
+         "\talg\tThe algorithm to test. Use the '-l' option to check for valid values.\n"
+         "\tmpi\tThe MPI provider to use.\n"
+         "\t-l\tList all built-in algorithms that can be timed.\n"
+         "\t-h\tThe help you're looking at.\n"
+   );
+   exit(status);
+}
+
+#define LTC_TEST_FN(f)  { time_ ## f, #f }
 int main(int argc, char **argv)
 {
 int err;
@@ -1335,26 +1349,37 @@ const struct
    void (*fn)(void);
    const char* name;
 } test_functions[] = {
-   LTC_TEST_FN(time_keysched),
-   LTC_TEST_FN(time_cipher_ecb),
-   LTC_TEST_FN(time_cipher_cbc),
-   LTC_TEST_FN(time_cipher_ctr),
-   LTC_TEST_FN(time_cipher_lrw),
-   LTC_TEST_FN(time_hash),
-   LTC_TEST_FN(time_macs),
-   LTC_TEST_FN(time_encmacs),
-   LTC_TEST_FN(time_prng),
-   LTC_TEST_FN(time_mult),
-   LTC_TEST_FN(time_sqr),
-   LTC_TEST_FN(time_rsa),
-   LTC_TEST_FN(time_dsa),
-   LTC_TEST_FN(time_ecc),
-   LTC_TEST_FN(time_dh),
+   LTC_TEST_FN(keysched),
+   LTC_TEST_FN(cipher_ecb),
+   LTC_TEST_FN(cipher_cbc),
+   LTC_TEST_FN(cipher_ctr),
+   LTC_TEST_FN(cipher_lrw),
+   LTC_TEST_FN(hash),
+   LTC_TEST_FN(macs),
+   LTC_TEST_FN(encmacs),
+   LTC_TEST_FN(prng),
+   LTC_TEST_FN(mult),
+   LTC_TEST_FN(sqr),
+   LTC_TEST_FN(rsa),
+   LTC_TEST_FN(dsa),
+   LTC_TEST_FN(ecc),
+   LTC_TEST_FN(dh),
 };
 char *single_test = NULL;
 unsigned int i;
 const char* mpi_provider = NULL;
 
+if (argc > 1) {
+   if (strstr(argv[1], "-h")) {
+      die(EXIT_SUCCESS);
+   } else if (strstr(argv[1], "-l")) {
+      for (i = 0; i < sizeof(test_functions)/sizeof(test_functions[0]); ++i) {
+         printf("%s\n", test_functions[i].name);
+      }
+      exit(0);
+   }
+}
+
 init_timer();
 register_all_ciphers();
 register_all_hashes();
@@ -1374,7 +1399,9 @@ register_all_prngs();
       mpi_provider = argv[2];
    }
 
-   crypt_mp_init(mpi_provider);
+   if (crypt_mp_init(mpi_provider) != CRYPT_OK) {
+      fprintf(stderr, "Init of MPI provider \"%s\" failed\n", mpi_provider ? mpi_provider : "(null)");
+   }
 
 if ((err = rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL)) != CRYPT_OK) {
    fprintf(stderr, "rng_make_prng failed: %s\n", error_to_string(err));

+ 21 - 2
demos/tv_gen.c

@@ -11,7 +11,8 @@ static void hash_gen(void)
 
    out = fopen("hash_tv.txt", "w");
    if (out == NULL) {
-      perror("can't open hash_tv");
+      perror("can't open hash_tv.txt");
+      return;
    }
 
    fprintf(out, "Hash Test Vectors:\n\nThese are the hashes of nn bytes '00 01 02 03 .. (nn-1)'\n\n");
@@ -766,8 +767,26 @@ static void lrw_gen(void)
 }
 #endif
 
-int main(void)
+static void LTC_NORETURN die(int status)
 {
+   FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
+   fprintf(o,
+         "Usage: tv_gen [<-h>]\n\n"
+         "Generate the internal test-vectors.\n\n"
+         "\t-h\tThe help you're looking at.\n"
+   );
+   exit(status);
+}
+
+int main(int argc, char **argv)
+{
+   if (argc > 1) {
+      if (strstr(argv[1], "-h")) {
+         die(EXIT_SUCCESS);
+      } else {
+         die(EXIT_FAILURE);
+      }
+   }
    register_all_ciphers();
    register_all_hashes();
    register_all_prngs();

+ 2 - 0
makefile

@@ -13,9 +13,11 @@ endif
 ifeq ($V,1)
 silent=
 silent_stdout=
+silent_stderr=
 else
 silent=@
 silent_stdout= > /dev/null
+silent_stderr= 2> /dev/null
 endif
 
 PLATFORM := $(shell uname | sed -e 's/_.*//')

+ 10 - 17
makefile_include.mk

@@ -55,13 +55,13 @@ endif
 
 ifndef EXTRALIBS
 ifneq ($(shell echo $(CFLAGS) | grep USE_LTM),)
-EXTRALIBS=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --libs libtommath)
-else
-ifneq ($(shell echo $(CFLAGS) | grep USE_TFM),)
-EXTRALIBS=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --libs tomsfastmath)
-endif
-endif
+EXTRALIBS=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --libs libtommath ${silent_stderr} || true)
+else ifneq ($(shell echo $(CFLAGS) | grep USE_TFM),)
+EXTRALIBS=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --libs tomsfastmath ${silent_stderr} || true)
+else ifneq ($(shell echo $(CFLAGS) | grep USE_GMP),)
+EXTRALIBS=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --libs gmp ${silent_stderr} || true)
 endif
+endif # EXTRALIBS
 
 need-help := $(filter help,$(MAKECMDGOALS))
 define print-help
@@ -77,13 +77,13 @@ endef
 #  make CFLAGS="-I./src/headers/ -DLTC_SOURCE ..." ...
 #
 ifneq ($(shell echo $(CFLAGS) | grep LTM_DESC),)
-LTC_CFLAGS+=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --cflags-only-I libtommath)
+LTC_CFLAGS+=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --cflags-only-I libtommath ${silent_stderr} || true)
 endif
 ifneq ($(shell echo $(CFLAGS) | grep TFM_DESC),)
-LTC_CFLAGS+=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --cflags-only-I tomsfastmath)
+LTC_CFLAGS+=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --cflags-only-I tomsfastmath ${silent_stderr} || true)
 endif
 ifneq ($(shell echo $(CFLAGS) | grep GMP_DESC),)
-LTC_CFLAGS+=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --cflags-only-I gmp)
+LTC_CFLAGS+=$(shell PKG_CONFIG_PATH=$(LIBPATH)/pkgconfig pkg-config --cflags-only-I gmp ${silent_stderr} || true)
 endif
 LTC_CFLAGS += -I./src/headers/ -DLTC_SOURCE -Wall -Wsign-compare -Wshadow
 
@@ -171,18 +171,11 @@ TEST=test
 USEFUL_DEMOS   = hashsum
 
 # Demos that are usable but only rarely make sense to be installed
-USEABLE_DEMOS  = crypt sizes constants pem-info
+USEABLE_DEMOS  = aesgcm constants crypt openssh-privkey openssl-enc pem-info sizes timing
 
 # Demos that are used for testing or measuring
 TEST_DEMOS     = small tv_gen
 
-# Demos that are in one config broken
-#  aesgcm          - can't be built with LTC_EASY
-#  openssl-enc     - can't be built with LTC_EASY
-#  openssh-privkey - can't be built with LTC_EASY
-#  timing          - not really broken, but older gcc builds spit warnings
-BROKEN_DEMOS   = aesgcm openssl-enc openssh-privkey timing
-
 # Combine demos in groups
 UNBROKEN_DEMOS = $(TEST_DEMOS) $(USEABLE_DEMOS) $(USEFUL_DEMOS)
 DEMOS          = $(UNBROKEN_DEMOS) $(BROKEN_DEMOS)

+ 4 - 0
src/headers/tomcrypt.h

@@ -75,6 +75,10 @@ enum {
    CRYPT_HASH_OVERFLOW,     /* Hash applied to too many bits */
    CRYPT_PW_CTX_MISSING,    /* Password context to decrypt key file is missing */
    CRYPT_UNKNOWN_PEM,       /* The PEM header was not recognized */
+
+   /* Here only follows the number of error codes.
+    * This will never be returned and shall always be at the end of the enum. */
+   CRYPT_ERR_NUM
 };
 
 #include "tomcrypt_cfg.h"

+ 3 - 0
src/headers/tomcrypt_cfg.h

@@ -91,6 +91,9 @@ LTC_EXPORT int   LTC_CALL XSTRCMP(const char *s1, const char *s2);
    #define ENDIAN_LITTLE
    #define ENDIAN_64BITWORD
    #define LTC_FAST
+   #if defined(_ILP32) || defined(__ILP32__)
+      #define ENDIAN_64BITWORD_X32
+   #endif
 #endif
 
 /* detect PPC32 */

+ 2 - 1
src/headers/tomcrypt_private.h

@@ -11,7 +11,8 @@
 
 #define LTC_PAD_MASK       (0xF000U)
 
-#if defined(ENDIAN_64BITWORD)
+/* only real 64bit, not x32 */
+#if defined(ENDIAN_64BITWORD) && !defined(ENDIAN_64BITWORD_X32)
    #define CONSTPTR(n) CONST64(n)
 #else
    #define CONSTPTR(n) n ## uL

+ 5 - 6
src/misc/error_to_string.c

@@ -8,7 +8,7 @@
   Convert error codes to ASCII strings, Tom St Denis
 */
 
-static const char * const err_2_str[] =
+static const char * const err_2_str[CRYPT_ERR_NUM] =
 {
    "CRYPT_OK",
    "CRYPT_ERROR",
@@ -44,19 +44,18 @@ static const char * const err_2_str[] =
 
    "The input was longer than expected.",
 
-   "Invalid sized parameter.",
+   "Invalid size input for PK parameters.",
 
    "Invalid size for prime.",
-
    "Invalid padding.",
 
    "Hash applied to too many bits.",
-
    "Password context to decrypt key file is missing.",
-
    "The PEM header was not recognized",
 };
 
+LTC_STATIC_ASSERT(correct_err_2_str_size, (sizeof(err_2_str)/sizeof(err_2_str[0])) == CRYPT_ERR_NUM)
+
 /**
    Convert an LTC error code to ASCII
    @param err    The error code
@@ -64,7 +63,7 @@ static const char * const err_2_str[] =
 */
 const char *error_to_string(int err)
 {
-   if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
+   if (err < 0 || err >= CRYPT_ERR_NUM) {
       return "Invalid error code.";
    }
    return err_2_str[err];

+ 1 - 1
tests/multi_test.c

@@ -15,7 +15,7 @@ int multi_test(void)
 
 /* HASH testing */
    len = sizeof(buf[0]);
-#if defined(ENDIAN_32BITWORD) || defined(_WIN32)
+#if defined(ENDIAN_32BITWORD) || defined(_WIN32) || defined(ENDIAN_64BITWORD_X32)
    len2 = 0x80000000UL;
 #else
    /* Check against the max. input limit of SHA-1 as of RFC8017 */