summaryrefslogtreecommitdiff
path: root/libtomcrypt/demos
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2018-02-09 21:44:05 +0800
committerMatt Johnston <matt@ucc.asn.au>2018-02-09 21:44:05 +0800
commit82ce1e2bdeb6ca01a0fca49be7e5ab609f5e088f (patch)
treed4be3a9369f274cccf02931239a4898830f8c032 /libtomcrypt/demos
parentea980c648234da9c6925dac0a27f33ed01cb79d3 (diff)
downloaddropbear-82ce1e2bdeb6ca01a0fca49be7e5ab609f5e088f.tar.gz
Update to libtomcrypt 1.18.1, merged with Dropbear changes
Diffstat (limited to 'libtomcrypt/demos')
-rw-r--r--libtomcrypt/demos/constants.c86
-rw-r--r--libtomcrypt/demos/demo_dynamic.py309
-rw-r--r--libtomcrypt/demos/hashsum.c333
-rw-r--r--libtomcrypt/demos/ltcrypt.c205
-rw-r--r--libtomcrypt/demos/openssl-enc.c397
-rw-r--r--libtomcrypt/demos/sizes.c79
-rw-r--r--libtomcrypt/demos/small.c14
-rw-r--r--libtomcrypt/demos/timing.c1478
-rw-r--r--libtomcrypt/demos/tv_gen.c346
9 files changed, 2977 insertions, 270 deletions
diff --git a/libtomcrypt/demos/constants.c b/libtomcrypt/demos/constants.c
new file mode 100644
index 0000000..f747eb5
--- /dev/null
+++ b/libtomcrypt/demos/constants.c
@@ -0,0 +1,86 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt.h"
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
+#include <libgen.h>
+#else
+#define basename(x) x
+#endif
+
+/**
+ @file demo_crypt_constants.c
+
+ Demo how to get various constants to dynamic languages
+ like Python
+
+ Larry Bugbee, February 2013
+*/
+
+static void _print_line(const char* cmd, const char* desc)
+{
+ printf(" %-16s - %s\n", cmd, desc);
+}
+
+int main(int argc, char **argv)
+{
+ if (argc == 1) {
+ /* given a specific constant name, get and print its value */
+ char name[] = "CTR_COUNTER_BIG_ENDIAN";
+ int value;
+ char *names_list;
+ unsigned int names_list_len;
+
+ if (crypt_get_constant(name, &value) != 0) exit(EXIT_FAILURE);
+ printf("\n %s is %d \n\n", name, value);
+
+ /* get and print the length of the names (and values) list */
+
+ if (crypt_list_all_constants(NULL, &names_list_len) != 0) exit(EXIT_FAILURE);
+ printf(" need to allocate %u bytes \n\n", names_list_len);
+
+ /* get and print the names (and values) list */
+ if ((names_list = malloc(names_list_len)) == NULL) exit(EXIT_FAILURE);
+ if (crypt_list_all_constants(names_list, &names_list_len) != 0) exit(EXIT_FAILURE);
+ printf(" supported constants:\n\n%s\n\n", names_list);
+ free(names_list);
+ } else if (argc == 2) {
+ if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
+ char* base = strdup(basename(argv[0]));
+ printf("Usage: %s [-a] [-s name]\n\n", base);
+ _print_line("<no argument>", "The old behavior of the demo");
+ _print_line("-a", "Only lists all constants");
+ _print_line("-s name", "List a single constant given as argument");
+ _print_line("-h", "The help you're looking at");
+ free(base);
+ } else if (strcmp(argv[1], "-a") == 0) {
+ char *names_list;
+ unsigned int names_list_len;
+ /* get and print the length of the names (and values) list */
+ if (crypt_list_all_constants(NULL, &names_list_len) != 0) exit(EXIT_FAILURE);
+ /* get and print the names (and values) list */
+ names_list = malloc(names_list_len);
+ if (crypt_list_all_constants(names_list, &names_list_len) != 0) exit(EXIT_FAILURE);
+ printf("%s\n", names_list);
+ }
+ } else if (argc == 3) {
+ if (strcmp(argv[1], "-s") == 0) {
+ int value;
+ if (crypt_get_constant(argv[2], &value) != 0) exit(EXIT_FAILURE);
+ printf("%s,%u\n", argv[2], value);
+ }
+ }
+
+ return 0;
+}
+
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/demos/demo_dynamic.py b/libtomcrypt/demos/demo_dynamic.py
new file mode 100644
index 0000000..a0699e4
--- /dev/null
+++ b/libtomcrypt/demos/demo_dynamic.py
@@ -0,0 +1,309 @@
+
+
+"""
+ demo_dynamic.py v2b
+
+ This program demonstrates Python's use of the dynamic
+ language support additions to LTC, namely access to LTC
+ constants, struct and union sizes, and the binding of a
+ math package to LTC. Also provided are simple code
+ fragments to illustrate how one might write a Python
+ wrapper for LTC and how an app might call the wrapper.
+ This or a similar model should work for Ruby and other
+ dynamic languages.
+
+ This instance uses Python's ctypes and requires a single
+ .dylib linking together LTC and a math library. Building
+ a single .dylib is needed because LTC wants a fairly tight
+ relationship between itself and the mathlib. (ctypes can
+ load multiple .dylibs, but it does not support this level
+ of tight coupling between otherwise independent libraries.)
+
+ My .dylib was created on OSX/macOS with the following:
+ sudo make -j5 -f makefile.shared \
+ CFLAGS="-DUSE_TFM -DTFM_DESC -I/usr/local/include" \
+ EXTRALIBS=/usr/local/lib/libtfm.a install
+
+ For python 2.7.12 on Ubuntu Xenial the following worked for
+ me (without MPI support):
+ sudo make -f makefile.shared install PREFIX="/usr"
+
+ Reminder: you don't need to bind in a math library unless
+ you are going to use LTC functions that need a
+ mathlib. For example, public key crypto requires
+ a mathlib; hashing and symmetric encryption do not.
+
+ ------
+
+ This code was originally written for Python 2.7 with the
+ ctypes standard library. This version is modified to run
+ under both Python 2.7 and 3.6.
+
+ Arguably the biggest change for Python3 has to do with
+ strings. Under Python2, native strings are ASCII bytes and
+ passing them to LTC is natural and requires no conversion.
+ Under Python3 all native strings are Unicode which requires
+ they be converted to bytes before use by LTC.
+
+ Note the following for Python3.
+ - ASCII keys, IVs and other string arguments must be
+ 'bytes'. Define them with a 'b' prefix or convert
+ via the 'bytes()' function.
+ - "strings" returned from LTC are bytes and conversion
+ to Unicode might be necessary for proper printing.
+ If so, use <string>.decode('utf-8').
+ - The Python2 'print' statement becomes a function in
+ Python3 which requires parenthesis, eg. 'print()'.
+
+ NB: Unicode is achieved under Python2 by either defining
+ a Unicode string with a 'u' prefix or passing ASCII
+ strings thru the 'unicode()' function.
+
+ Larry Bugbee
+ March 2014 v1
+ August 2017 v2b
+
+"""
+
+
+import sys
+from ctypes import *
+from ctypes.util import find_library
+
+# switches to enable/disable selected output
+SHOW_ALL_CONSTANTS = True
+SHOW_ALL_SIZES = True
+SHOW_SELECTED_CONSTANTS = True
+SHOW_SELECTED_SIZES = True
+SHOW_BUILD_OPTIONS_ALGS = True
+SHOW_SHA256_EXAMPLE = True
+SHOW_CHACHA_EXAMPLE = True
+
+print(' ')
+print(' demo_dynamic.py')
+
+def inprint(s, indent=0):
+ "prints strings indented, including multline strings"
+ for line in s.split('\n'):
+ print(' '*indent + line)
+
+#-------------------------------------------------------------------------------
+# load the .dylib
+
+libname = 'tomcrypt'
+libpath = find_library(libname)
+print(' ')
+print(' path to library %s: %s' % (libname, libpath))
+
+LTC = cdll.LoadLibrary(libpath)
+print(' loaded: %s' % LTC)
+print(' ')
+
+
+#-------------------------------------------------------------------------------
+# get list of all supported constants followed by a list of all
+# supported sizes. One alternative: these lists may be parsed
+# and used as needed.
+
+if SHOW_ALL_CONSTANTS:
+ print('-'*60)
+ print(' all supported constants and their values:')
+
+ # get size to allocate for constants output list
+ str_len = c_int(0)
+ ret = LTC.crypt_list_all_constants(None, byref(str_len))
+ print(' need to allocate %d bytes to build list \n' % str_len.value)
+
+ # allocate that size and get (name, size) pairs, each pair
+ # separated by a newline char.
+ names_sizes = c_buffer(str_len.value)
+ ret = LTC.crypt_list_all_constants(names_sizes, byref(str_len))
+ print(names_sizes.value.decode("utf-8"))
+ print(' ')
+
+
+if SHOW_ALL_SIZES:
+ print('-'*60)
+ print(' all supported sizes:')
+
+ # get size to allocate for sizes output list
+ str_len = c_int(0)
+ ret = LTC.crypt_list_all_sizes(None, byref(str_len))
+ print(' need to allocate %d bytes to build list \n' % str_len.value)
+
+ # allocate that size and get (name, size) pairs, each pair
+ # separated by a newline char.
+ names_sizes = c_buffer(str_len.value)
+ ret = LTC.crypt_list_all_sizes(names_sizes, byref(str_len))
+ print(names_sizes.value.decode("utf-8"))
+ print(' ')
+
+
+#-------------------------------------------------------------------------------
+# get individually named constants and sizes
+
+if SHOW_SELECTED_CONSTANTS:
+ print('-'*60)
+ print('\n selected constants:')
+
+ names = [
+ b'ENDIAN_LITTLE',
+ b'ENDIAN_64BITWORD',
+ b'PK_PUBLIC',
+ b'LTC_MILLER_RABIN_REPS',
+ b'CTR_COUNTER_BIG_ENDIAN',
+ ]
+ for name in names:
+ const_value = c_int(0)
+ rc = LTC.crypt_get_constant(name, byref(const_value))
+ value = const_value.value
+ print(' %-25s %d' % (name.decode("utf-8"), value))
+ print(' ')
+
+if SHOW_SELECTED_SIZES:
+ print('-'*60)
+ print('\n selected sizes:')
+
+ names = [
+ b'rijndael_key',
+ b'rsa_key',
+ b'symmetric_CTR',
+ b'twofish_key',
+ b'ecc_point',
+ b'gcm_state',
+ b'sha512_state',
+ ]
+ for name in names:
+ size_value = c_int(0)
+ rc = LTC.crypt_get_size(name, byref(size_value))
+ value = size_value.value
+ print(' %-25s %d' % (name.decode("utf-8"), value))
+ print(' ')
+
+
+#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+# LibTomCrypt exposes one interesting string that can be accessed
+# via Python's ctypes module, "crypt_build_settings", which
+# provides a list of this build's compiler switches and supported
+# algorithms. If someday LTC exposes other interesting strings,
+# they can be found with:
+# nm /usr/local/lib/libtomcrypt.dylib | grep " D "
+
+def get_named_string(lib, name):
+ return c_char_p.in_dll(lib, name).value.decode("utf-8")
+
+if SHOW_BUILD_OPTIONS_ALGS:
+ print('-'*60)
+ print('This is a string compiled into LTC showing compile')
+ print('options and algorithms supported by this build \n')
+# print(get_named_string(LTC, 'crypt_build_settings'))
+ inprint(get_named_string(LTC, 'crypt_build_settings'), 4)
+
+
+#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+# here is an example of how Python code can be written to access
+# LTC's implementation of SHA256 and ChaCha,
+
+# - - - - - - - - - - - - -
+# definitions
+
+from binascii import hexlify, unhexlify
+
+def _err2str(err):
+ # define return type
+ errstr = LTC.error_to_string
+ errstr.restype = c_char_p
+ # get and return err string
+ return errstr(err)
+
+def _get_size(name):
+ size = c_int(0)
+ rc = LTC.crypt_get_size(bytes(name), byref(size))
+ if rc != 0:
+ raise Exception('LTC.crypt_get_size(%s) rc = %d' % (name, rc))
+ return size.value
+
+def _get_constant(name):
+ constant = c_int(0)
+ rc = LTC.crypt_get_constant(bytes(name), byref(constant))
+ if rc != 0:
+ raise Exception('LTC.crypt_get_constant(%s) rc = %d' % (name, rc))
+ return constant.value
+
+CRYPT_OK = _get_constant(b'CRYPT_OK')
+
+class SHA256(object):
+ def __init__(self):
+ self.state = c_buffer(_get_size(b'sha256_state'))
+ LTC.sha256_init(byref(self.state))
+ def update(self, data):
+ LTC.sha256_process(byref(self.state), data, len(data))
+ def digest(self):
+ md = c_buffer(32)
+ LTC.sha256_done(byref(self.state), byref(md))
+ return md.raw
+
+class ChaCha(object):
+ def __init__(self, key, rounds):
+ self.state = c_buffer(_get_size(b'chacha_state'))
+ self.counter = c_int(1)
+ err = LTC.chacha_setup(byref(self.state), key, len(key), rounds)
+ if err != CRYPT_OK:
+ raise Exception('LTC.chacha_setup(), err = %d, "%s"' % (err, _err2str(err)))
+ def set_iv32(self, iv):
+ err = LTC.chacha_ivctr32(byref(self.state), iv, len(iv), byref(self.counter))
+ if err != CRYPT_OK:
+ raise Exception('LTC.chacha_ivctr32(), err = %d, "%s"' % (err, _err2str(err)))
+ def crypt(self, datain):
+ dataout = c_buffer(len(datain))
+ err = LTC.chacha_crypt(byref(self.state), datain, len(datain), byref(dataout))
+ if err != CRYPT_OK:
+ raise Exception('LTC.chacha_crypt(), err = %d, "%s"' % (err, _err2str(err)))
+ return dataout.raw
+
+# - - - - - - - - - - - - -
+# a SHA256 app fragment
+
+if SHOW_SHA256_EXAMPLE:
+ print('-'*60)
+ data = b'hello world' # we want bytes, not Unicode
+
+ sha256 = SHA256()
+ sha256.update(data)
+ md = sha256.digest()
+
+ template = '\n the SHA256 digest for "%s" is %s \n'
+ print(template % (data, hexlify(md)))
+
+# - - - - - - - - - - - - -
+# a ChaCha app fragment
+
+if SHOW_CHACHA_EXAMPLE:
+ print('-'*60)
+ key = b'hownowbrowncow\x00\x00' # exactly 16 or 32 bytes
+ rounds = 12 # common values: 8, 12, 20
+ iv = b'123456789012' # exactly 12 bytes
+ plain = b'Kilroy was here, there, and everywhere!'
+
+ cha = ChaCha(key, rounds)
+ cha.set_iv32(iv)
+ cipher = cha.crypt(plain)
+
+ template = '\n ChaCha%d ciphertext for "%s" is "%s"'
+ print(template % (rounds, plain, hexlify(cipher)))
+
+ cha.set_iv32(iv) # reset to decrypt
+ decrypted = cha.crypt(cipher)
+
+ template = ' ChaCha%d decoded text for "%s" is "%s" \n'
+ print(template % (rounds, plain, decrypted.decode("utf-8")))
+
+# Footnote: Keys should be erased fm memory as soon as possible after use,
+# and that includes Python. For a tip on how to do that in Python, see
+# http://buggywhip.blogspot.com/2010/12/erase-keys-and-credit-card-numbers-in.html
+
+#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
diff --git a/libtomcrypt/demos/hashsum.c b/libtomcrypt/demos/hashsum.c
index 4e31501..aee0bd2 100644
--- a/libtomcrypt/demos/hashsum.c
+++ b/libtomcrypt/demos/hashsum.c
@@ -1,3 +1,12 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
/*
* Written by Daniel Richards <kyhwana@world-net.co.nz> 6/7/2002
* hash.c: This app uses libtomcrypt to hash either stdin or a file
@@ -9,111 +18,283 @@
#include <tomcrypt.h>
-int errno;
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
+#include <libgen.h>
+#else
+#define basename(x) x
+#endif
-void register_algs();
+#if !defined(PATH_MAX) && defined(_MSC_VER)
+#include <windows.h>
+#define PATH_MAX MAX_PATH
+#endif
-int main(int argc, char **argv)
+/* thanks http://stackoverflow.com/a/8198009 */
+#define _base(x) ((x >= '0' && x <= '9') ? '0' : \
+ (x >= 'a' && x <= 'f') ? 'a' - 10 : \
+ (x >= 'A' && x <= 'F') ? 'A' - 10 : \
+ '\255')
+#define HEXOF(x) (x - _base(x))
+
+static char* hashsum;
+
+static void cleanup(void)
{
- int idx, x, z;
- unsigned long w;
- unsigned char hash_buffer[MAXBLOCKSIZE];
- hash_state md;
+ free(hashsum);
+}
- /* You need to register algorithms before using them */
- register_algs();
- if (argc < 2) {
- printf("usage: ./hash algorithm file [file ...]\n");
- printf("Algorithms:\n");
- for (x = 0; hash_descriptor[x].name != NULL; x++) {
- printf(" %s (%d)\n", hash_descriptor[x].name, hash_descriptor[x].ID);
+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");
+ w = 0;
+ for (x = 0; hash_descriptor[x].name != NULL; x++) {
+ w += fprintf(o, "%-14s", hash_descriptor[x].name);
+ if (w >= 70) {
+ fprintf(o, "\n\t");
+ w = 0;
}
- exit(EXIT_SUCCESS);
}
+ if (w != 0) fprintf(o, "\n");
+ exit(status);
+}
- idx = find_hash(argv[1]);
- if (idx == -1) {
- fprintf(stderr, "\nInvalid hash specified on command line.\n");
- return -1;
+static void printf_hex(unsigned char* hash_buffer, unsigned long w)
+{
+ unsigned long x;
+ for (x = 0; x < w; x++) {
+ printf("%02x",hash_buffer[x]);
}
+}
- if (argc == 2) {
- hash_descriptor[idx].init(&md);
- do {
- x = fread(hash_buffer, 1, sizeof(hash_buffer), stdin);
- hash_descriptor[idx].process(&md, hash_buffer, x);
- } while (x == sizeof(hash_buffer));
- hash_descriptor[idx].done(&md, hash_buffer);
- for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) {
- printf("%02x",hash_buffer[x]);
+static void check_file(int argn, int argc, char **argv)
+{
+ int err, failed, invalid;
+ unsigned char is_buffer[MAXBLOCKSIZE], should_buffer[MAXBLOCKSIZE];
+ char buf[PATH_MAX + (MAXBLOCKSIZE * 3)];
+ /* iterate through all files */
+ while(argn < argc) {
+ char* s;
+ FILE* f = fopen(argv[argn], "rb");
+ if(f == NULL) {
+ int n = snprintf(buf, sizeof(buf), "%s: %s", hashsum, argv[argn]);
+ if (n > 0 && n < (int)sizeof(buf))
+ perror(buf);
+ else
+ perror(argv[argn]);
+ exit(EXIT_FAILURE);
}
- printf(" (stdin)\n");
- } else {
- for (z = 2; z < argc; z++) {
- w = sizeof(hash_buffer);
- if ((errno = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) {
- printf("File hash error: %s\n", error_to_string(errno));
- } else {
- for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) {
- printf("%02x",hash_buffer[x]);
- }
- printf(" %s\n", argv[z]);
+ failed = 0;
+ invalid = 0;
+ /* read the file line by line */
+ while((s = fgets(buf, sizeof(buf), f)) != NULL)
+ {
+ int tries, n;
+ unsigned long hash_len, w, x;
+ char* space = strstr(s, " ");
+
+ /* skip lines with comments */
+ if (buf[0] == '#') continue;
+
+ if (space == NULL) {
+ fprintf(stderr, "%s: no properly formatted checksum lines found\n", hashsum);
+ goto ERR;
+ }
+
+ hash_len = space - s;
+ hash_len /= 2;
+
+ if (hash_len > sizeof(should_buffer)) {
+ fprintf(stderr, "%s: hash too long\n", hashsum);
+ goto ERR;
+ }
+
+ /* convert the hex-string back to binary */
+ for (x = 0; x < hash_len; ++x) {
+ should_buffer[x] = HEXOF(s[x*2]) << 4 | HEXOF(s[x*2 + 1]);
}
+
+ space++;
+ if (*space != '*') {
+ fprintf(stderr, "%s: unsupported input mode '%c'\n", hashsum, *space);
+ goto ERR;
+ }
+ space++;
+
+ for (n = 0; n < (buf + sizeof(buf)) - space; ++n) {
+ if(iscntrl((int)space[n])) {
+ space[n] = '\0';
+ break;
+ }
+ }
+
+ /* try all hash algorithms that have the appropriate hash size */
+ tries = 0;
+ for (x = 0; hash_descriptor[x].name != NULL; ++x) {
+ if (hash_descriptor[x].hashsize == hash_len) {
+ tries++;
+ w = sizeof(is_buffer);
+ if ((err = hash_file(x, space, is_buffer, &w)) != CRYPT_OK) {
+ fprintf(stderr, "%s: File hash error: %s: %s\n", hashsum, space, error_to_string(err));
+ERR:
+ fclose(f);
+ exit(EXIT_FAILURE);
+ }
+ if(XMEMCMP(should_buffer, is_buffer, w) == 0) {
+ printf("%s: OK\n", space);
+ break;
+ }
+ }
+ } /* for */
+ if (hash_descriptor[x].name == NULL) {
+ if(tries > 0) {
+ printf("%s: FAILED\n", space);
+ failed++;
+ }
+ else {
+ invalid++;
+ }
+ }
+ } /* while */
+ fclose(f);
+ if(invalid) {
+ fprintf(stderr, "%s: WARNING: %d %s is improperly formatted\n", hashsum, invalid, invalid > 1?"lines":"line");
+ }
+ if(failed) {
+ fprintf(stderr, "%s: WARNING: %d computed %s did NOT match\n", hashsum, failed, failed > 1?"checksums":"checksum");
}
+ argn++;
}
- return EXIT_SUCCESS;
+ exit(EXIT_SUCCESS);
}
-void register_algs(void)
+int main(int argc, char **argv)
{
- int err;
+ int idxs[TAB_SIZE], idx, check, y, z, err, argn;
+ unsigned long w, x;
+ unsigned char hash_buffer[MAXBLOCKSIZE];
-#ifdef LTC_TIGER
- register_hash (&tiger_desc);
-#endif
-#ifdef LTC_MD2
- register_hash (&md2_desc);
-#endif
-#ifdef LTC_MD4
- register_hash (&md4_desc);
-#endif
-#ifdef LTC_MD5
- register_hash (&md5_desc);
-#endif
+ hashsum = strdup(basename(argv[0]));
+ atexit(cleanup);
+
+ /* 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)) {
+ die(EXIT_SUCCESS);
+ }
+ if (argc < 3) {
+ die(EXIT_FAILURE);
+ }
+
+ for (x = 0; x < sizeof(idxs)/sizeof(idxs[0]); ++x) {
+ idxs[x] = -2;
+ }
+ argn = 1;
+ check = 0;
+ idx = 0;
+
+ while(argn < argc){
+ if(strcmp("-a", argv[argn]) == 0) {
+ argn++;
+ if(argn < argc) {
+ idxs[idx] = find_hash(argv[argn]);
+ if (idxs[idx] == -1) {
+ struct {
+ const char* is;
+ const char* should;
+ } shasum_compat[] =
+ {
#ifdef LTC_SHA1
- register_hash (&sha1_desc);
+ { "1", sha1_desc.name },
#endif
#ifdef LTC_SHA224
- register_hash (&sha224_desc);
+ { "224", sha224_desc.name },
#endif
#ifdef LTC_SHA256
- register_hash (&sha256_desc);
+ { "256", sha256_desc.name },
#endif
#ifdef LTC_SHA384
- register_hash (&sha384_desc);
+ { "384", sha384_desc.name },
#endif
#ifdef LTC_SHA512
- register_hash (&sha512_desc);
-#endif
-#ifdef LTC_RIPEMD128
- register_hash (&rmd128_desc);
+ { "512", sha512_desc.name },
#endif
-#ifdef LTC_RIPEMD160
- register_hash (&rmd160_desc);
+#ifdef LTC_SHA512_224
+ { "512224", sha512_224_desc.name },
#endif
-#ifdef LTC_WHIRLPOOL
- register_hash (&whirlpool_desc);
-#endif
-#ifdef LTC_CHC_HASH
- register_hash(&chc_desc);
- if ((err = chc_register(register_cipher(&aes_enc_desc))) != CRYPT_OK) {
- printf("chc_register error: %s\n", error_to_string(err));
- exit(EXIT_FAILURE);
- }
+#ifdef LTC_SHA512_256
+ { "512256", sha512_256_desc.name },
#endif
+ { NULL, NULL }
+ };
+ for (x = 0; shasum_compat[x].is != NULL; ++x) {
+ if(XSTRCMP(shasum_compat[x].is, argv[argn]) == 0) {
+ idxs[idx] = find_hash(shasum_compat[x].should);
+ break;
+ }
+ }
+ }
+ if (idxs[idx] == -1) {
+ fprintf(stderr, "%s: Unrecognized algorithm\n", hashsum);
+ die(EXIT_FAILURE);
+ }
+ idx++;
+ if ((size_t)idx >= sizeof(idxs)/sizeof(idxs[0])) {
+ fprintf(stderr, "%s: Too many '-a' options chosen\n", hashsum);
+ die(EXIT_FAILURE);
+ }
+ argn++;
+ continue;
+ }
+ else {
+ die(EXIT_FAILURE);
+ }
+ }
+ if(strcmp("-c", argv[argn]) == 0) {
+ check = 1;
+ argn++;
+ continue;
+ }
+ break;
+ }
+
+ if (check == 1) {
+ check_file(argn, argc, argv);
+ }
+ if (argc == argn) {
+ w = sizeof(hash_buffer);
+ if ((err = hash_filehandle(idxs[0], stdin, hash_buffer, &w)) != CRYPT_OK) {
+ fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err));
+ return EXIT_FAILURE;
+ } else {
+ for (x = 0; x < w; x++) {
+ printf("%02x",hash_buffer[x]);
+ }
+ printf(" *-\n");
+ }
+ } else {
+ for (z = argn; z < argc; z++) {
+ for (y = 0; y < idx; ++y) {
+ w = sizeof(hash_buffer);
+ if ((err = hash_file(idxs[y],argv[z],hash_buffer,&w)) != CRYPT_OK) {
+ fprintf(stderr, "%s: File hash error: %s\n", hashsum, error_to_string(err));
+ return EXIT_FAILURE;
+ } else {
+ printf_hex(hash_buffer, w);
+ printf(" *%s\n", argv[z]);
+ }
+ }
+ }
+ }
+ return EXIT_SUCCESS;
}
-/* $Source$ */
-/* $Revision$ */
-/* $Date$ */
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/demos/ltcrypt.c b/libtomcrypt/demos/ltcrypt.c
new file mode 100644
index 0000000..024c005
--- /dev/null
+++ b/libtomcrypt/demos/ltcrypt.c
@@ -0,0 +1,205 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/* encrypt V1.1 Fri Oct 18 04:28:03 NZDT 2002 */
+/* File de/encryption, using libtomcrypt */
+/* Written by Daniel Richards <kyhwana@world-net.co.nz> */
+/* Help from Tom St Denis with various bits */
+/* This code is public domain, no rights reserved. */
+/* Encrypts by default, -d flag enables decryption */
+/* ie: ./encrypt blowfish story.txt story.ct */
+/* ./encrypt -d blowfish story.ct story.pt */
+
+#include <tomcrypt.h>
+
+int usage(char *name)
+{
+ 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);
+ for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+ printf("%s\n",cipher_descriptor[x].name);
+ }
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ unsigned char plaintext[512],ciphertext[512];
+ unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE];
+ unsigned char inbuf[512]; /* i/o block size */
+ unsigned long outlen, y, ivsize, x, decrypt;
+ symmetric_CTR ctr;
+ int cipher_idx, hash_idx, ks;
+ char *infile, *outfile, *cipher;
+ prng_state prng;
+ FILE *fdin, *fdout;
+ int err;
+
+ /* register algs, so they can be printed */
+ register_all_ciphers();
+ register_all_hashes();
+ register_all_prngs();
+
+ if (argc < 4) {
+ if ((argc > 2) && (!strcmp(argv[1], "-t"))) {
+ cipher = argv[2];
+ cipher_idx = find_cipher(cipher);
+ if (cipher_idx == -1) {
+ printf("Invalid cipher %s entered on command line.\n", cipher);
+ exit(-1);
+ } /* 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);
+ }
+ else
+ {
+ printf("Testing cipher %s succeeded.\n", cipher);
+ exit(0);
+ } /* if ... else */
+ } /* if */
+ }
+ return usage(argv[0]);
+ }
+
+ if (!strcmp(argv[1], "-d")) {
+ decrypt = 1;
+ cipher = argv[2];
+ infile = argv[3];
+ outfile = argv[4];
+ } else {
+ decrypt = 0;
+ cipher = argv[1];
+ infile = argv[2];
+ outfile = argv[3];
+ }
+
+ /* file handles setup */
+ fdin = fopen(infile,"rb");
+ if (fdin == NULL) {
+ perror("Can't open input for reading");
+ exit(-1);
+ }
+
+ fdout = fopen(outfile,"wb");
+ if (fdout == NULL) {
+ perror("Can't open output for writing");
+ exit(-1);
+ }
+
+ cipher_idx = find_cipher(cipher);
+ if (cipher_idx == -1) {
+ printf("Invalid cipher entered on command line.\n");
+ exit(-1);
+ }
+
+ hash_idx = find_hash("sha256");
+ if (hash_idx == -1) {
+ printf("LTC_SHA256 not found...?\n");
+ exit(-1);
+ }
+
+ ivsize = cipher_descriptor[cipher_idx].block_length;
+ ks = hash_descriptor[hash_idx].hashsize;
+ if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) {
+ printf("Invalid keysize???\n");
+ exit(-1);
+ }
+
+ printf("\nEnter key: ");
+ if(fgets((char *)tmpkey,sizeof(tmpkey), stdin) == NULL)
+ exit(-1);
+ outlen = sizeof(key);
+ if ((err = hash_memory(hash_idx,tmpkey,strlen((char *)tmpkey),key,&outlen)) != CRYPT_OK) {
+ printf("Error hashing key: %s\n", error_to_string(err));
+ exit(-1);
+ }
+
+ if (decrypt) {
+ /* Need to read in IV */
+ if (fread(IV,1,ivsize,fdin) != ivsize) {
+ printf("Error reading IV from input.\n");
+ exit(-1);
+ }
+
+ if ((err = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
+ printf("ctr_start error: %s\n",error_to_string(err));
+ exit(-1);
+ }
+
+ /* IV done */
+ do {
+ y = fread(inbuf,1,sizeof(inbuf),fdin);
+
+ if ((err = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) {
+ printf("ctr_decrypt error: %s\n", error_to_string(err));
+ exit(-1);
+ }
+
+ if (fwrite(plaintext,1,y,fdout) != y) {
+ printf("Error writing to file.\n");
+ exit(-1);
+ }
+ } while (y == sizeof(inbuf));
+ fclose(fdin);
+ fclose(fdout);
+
+ } else { /* encrypt */
+ /* Setup yarrow for random bytes for IV */
+
+ if ((err = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) {
+ printf("Error setting up PRNG, %s\n", error_to_string(err));
+ }
+
+ /* You can use rng_get_bytes on platforms that support it */
+ /* x = rng_get_bytes(IV,ivsize,NULL);*/
+ x = yarrow_read(IV,ivsize,&prng);
+ if (x != ivsize) {
+ printf("Error reading PRNG for IV required.\n");
+ exit(-1);
+ }
+
+ if (fwrite(IV,1,ivsize,fdout) != ivsize) {
+ printf("Error writing IV to output.\n");
+ exit(-1);
+ }
+
+ if ((err = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
+ printf("ctr_start error: %s\n",error_to_string(err));
+ exit(-1);
+ }
+
+ do {
+ y = fread(inbuf,1,sizeof(inbuf),fdin);
+
+ if ((err = ctr_encrypt(inbuf,ciphertext,y,&ctr)) != CRYPT_OK) {
+ printf("ctr_encrypt error: %s\n", error_to_string(err));
+ exit(-1);
+ }
+
+ if (fwrite(ciphertext,1,y,fdout) != y) {
+ printf("Error writing to output.\n");
+ exit(-1);
+ }
+ } while (y == sizeof(inbuf));
+ fclose(fdout);
+ fclose(fdin);
+ }
+ return 0;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/demos/openssl-enc.c b/libtomcrypt/demos/openssl-enc.c
new file mode 100644
index 0000000..3aca04f
--- /dev/null
+++ b/libtomcrypt/demos/openssl-enc.c
@@ -0,0 +1,397 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/*
+ * Demo to do the rough equivalent of:
+ *
+ * openssl enc -aes-256-cbc -pass pass:foobar -in infile -out outfile -p
+ *
+ * Compilation:
+ *
+ * $(CC) -I /path/to/headers -L .../libs \
+ * -o openssl-enc \
+ * openssl-enc.c -ltomcrypt
+ *
+ * Usage:
+ *
+ * ./openssl-enc <enc|dec> infile outfile "passphrase" [salt]
+ *
+ * If provided, the salt must be EXACTLY a 16-char hex string.
+ *
+ * Demo is an example of:
+ *
+ * - (When decrypting) yanking salt out of the OpenSSL "Salted__..." header
+ * - 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 :-)
+ *
+ * BJ Black, bblack@barracuda.com, https://wjblack.com
+ *
+ * BUGS:
+ * Passing a password on a command line is a HORRIBLE idea. Don't use
+ * this program for serious work!
+ */
+
+#include <tomcrypt.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
+
+/* OpenSSL by default only runs one hash round */
+#define OPENSSL_ITERATIONS 1
+/* Use aes-256-cbc, so 256 bits of key, 128 of IV */
+#define KEY_LENGTH (256>>3)
+#define IV_LENGTH (128>>3)
+/* PKCS#5v1 requires exactly an 8-byte salt */
+#define SALT_LENGTH 8
+/* The header OpenSSL puts on an encrypted file */
+static char salt_header[] = { 'S', 'a', 'l', 't', 'e', 'd', '_', '_' };
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+/* A simple way to handle the possibility that a block may increase in size
+ after padding. */
+union paddable {
+ unsigned char unpad[1024];
+ unsigned char pad[1024+MAXBLOCKSIZE];
+};
+
+/*
+ * Print usage and exit with a bad status (and perror() if any errno).
+ *
+ * Input: argv[0] and the error string
+ * Output: <no return>
+ * Side Effects: print messages and barf (does exit(3))
+ */
+void 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);
+ 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;
+}
+
+/*
+ * Parse the Salted__[+8 bytes] from an OpenSSL-compatible file header.
+ *
+ * Input: file to read from and a to put the salt in (exactly 8 bytes!)
+ * Output: CRYPT_OK if parsed OK, CRYPT_ERROR if not
+ * Side Effects: infile's read pointer += 16
+ */
+int parse_openssl_header(FILE *in, unsigned char *out)
+{
+ unsigned char tmp[SALT_LENGTH];
+ if(fread(tmp, 1, sizeof(tmp), in) != sizeof(tmp))
+ return CRYPT_ERROR;
+ if(memcmp(tmp, salt_header, sizeof(tmp)))
+ return CRYPT_ERROR;
+ if(fread(tmp, 1, sizeof(tmp), in) != sizeof(tmp))
+ return CRYPT_ERROR;
+ memcpy(out, tmp, sizeof(tmp));
+ return CRYPT_OK;
+}
+
+/*
+ * Dump a hexed stream of bytes (convenience func).
+ *
+ * Input: buf to read from, length
+ * Output: none
+ * Side Effects: bytes printed as a hex blob, no lf at the end
+ */
+void dump_bytes(unsigned char *in, unsigned long len)
+{
+ unsigned long idx;
+ for(idx=0; idx<len; idx++)
+ printf("%02hhX", *(in+idx));
+}
+
+/*
+ * Pad or unpad a message using PKCS#7 padding.
+ * Padding will add 1-(blocksize) bytes and unpadding will remove that amount.
+ * Set is_padding to 1 to pad, 0 to unpad.
+ *
+ * Input: paddable buffer, size read, block length of cipher, mode
+ * Output: number of bytes after padding resp. after unpadding
+ * Side Effects: none
+ */
+size_t pkcs7_pad(union paddable *buf, size_t nb, int block_length,
+ int is_padding)
+{
+ unsigned char padval;
+ off_t idx;
+
+ if(is_padding) {
+ /* We are PADDING this block (and therefore adding bytes) */
+ /* The pad value in PKCS#7 is the number of bytes remaining in
+ the block, so for a 16-byte block and 3 bytes left, it's
+ 0x030303. In the oddball case where nb is an exact multiple
+ multiple of block_length, set the padval to blocksize (i.e.
+ add one full block) */
+ padval = (unsigned char) (block_length - (nb % block_length));
+ padval = padval ? padval : block_length;
+
+ memset(buf->pad+nb, padval, padval);
+ return nb+padval;
+ } else {
+ /* We are UNPADDING this block (and removing bytes)
+ We really just need to verify that the pad bytes are correct,
+ so start at the end of the string and work backwards. */
+
+ /* Figure out what the padlength should be by looking at the
+ last byte */
+ idx = nb-1;
+ padval = buf->pad[idx];
+
+ /* padval must be nonzero and <= block length */
+ if(padval <= 0 || padval > block_length)
+ return 0;
+
+ /* First byte's accounted for; do the rest */
+ idx--;
+
+ while(idx >= (off_t)(nb-padval))
+ if(buf->pad[idx] != padval)
+ return 0;
+ else
+ idx--;
+
+ /* If we got here, the pad checked out, so return a smaller
+ number of bytes than nb (basically where we left off+1) */
+ return idx+1;
+ }
+}
+
+/*
+ * Perform an encrypt/decrypt operation to/from files using AES+CBC+PKCS7 pad.
+ * Set encrypt to 1 to encrypt, 0 to decrypt.
+ *
+ * Input: in/out files, key, iv, and mode
+ * Output: CRYPT_OK if no error
+ * Side Effects: bytes slurped from infile, pushed to outfile, fds updated.
+ */
+int do_crypt(FILE *infd, FILE *outfd, unsigned char *key, unsigned char *iv,
+ int encrypt)
+{
+ union paddable inbuf, outbuf;
+ int cipher, ret;
+ symmetric_CBC cbc;
+ size_t nb;
+
+ /* Register your cipher! */
+ cipher = register_cipher(&aes_desc);
+ if(cipher == -1)
+ return CRYPT_INVALID_CIPHER;
+
+ /* Start a CBC session with cipher/key/val params */
+ ret = cbc_start(cipher, iv, key, KEY_LENGTH, 0, &cbc);
+ if( ret != CRYPT_OK )
+ return -1;
+
+ do {
+ /* Get bytes from the source */
+ nb = fread(inbuf.unpad, 1, sizeof(inbuf.unpad), infd);
+ if(!nb)
+ return encrypt ? CRYPT_OK : CRYPT_ERROR;
+
+ /* Barf if we got a read error */
+ if(ferror(infd))
+ return CRYPT_ERROR;
+
+ if(encrypt) {
+ /* We're encrypting, so pad first (if at EOF) and then
+ crypt */
+ if(feof(infd))
+ nb = pkcs7_pad(&inbuf, nb,
+ aes_desc.block_length, 1);
+
+ ret = cbc_encrypt(inbuf.pad, outbuf.pad, nb, &cbc);
+ if(ret != CRYPT_OK)
+ return ret;
+
+ } else {
+ /* We're decrypting, so decrypt and then unpad if at
+ EOF */
+ ret = cbc_decrypt(inbuf.unpad, outbuf.unpad, nb, &cbc);
+ if( ret != CRYPT_OK )
+ return ret;
+
+ if( feof(infd) )
+ nb = pkcs7_pad(&outbuf, nb,
+ aes_desc.block_length, 0);
+ if(nb == 0)
+ /* The file didn't decrypt correctly */
+ return CRYPT_ERROR;
+
+ }
+
+ /* Push bytes to outfile */
+ if(fwrite(outbuf.unpad, 1, nb, outfd) != nb)
+ return CRYPT_ERROR;
+
+ } while(!feof(infd));
+
+ /* Close up */
+ cbc_done(&cbc);
+
+ return CRYPT_OK;
+}
+
+/* Convenience macro for the various barfable places below */
+#define BARF(a) { \
+ if(infd) fclose(infd); \
+ if(outfd) { fclose(outfd); remove(argv[3]); } \
+ barf(argv[0], a); \
+}
+/*
+ * The main routine. Mostly validate cmdline params, open files, run the KDF,
+ * and do the crypt.
+ */
+int main(int argc, char *argv[]) {
+ unsigned char salt[SALT_LENGTH];
+ FILE *infd = NULL, *outfd = NULL;
+ int encrypt = -1;
+ int hash = -1;
+ int ret;
+ unsigned char keyiv[KEY_LENGTH + IV_LENGTH];
+ unsigned long keyivlen = (KEY_LENGTH + IV_LENGTH);
+ unsigned char *key, *iv;
+
+ /* Check proper number of cmdline args */
+ if(argc < 5 || argc > 6)
+ BARF("Invalid number of arguments");
+
+ /* Check proper mode of operation */
+ if (!strncmp(argv[1], "enc", 3))
+ encrypt = 1;
+ else if(!strncmp(argv[1], "dec", 3))
+ encrypt = 0;
+ else
+ BARF("Bad command name");
+
+ /* Check we can open infile/outfile */
+ infd = fopen(argv[2], "rb");
+ if(infd == NULL)
+ BARF("Could not open infile");
+ outfd = fopen(argv[3], "wb");
+ if(outfd == NULL)
+ BARF("Could not open outfile");
+
+ /* Get the salt from wherever */
+ if(argc == 6) {
+ /* User-provided */
+ if(parse_hex_salt((unsigned char*) argv[5], salt) != CRYPT_OK)
+ BARF("Bad user-specified salt");
+ } else if(!strncmp(argv[1], "enc", 3)) {
+ /* Encrypting; get from RNG */
+ if(rng_get_bytes(salt, sizeof(salt), NULL) != sizeof(salt))
+ BARF("Not enough random data");
+ } else {
+ /* Parse from infile (decrypt only) */
+ if(parse_openssl_header(infd, salt) != CRYPT_OK)
+ BARF("Invalid OpenSSL header in infile");
+ }
+
+ /* Fetch the MD5 hasher for PKCS#5 */
+ hash = register_hash(&md5_desc);
+ if(hash == -1)
+ BARF("Could not register MD5 hash");
+
+ /* Set things to a sane initial state */
+ zeromem(keyiv, sizeof(keyiv));
+ key = keyiv + 0; /* key comes first */
+ iv = keyiv + KEY_LENGTH; /* iv comes next */
+
+ /* Run the key derivation from the provided passphrase. This gets us
+ the key and iv. */
+ ret = pkcs_5_alg1_openssl((unsigned char*)argv[4], strlen(argv[4]), salt,
+ OPENSSL_ITERATIONS, hash, keyiv, &keyivlen );
+ if(ret != CRYPT_OK)
+ BARF("Could not derive key/iv from passphrase");
+
+ /* Display the salt/key/iv like OpenSSL cmdline does when -p */
+ printf("salt="); dump_bytes(salt, sizeof(salt)); printf("\n");
+ printf("key="); dump_bytes(key, KEY_LENGTH); printf("\n");
+ printf("iv ="); dump_bytes(iv, IV_LENGTH ); printf("\n");
+
+ /* If we're encrypting, write the salt header as OpenSSL does */
+ if(!strncmp(argv[1], "enc", 3)) {
+ if(fwrite(salt_header, 1, sizeof(salt_header), outfd) !=
+ sizeof(salt_header) )
+ BARF("Error writing salt header to outfile");
+ if(fwrite(salt, 1, sizeof(salt), outfd) != sizeof(salt))
+ BARF("Error writing salt to outfile");
+ }
+
+ /* At this point, the files are open, the salt has been figured out,
+ and we're ready to pump data through crypt. */
+
+ /* Do the crypt operation */
+ if(do_crypt(infd, outfd, key, iv, encrypt) != CRYPT_OK)
+ BARF("Error during crypt operation");
+
+ /* Clean up */
+ fclose(infd); fclose(outfd);
+ return 0;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/demos/sizes.c b/libtomcrypt/demos/sizes.c
new file mode 100644
index 0000000..54d1979
--- /dev/null
+++ b/libtomcrypt/demos/sizes.c
@@ -0,0 +1,79 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+#include "tomcrypt.h"
+
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L
+#include <libgen.h>
+#else
+#define basename(x) x
+#endif
+/**
+ @file demo_crypt_sizes.c
+
+ Demo how to get various sizes to dynamic languages
+ like Python - Larry Bugbee, February 2013
+*/
+
+static void _print_line(const char* cmd, const char* desc)
+{
+ printf(" %-16s - %s\n", cmd, desc);
+}
+
+int main(int argc, char **argv)
+{
+ if (argc == 1) {
+ /* given a specific size name, get and print its size */
+ char name[] = "ltc_hash_descriptor";
+ unsigned int size;
+ char *sizes_list;
+ unsigned int sizes_list_len;
+ if (crypt_get_size(name, &size) != 0) exit(EXIT_FAILURE);
+ printf("\n size of '%s' is %u \n\n", name, size);
+
+ /* get and print the length of the names (and sizes) list */
+ if (crypt_list_all_sizes(NULL, &sizes_list_len) != 0) exit(EXIT_FAILURE);
+ printf(" need to allocate %u bytes \n\n", sizes_list_len);
+
+ /* get and print the names (and sizes) list */
+ sizes_list = malloc(sizes_list_len);
+ if (crypt_list_all_sizes(sizes_list, &sizes_list_len) != 0) exit(EXIT_FAILURE);
+ printf(" supported sizes:\n\n%s\n\n", sizes_list);
+ } else if (argc == 2) {
+ if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
+ char* base = strdup(basename(argv[0]));
+ printf("Usage: %s [-a] [-s name]\n\n", base);
+ _print_line("<no argument>", "The old behavior of the demo");
+ _print_line("-a", "Only lists all sizes");
+ _print_line("-s name", "List a single size given as argument");
+ _print_line("-h", "The help you're looking at");
+ free(base);
+ } else if (strcmp(argv[1], "-a") == 0) {
+ char *sizes_list;
+ unsigned int sizes_list_len;
+ /* get and print the length of the names (and sizes) list */
+ if (crypt_list_all_sizes(NULL, &sizes_list_len) != 0) exit(EXIT_FAILURE);
+ /* get and print the names (and sizes) list */
+ sizes_list = malloc(sizes_list_len);
+ if (crypt_list_all_sizes(sizes_list, &sizes_list_len) != 0) exit(EXIT_FAILURE);
+ printf("%s\n", sizes_list);
+ }
+ } else if (argc == 3) {
+ if (strcmp(argv[1], "-s") == 0) {
+ unsigned int size;
+ if (crypt_get_size(argv[2], &size) != 0) exit(EXIT_FAILURE);
+ printf("%s,%u\n", argv[2], size);
+ }
+ }
+ return 0;
+}
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/demos/small.c b/libtomcrypt/demos/small.c
index 8d43821..de1f93d 100644
--- a/libtomcrypt/demos/small.c
+++ b/libtomcrypt/demos/small.c
@@ -1,3 +1,11 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
/* small demo app that just includes a cipher/hash/prng */
#include <tomcrypt.h>
@@ -9,6 +17,6 @@ int main(void)
return 0;
}
-/* $Source$ */
-/* $Revision$ */
-/* $Date$ */
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/demos/timing.c b/libtomcrypt/demos/timing.c
index 76fd8cd..14a59df 100644
--- a/libtomcrypt/demos/timing.c
+++ b/libtomcrypt/demos/timing.c
@@ -1,10 +1,1435 @@
-#include <tomcrypt_test.h>
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include <tomcrypt.h>
-int main(void)
+#if defined(_WIN32)
+ #define PRI64 "I64d"
+#else
+ #define PRI64 "ll"
+#endif
+
+static prng_state yarrow_prng;
+
+/* timing */
+#define KTIMES 25
+#define TIMES 100000
+
+static struct list {
+ int id;
+ ulong64 spd1, spd2, avg;
+} results[100];
+static int no_results;
+
+static int sorter(const void *a, const void *b)
+{
+ const struct list *A, *B;
+ A = a;
+ B = b;
+ if (A->avg < B->avg) return -1;
+ if (A->avg > B->avg) return 1;
+ return 0;
+}
+
+static void tally_results(int type)
+{
+ int x;
+
+ /* qsort the results */
+ qsort(results, no_results, sizeof(struct list), &sorter);
+
+ fprintf(stderr, "\n");
+ if (type == 0) {
+ for (x = 0; x < no_results; x++) {
+ fprintf(stderr, "%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1);
+ }
+ } else if (type == 1) {
+ for (x = 0; x < no_results; x++) {
+ printf
+ ("%-20s[%3d]: Encrypt at %5"PRI64"u, Decrypt at %5"PRI64"u\n", cipher_descriptor[results[x].id].name, cipher_descriptor[results[x].id].ID, results[x].spd1, results[x].spd2);
+ }
+ } else {
+ for (x = 0; x < no_results; x++) {
+ printf
+ ("%-20s: Process at %5"PRI64"u\n", hash_descriptor[results[x].id].name, results[x].spd1 / 1000);
+ }
+ }
+}
+
+/* RDTSC from Scott Duplichan */
+static ulong64 rdtsc (void)
+ {
+ #if defined __GNUC__ && !defined(LTC_NO_ASM)
+ #if defined(__i386__) || defined(__x86_64__)
+ /* version from http://www.mcs.anl.gov/~kazutomo/rdtsc.html
+ * the old code always got a warning issued by gcc, clang did not complain...
+ */
+ unsigned hi, lo;
+ __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
+ return ((ulong64)lo)|( ((ulong64)hi)<<32);
+ #elif defined(LTC_PPC32) || defined(TFM_PPC32)
+ unsigned long a, b;
+ __asm__ __volatile__ ("mftbu %1 \nmftb %0\n":"=r"(a), "=r"(b));
+ return (((ulong64)b) << 32ULL) | ((ulong64)a);
+ #elif defined(__ia64__) /* gcc-IA64 version */
+ unsigned long result;
+ __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
+ while (__builtin_expect ((int) result == -1, 0))
+ __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
+ return result;
+ #elif defined(__sparc__)
+ #if defined(__arch64__)
+ ulong64 a;
+ asm volatile("rd %%tick,%0" : "=r" (a));
+ return a;
+ #else
+ register unsigned long x, y;
+ __asm__ __volatile__ ("rd %%tick, %0; clruw %0, %1; srlx %0, 32, %0" : "=r" (x), "=r" (y) : "0" (x), "1" (y));
+ return ((unsigned long long) x << 32) | y;
+ #endif
+ #else
+ return XCLOCK();
+ #endif
+
+ /* Microsoft and Intel Windows compilers */
+ #elif defined _M_IX86 && !defined(LTC_NO_ASM)
+ __asm rdtsc
+ #elif defined _M_AMD64 && !defined(LTC_NO_ASM)
+ return __rdtsc ();
+ #elif defined _M_IA64 && !defined(LTC_NO_ASM)
+ #if defined __INTEL_COMPILER
+ #include <ia64intrin.h>
+ #endif
+ return __getReg (3116);
+ #else
+ return XCLOCK();
+ #endif
+ }
+
+static ulong64 timer, skew = 0;
+
+static void t_start(void)
+{
+ timer = rdtsc();
+}
+
+static ulong64 t_read(void)
+{
+ return rdtsc() - timer;
+}
+
+static void init_timer(void)
+{
+ ulong64 c1, c2, t1, t2;
+ unsigned long y1;
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < TIMES*100; y1++) {
+ t_start();
+ t1 = t_read();
+ t2 = (t_read() - t1)>>1;
+
+ c1 = (t1 > c1) ? t1 : c1;
+ c2 = (t2 > c2) ? t2 : c2;
+ }
+ skew = c2 - c1;
+ fprintf(stderr, "Clock Skew: %lu\n", (unsigned long)skew);
+}
+
+static void time_keysched(void)
+{
+ unsigned long x, y1;
+ ulong64 t1, c1;
+ symmetric_key skey;
+ int kl;
+ int (*func) (const unsigned char *, int , int , symmetric_key *);
+ unsigned char key[MAXBLOCKSIZE];
+
+ fprintf(stderr, "\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n");
+ no_results = 0;
+ for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+#define DO1(k) func(k, kl, 0, &skey);
+
+ func = cipher_descriptor[x].setup;
+ kl = cipher_descriptor[x].min_key_length;
+ c1 = (ulong64)-1;
+ for (y1 = 0; y1 < KTIMES; y1++) {
+ yarrow_read(key, kl, &yarrow_prng);
+ t_start();
+ DO1(key);
+ t1 = t_read();
+ c1 = (t1 > c1) ? c1 : t1;
+ }
+ t1 = c1 - skew;
+ results[no_results].spd1 = results[no_results].avg = t1;
+ results[no_results++].id = x;
+ fprintf(stderr, "."); fflush(stdout);
+
+#undef DO1
+ }
+ tally_results(0);
+}
+
+#ifdef LTC_ECB_MODE
+static void time_cipher_ecb(void)
+{
+ unsigned long x, y1;
+ ulong64 t1, t2, c1, c2, a1, a2;
+ symmetric_ECB ecb;
+ unsigned char key[MAXBLOCKSIZE] = { 0 }, pt[4096] = { 0 };
+ int err;
+
+ fprintf(stderr, "\n\nECB Time Trials for the Symmetric Ciphers:\n");
+ no_results = 0;
+ for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+ ecb_start(x, key, cipher_descriptor[x].min_key_length, 0, &ecb);
+
+ /* sanity check on cipher */
+ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
+ fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+#define DO1 ecb_encrypt(pt, pt, sizeof(pt), &ecb);
+#define DO2 DO1 DO1
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < 100; y1++) {
+ t_start();
+ DO1;
+ t1 = t_read();
+ DO2;
+ t2 = t_read();
+ t2 -= t1;
+
+ c1 = (t1 > c1 ? c1 : t1);
+ c2 = (t2 > c2 ? c2 : t2);
+ }
+ a1 = c2 - c1 - skew;
+
+#undef DO1
+#undef DO2
+#define DO1 ecb_decrypt(pt, pt, sizeof(pt), &ecb);
+#define DO2 DO1 DO1
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < 100; y1++) {
+ t_start();
+ DO1;
+ t1 = t_read();
+ DO2;
+ t2 = t_read();
+ t2 -= t1;
+
+ c1 = (t1 > c1 ? c1 : t1);
+ c2 = (t2 > c2 ? c2 : t2);
+ }
+ a2 = c2 - c1 - skew;
+ ecb_done(&ecb);
+
+ results[no_results].id = x;
+ results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length);
+ results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
+ results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
+ ++no_results;
+ fprintf(stderr, "."); fflush(stdout);
+
+#undef DO2
+#undef DO1
+ }
+ tally_results(1);
+}
+#else
+static void time_cipher_ecb(void) { fprintf(stderr, "NO ECB\n"); return 0; }
+#endif
+
+#ifdef LTC_CBC_MODE
+static void time_cipher_cbc(void)
+{
+ unsigned long x, y1;
+ ulong64 t1, t2, c1, c2, a1, a2;
+ symmetric_CBC cbc;
+ unsigned char key[MAXBLOCKSIZE] = { 0 }, pt[4096] = { 0 };
+ int err;
+
+ fprintf(stderr, "\n\nCBC Time Trials for the Symmetric Ciphers:\n");
+ no_results = 0;
+ for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+ cbc_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &cbc);
+
+ /* sanity check on cipher */
+ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
+ fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+#define DO1 cbc_encrypt(pt, pt, sizeof(pt), &cbc);
+#define DO2 DO1 DO1
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < 100; y1++) {
+ t_start();
+ DO1;
+ t1 = t_read();
+ DO2;
+ t2 = t_read();
+ t2 -= t1;
+
+ c1 = (t1 > c1 ? c1 : t1);
+ c2 = (t2 > c2 ? c2 : t2);
+ }
+ a1 = c2 - c1 - skew;
+
+#undef DO1
+#undef DO2
+#define DO1 cbc_decrypt(pt, pt, sizeof(pt), &cbc);
+#define DO2 DO1 DO1
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < 100; y1++) {
+ t_start();
+ DO1;
+ t1 = t_read();
+ DO2;
+ t2 = t_read();
+ t2 -= t1;
+
+ c1 = (t1 > c1 ? c1 : t1);
+ c2 = (t2 > c2 ? c2 : t2);
+ }
+ a2 = c2 - c1 - skew;
+ cbc_done(&cbc);
+
+ results[no_results].id = x;
+ results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length);
+ results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
+ results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
+ ++no_results;
+ fprintf(stderr, "."); fflush(stdout);
+
+#undef DO2
+#undef DO1
+ }
+ tally_results(1);
+}
+#else
+static void time_cipher_cbc(void) { fprintf(stderr, "NO CBC\n"); return 0; }
+#endif
+
+#ifdef LTC_CTR_MODE
+static void time_cipher_ctr(void)
+{
+ unsigned long x, y1;
+ ulong64 t1, t2, c1, c2, a1, a2;
+ symmetric_CTR ctr;
+ unsigned char key[MAXBLOCKSIZE] = { 0 }, pt[4096] = { 0 };
+ int err;
+
+ fprintf(stderr, "\n\nCTR Time Trials for the Symmetric Ciphers:\n");
+ no_results = 0;
+ for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+ ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr);
+
+ /* sanity check on cipher */
+ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
+ fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+#define DO1 ctr_encrypt(pt, pt, sizeof(pt), &ctr);
+#define DO2 DO1 DO1
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < 100; y1++) {
+ t_start();
+ DO1;
+ t1 = t_read();
+ DO2;
+ t2 = t_read();
+ t2 -= t1;
+
+ c1 = (t1 > c1 ? c1 : t1);
+ c2 = (t2 > c2 ? c2 : t2);
+ }
+ a1 = c2 - c1 - skew;
+
+#undef DO1
+#undef DO2
+#define DO1 ctr_decrypt(pt, pt, sizeof(pt), &ctr);
+#define DO2 DO1 DO1
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < 100; y1++) {
+ t_start();
+ DO1;
+ t1 = t_read();
+ DO2;
+ t2 = t_read();
+ t2 -= t1;
+
+ c1 = (t1 > c1 ? c1 : t1);
+ c2 = (t2 > c2 ? c2 : t2);
+ }
+ a2 = c2 - c1 - skew;
+ ctr_done(&ctr);
+
+ results[no_results].id = x;
+ results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length);
+ results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
+ results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
+ ++no_results;
+ fprintf(stderr, "."); fflush(stdout);
+
+#undef DO2
+#undef DO1
+ }
+ tally_results(1);
+}
+#else
+static void time_cipher_ctr(void) { fprintf(stderr, "NO CTR\n"); return 0; }
+#endif
+
+#ifdef LTC_LRW_MODE
+static void time_cipher_lrw(void)
+{
+ unsigned long x, y1;
+ ulong64 t1, t2, c1, c2, a1, a2;
+ symmetric_LRW lrw;
+ unsigned char key[MAXBLOCKSIZE] = { 0 }, pt[4096] = { 0 };
+ int err;
+
+ fprintf(stderr, "\n\nLRW Time Trials for the Symmetric Ciphers:\n");
+ no_results = 0;
+ for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+ if (cipher_descriptor[x].block_length != 16) continue;
+ lrw_start(x, pt, key, cipher_descriptor[x].min_key_length, key, 0, &lrw);
+
+ /* sanity check on cipher */
+ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
+ fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+#define DO1 lrw_encrypt(pt, pt, sizeof(pt), &lrw);
+#define DO2 DO1 DO1
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < 100; y1++) {
+ t_start();
+ DO1;
+ t1 = t_read();
+ DO2;
+ t2 = t_read();
+ t2 -= t1;
+
+ c1 = (t1 > c1 ? c1 : t1);
+ c2 = (t2 > c2 ? c2 : t2);
+ }
+ a1 = c2 - c1 - skew;
+
+#undef DO1
+#undef DO2
+#define DO1 lrw_decrypt(pt, pt, sizeof(pt), &lrw);
+#define DO2 DO1 DO1
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < 100; y1++) {
+ t_start();
+ DO1;
+ t1 = t_read();
+ DO2;
+ t2 = t_read();
+ t2 -= t1;
+
+ c1 = (t1 > c1 ? c1 : t1);
+ c2 = (t2 > c2 ? c2 : t2);
+ }
+ a2 = c2 - c1 - skew;
+
+ lrw_done(&lrw);
+
+ results[no_results].id = x;
+ results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length);
+ results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
+ results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
+ ++no_results;
+ fprintf(stderr, "."); fflush(stdout);
+
+#undef DO2
+#undef DO1
+ }
+ tally_results(1);
+}
+#else
+static void time_cipher_lrw(void) { fprintf(stderr, "NO LRW\n"); return 0; }
+#endif
+
+
+static void time_hash(void)
+{
+ unsigned long x, y1, len;
+ ulong64 t1, t2, c1, c2;
+ hash_state md;
+ int (*func)(hash_state *, const unsigned char *, unsigned long), err;
+ unsigned char pt[MAXBLOCKSIZE] = { 0 };
+
+
+ fprintf(stderr, "\n\nHASH Time Trials for:\n");
+ no_results = 0;
+ for (x = 0; hash_descriptor[x].name != NULL; x++) {
+
+ /* sanity check on hash */
+ if ((err = hash_descriptor[x].test()) != CRYPT_OK) {
+ fprintf(stderr, "\n\nERROR: Hash %s failed self-test %s\n", hash_descriptor[x].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+ hash_descriptor[x].init(&md);
+
+#define DO1 func(&md,pt,len);
+#define DO2 DO1 DO1
+
+ func = hash_descriptor[x].process;
+ len = hash_descriptor[x].blocksize;
+
+ c1 = c2 = (ulong64)-1;
+ for (y1 = 0; y1 < TIMES; y1++) {
+ t_start();
+ DO1;
+ t1 = t_read();
+ DO2;
+ t2 = t_read() - t1;
+ c1 = (t1 > c1) ? c1 : t1;
+ c2 = (t2 > c2) ? c2 : t2;
+ }
+ t1 = c2 - c1 - skew;
+ t1 = ((t1 * CONST64(1000))) / ((ulong64)hash_descriptor[x].blocksize);
+ results[no_results].id = x;
+ results[no_results].spd1 = results[no_results].avg = t1;
+ ++no_results;
+ fprintf(stderr, "."); fflush(stdout);
+#undef DO2
+#undef DO1
+ }
+ tally_results(2);
+}
+
+/*#warning you need an mp_rand!!!*/
+#if !defined(USE_LTM) && !defined(USE_TFM) && !defined(USE_GMP) && !defined(EXT_MATH_LIB)
+ #undef LTC_MPI
+ #undef LTC_TEST_MPI
+#else
+ #define LTC_TEST_MPI
+#endif
+
+#ifdef LTC_MPI
+static void time_mult(void)
+{
+ ulong64 t1, t2;
+ unsigned long x, y;
+ void *a, *b, *c;
+
+ fprintf(stderr, "Timing Multiplying:\n");
+ mp_init_multi(&a,&b,&c,NULL);
+ for (x = 128/MP_DIGIT_BIT; x <= (unsigned long)1536/MP_DIGIT_BIT; x += 128/MP_DIGIT_BIT) {
+ mp_rand(a, x);
+ mp_rand(b, x);
+
+#define DO1 mp_mul(a, b, c);
+#define DO2 DO1; DO1;
+
+ t2 = -1;
+ for (y = 0; y < TIMES; y++) {
+ t_start();
+ t1 = t_read();
+ DO2;
+ t1 = (t_read() - t1)>>1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "%4lu bits: %9"PRI64"u cycles\n", x*MP_DIGIT_BIT, t2);
+ }
+ mp_clear_multi(a,b,c,NULL);
+
+#undef DO1
+#undef DO2
+}
+
+static void time_sqr(void)
+{
+ ulong64 t1, t2;
+ unsigned long x, y;
+ void *a, *b;
+
+ fprintf(stderr, "Timing Squaring:\n");
+ mp_init_multi(&a,&b,NULL);
+ for (x = 128/MP_DIGIT_BIT; x <= (unsigned long)1536/MP_DIGIT_BIT; x += 128/MP_DIGIT_BIT) {
+ mp_rand(a, x);
+
+#define DO1 mp_sqr(a, b);
+#define DO2 DO1; DO1;
+
+ t2 = -1;
+ for (y = 0; y < TIMES; y++) {
+ t_start();
+ t1 = t_read();
+ DO2;
+ t1 = (t_read() - t1)>>1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "%4lu bits: %9"PRI64"u cycles\n", x*MP_DIGIT_BIT, t2);
+ }
+ mp_clear_multi(a,b,NULL);
+
+#undef DO1
+#undef DO2
+}
+#else
+static void time_mult(void) { fprintf(stderr, "NO MULT\n"); }
+static void time_sqr(void) { fprintf(stderr, "NO SQR\n"); }
+#endif
+
+static void time_prng(void)
+{
+ ulong64 t1, t2;
+ unsigned char buf[4096];
+ prng_state tprng;
+ unsigned long x, y;
+ int err;
+
+ fprintf(stderr, "Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n");
+ for (x = 0; prng_descriptor[x].name != NULL; x++) {
+
+ /* sanity check on prng */
+ if ((err = prng_descriptor[x].test()) != CRYPT_OK) {
+ fprintf(stderr, "\n\nERROR: PRNG %s failed self-test %s\n", prng_descriptor[x].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+ prng_descriptor[x].start(&tprng);
+ zeromem(buf, 256);
+ prng_descriptor[x].add_entropy(buf, 256, &tprng);
+ prng_descriptor[x].ready(&tprng);
+ t2 = -1;
+
+#define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { fprintf(stderr, "\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); }
+#define DO2 DO1 DO1
+ for (y = 0; y < 10000; y++) {
+ t_start();
+ t1 = t_read();
+ DO2;
+ t1 = (t_read() - t1)>>1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "%20s: %5"PRI64"u ", prng_descriptor[x].name, t2>>12);
+#undef DO2
+#undef DO1
+
+#define DO1 prng_descriptor[x].start(&tprng); prng_descriptor[x].add_entropy(buf, 32, &tprng); prng_descriptor[x].ready(&tprng); prng_descriptor[x].done(&tprng);
+#define DO2 DO1 DO1
+ for (y = 0; y < 10000; y++) {
+ t_start();
+ t1 = t_read();
+ DO2;
+ t1 = (t_read() - t1)>>1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "%5"PRI64"u\n", t2);
+#undef DO2
+#undef DO1
+
+ }
+}
+
+#if defined(LTC_MDSA) && defined(LTC_TEST_MPI)
+/* time various DSA operations */
+static void time_dsa(void)
+{
+ dsa_key key;
+ ulong64 t1, t2;
+ unsigned long x, y;
+ int err;
+static const struct {
+ int group, modulus;
+} groups[] = {
+{ 20, 96 },
+{ 20, 128 },
+{ 24, 192 },
+{ 28, 256 },
+#ifndef TFM_DESC
+{ 32, 512 },
+#endif
+};
+
+ for (x = 0; x < (sizeof(groups)/sizeof(groups[0])); x++) {
+ t2 = 0;
+ for (y = 0; y < 4; y++) {
+ t_start();
+ t1 = t_read();
+ if ((err = dsa_generate_pqg(&yarrow_prng, find_prng("yarrow"), groups[x].group, groups[x].modulus, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\ndsa_generate_pqg says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ if ((err = dsa_generate_key(&yarrow_prng, find_prng("yarrow"), &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\ndsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+
+#ifdef LTC_PROFILE
+ t2 <<= 2;
+ break;
+#endif
+ if (y < 3) {
+ dsa_free(&key);
+ }
+ }
+ t2 >>= 2;
+ fprintf(stderr, "DSA-(%lu, %lu) make_key took %15"PRI64"u cycles\n", (unsigned long)groups[x].group*8, (unsigned long)groups[x].modulus*8, t2);
+ dsa_free(&key);
+ }
+ fprintf(stderr, "\n\n");
+}
+#else
+static void time_dsa(void) { fprintf(stderr, "NO DSA\n"); }
+#endif
+
+
+#if defined(LTC_MRSA) && defined(LTC_TEST_MPI)
+/* time various RSA operations */
+static void time_rsa(void)
+{
+ rsa_key key;
+ ulong64 t1, t2;
+ unsigned char buf[2][2048] = { 0 };
+ unsigned long x, y, z, zzz;
+ int err, zz, stat;
+
+ for (x = 1024; x <= 2048; x += 256) {
+ t2 = 0;
+ for (y = 0; y < 4; y++) {
+ t_start();
+ t1 = t_read();
+ if ((err = rsa_make_key(&yarrow_prng, find_prng("yarrow"), x/8, 65537, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nrsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+
+#ifdef LTC_PROFILE
+ t2 <<= 2;
+ break;
+#endif
+
+ if (y < 3) {
+ rsa_free(&key);
+ }
+ }
+ t2 >>= 2;
+ fprintf(stderr, "RSA-%lu make_key took %15"PRI64"u cycles\n", x, t2);
+
+ t2 = 0;
+ for (y = 0; y < 16; y++) {
+ t_start();
+ t1 = t_read();
+ z = sizeof(buf[1]);
+ if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, (const unsigned char *)"testprog", 8, &yarrow_prng,
+ find_prng("yarrow"), find_hash("sha1"),
+ &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+#ifdef LTC_PROFILE
+ t2 <<= 4;
+ break;
+#endif
+ }
+ t2 >>= 4;
+ fprintf(stderr, "RSA-%lu encrypt_key took %15"PRI64"u cycles\n", x, t2);
+
+ t2 = 0;
+ for (y = 0; y < 2048; y++) {
+ t_start();
+ t1 = t_read();
+ zzz = sizeof(buf[0]);
+ if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, (const unsigned char *)"testprog", 8, find_hash("sha1"),
+ &zz, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+#ifdef LTC_PROFILE
+ t2 <<= 11;
+ break;
+#endif
+ }
+ t2 >>= 11;
+ fprintf(stderr, "RSA-%lu decrypt_key took %15"PRI64"u cycles\n", x, t2);
+
+ t2 = 0;
+ for (y = 0; y < 256; y++) {
+ t_start();
+ t1 = t_read();
+ z = sizeof(buf[1]);
+ if ((err = rsa_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng,
+ find_prng("yarrow"), find_hash("sha1"), 8, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nrsa_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+#ifdef LTC_PROFILE
+ t2 <<= 8;
+ break;
+#endif
+ }
+ t2 >>= 8;
+ fprintf(stderr, "RSA-%lu sign_hash took %15"PRI64"u cycles\n", x, t2);
+
+ t2 = 0;
+ for (y = 0; y < 2048; y++) {
+ t_start();
+ t1 = t_read();
+ if ((err = rsa_verify_hash(buf[1], z, buf[0], 20, find_hash("sha1"), 8, &stat, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nrsa_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ if (stat == 0) {
+ fprintf(stderr, "\n\nrsa_verify_hash for RSA-%lu failed to verify signature(%lu)\n", x, y);
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+#ifdef LTC_PROFILE
+ t2 <<= 11;
+ break;
+#endif
+ }
+ t2 >>= 11;
+ fprintf(stderr, "RSA-%lu verify_hash took %15"PRI64"u cycles\n", x, t2);
+ fprintf(stderr, "\n\n");
+ rsa_free(&key);
+ }
+}
+#else
+static void time_rsa(void) { fprintf(stderr, "NO RSA\n"); }
+#endif
+
+#if defined(LTC_MKAT) && defined(LTC_TEST_MPI)
+/* time various KAT operations */
+static void time_katja(void)
+{
+ katja_key key;
+ ulong64 t1, t2;
+ unsigned char buf[2][4096];
+ unsigned long x, y, z, zzz;
+ int err, zz;
+
+ for (x = 1024; x <= 2048; x += 256) {
+ t2 = 0;
+ for (y = 0; y < 4; y++) {
+ t_start();
+ t1 = t_read();
+ if ((err = katja_make_key(&yarrow_prng, find_prng("yarrow"), x/8, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nkatja_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+
+ if (y < 3) {
+ katja_free(&key);
+ }
+ }
+ t2 >>= 2;
+ fprintf(stderr, "Katja-%lu make_key took %15"PRI64"u cycles\n", x, t2);
+
+ t2 = 0;
+ for (y = 0; y < 16; y++) {
+ t_start();
+ t1 = t_read();
+ z = sizeof(buf[1]);
+ if ((err = katja_encrypt_key(buf[0], 32, buf[1], &z, "testprog", 8, &yarrow_prng,
+ find_prng("yarrow"), find_hash("sha1"),
+ &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nkatja_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+ }
+ t2 >>= 4;
+ fprintf(stderr, "Katja-%lu encrypt_key took %15"PRI64"u cycles\n", x, t2);
+
+ t2 = 0;
+ for (y = 0; y < 2048; y++) {
+ t_start();
+ t1 = t_read();
+ zzz = sizeof(buf[0]);
+ if ((err = katja_decrypt_key(buf[1], z, buf[0], &zzz, "testprog", 8, find_hash("sha1"),
+ &zz, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nkatja_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+ }
+ t2 >>= 11;
+ fprintf(stderr, "Katja-%lu decrypt_key took %15"PRI64"u cycles\n", x, t2);
+
+
+ katja_free(&key);
+ }
+}
+#else
+static void time_katja(void) { fprintf(stderr, "NO Katja\n"); }
+#endif
+
+#if defined(LTC_MDH) && defined(LTC_TEST_MPI)
+/* time various DH operations */
+static void time_dh(void)
+{
+ dh_key key;
+ ulong64 t1, t2;
+ unsigned long i, x, y;
+ int err;
+ static unsigned long sizes[] = {768/8, 1024/8, 1536/8, 2048/8,
+#ifndef TFM_DESC
+ 3072/8, 4096/8, 6144/8, 8192/8,
+#endif
+ 100000
+ };
+
+ for (x = sizes[i=0]; x < 100000; x = sizes[++i]) {
+ t2 = 0;
+ for (y = 0; y < 16; y++) {
+ if((err = dh_set_pg_groupsize(x, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\ndh_set_pg_groupsize says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+
+ t_start();
+ t1 = t_read();
+ if ((err = dh_generate_key(&yarrow_prng, find_prng("yarrow"), &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\ndh_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+
+ dh_free(&key);
+ }
+ t2 >>= 4;
+ fprintf(stderr, "DH-%4lu make_key took %15"PRI64"u cycles\n", x*8, t2);
+ }
+}
+#else
+static void time_dh(void) { fprintf(stderr, "NO DH\n"); }
+#endif
+
+#if defined(LTC_MECC) && defined(LTC_TEST_MPI)
+/* time various ECC operations */
+static void time_ecc(void)
+{
+ ecc_key key;
+ ulong64 t1, t2;
+ unsigned char buf[2][256] = { 0 };
+ unsigned long i, w, x, y, z;
+ int err, stat;
+ static unsigned long sizes[] = {
+#ifdef LTC_ECC112
+112/8,
+#endif
+#ifdef LTC_ECC128
+128/8,
+#endif
+#ifdef LTC_ECC160
+160/8,
+#endif
+#ifdef LTC_ECC192
+192/8,
+#endif
+#ifdef LTC_ECC224
+224/8,
+#endif
+#ifdef LTC_ECC256
+256/8,
+#endif
+#ifdef LTC_ECC384
+384/8,
+#endif
+#ifdef LTC_ECC521
+521/8,
+#endif
+100000};
+
+ for (x = sizes[i=0]; x < 100000; x = sizes[++i]) {
+ t2 = 0;
+ for (y = 0; y < 256; y++) {
+ t_start();
+ t1 = t_read();
+ if ((err = ecc_make_key(&yarrow_prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\necc_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+
+#ifdef LTC_PROFILE
+ t2 <<= 8;
+ break;
+#endif
+
+ if (y < 255) {
+ ecc_free(&key);
+ }
+ }
+ t2 >>= 8;
+ fprintf(stderr, "ECC-%lu make_key took %15"PRI64"u cycles\n", x*8, t2);
+
+ t2 = 0;
+ for (y = 0; y < 256; y++) {
+ t_start();
+ t1 = t_read();
+ z = sizeof(buf[1]);
+ if ((err = ecc_encrypt_key(buf[0], 20, buf[1], &z, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"),
+ &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\necc_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+#ifdef LTC_PROFILE
+ t2 <<= 8;
+ break;
+#endif
+ }
+ t2 >>= 8;
+ fprintf(stderr, "ECC-%lu encrypt_key took %15"PRI64"u cycles\n", x*8, t2);
+
+ t2 = 0;
+ for (y = 0; y < 256; y++) {
+ t_start();
+ t1 = t_read();
+ w = 20;
+ if ((err = ecc_decrypt_key(buf[1], z, buf[0], &w, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\necc_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+#ifdef LTC_PROFILE
+ t2 <<= 8;
+ break;
+#endif
+ }
+ t2 >>= 8;
+ fprintf(stderr, "ECC-%lu decrypt_key took %15"PRI64"u cycles\n", x*8, t2);
+
+ t2 = 0;
+ for (y = 0; y < 256; y++) {
+ t_start();
+ t1 = t_read();
+ z = sizeof(buf[1]);
+ if ((err = ecc_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng,
+ find_prng("yarrow"), &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\necc_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+#ifdef LTC_PROFILE
+ t2 <<= 8;
+ break;
+#endif
+ }
+ t2 >>= 8;
+ fprintf(stderr, "ECC-%lu sign_hash took %15"PRI64"u cycles\n", x*8, t2);
+
+ t2 = 0;
+ for (y = 0; y < 256; y++) {
+ t_start();
+ t1 = t_read();
+ if ((err = ecc_verify_hash(buf[1], z, buf[0], 20, &stat, &key)) != CRYPT_OK) {
+ fprintf(stderr, "\n\necc_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
+ exit(EXIT_FAILURE);
+ }
+ if (stat == 0) {
+ fprintf(stderr, "\n\necc_verify_hash for ECC-%lu failed to verify signature(%lu)\n", x*8, y);
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ t2 += t1;
+#ifdef LTC_PROFILE
+ t2 <<= 8;
+ break;
+#endif
+ }
+ t2 >>= 8;
+ fprintf(stderr, "ECC-%lu verify_hash took %15"PRI64"u cycles\n", x*8, t2);
+
+ fprintf(stderr, "\n\n");
+ ecc_free(&key);
+ }
+}
+#else
+static void time_ecc(void) { fprintf(stderr, "NO ECC\n"); }
+#endif
+
+static void time_macs_(unsigned long MAC_SIZE)
+{
+#if defined(LTC_OMAC) || defined(LTC_XCBC) || defined(LTC_F9_MODE) || defined(LTC_PMAC) || defined(LTC_PELICAN) || defined(LTC_HMAC)
+ unsigned char *buf, key[16], tag[16];
+ ulong64 t1, t2;
+ unsigned long x, z;
+ int err, cipher_idx, hash_idx;
+
+ fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE);
+
+ buf = XMALLOC(MAC_SIZE*1024);
+ if (buf == NULL) {
+ fprintf(stderr, "\n\nout of heap yo\n\n");
+ exit(EXIT_FAILURE);
+ }
+
+ cipher_idx = find_cipher("aes");
+ hash_idx = find_hash("sha1");
+
+ if (cipher_idx == -1 || hash_idx == -1) {
+ fprintf(stderr, "Warning the MAC tests requires AES and SHA1 to operate... so sorry\n");
+ exit(EXIT_FAILURE);
+ }
+
+ yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng);
+ yarrow_read(key, 16, &yarrow_prng);
+
+#ifdef LTC_OMAC
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = omac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nomac-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "OMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024));
+#endif
+
+#ifdef LTC_XCBC
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = xcbc_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nxcbc-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "XCBC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024));
+#endif
+
+#ifdef LTC_F9_MODE
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = f9_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nF9-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "F9-%s\t\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024));
+#endif
+
+#ifdef LTC_PMAC
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = pmac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
+ fprintf(stderr, "\n\npmac-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "PMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024));
+#endif
+
+#ifdef LTC_PELICAN
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = pelican_memory(key, 16, buf, MAC_SIZE*1024, tag)) != CRYPT_OK) {
+ fprintf(stderr, "\n\npelican error... %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "PELICAN \t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
+#endif
+
+#ifdef LTC_HMAC
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = hmac_memory(hash_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
+ fprintf(stderr, "\n\nhmac-%s error... %s\n", hash_descriptor[hash_idx].name, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "HMAC-%s\t\t%9"PRI64"u\n", hash_descriptor[hash_idx].name, t2/(ulong64)(MAC_SIZE*1024));
+#endif
+
+ XFREE(buf);
+#else
+ LTC_UNUSED_PARAM(MAC_SIZE);
+ fprintf(stderr, "NO MACs\n");
+#endif
+}
+
+static void time_macs(void)
+{
+ time_macs_(1);
+ time_macs_(4);
+ time_macs_(32);
+}
+
+static void time_encmacs_(unsigned long MAC_SIZE)
+{
+#if defined(LTC_EAX_MODE) || defined(LTC_OCB_MODE) || defined(LTC_OCB3_MODE) || defined(LTC_CCM_MODE) || defined(LTC_GCM_MODE)
+ unsigned char *buf, IV[16], key[16], tag[16];
+ ulong64 t1, t2;
+ unsigned long x, z;
+ int err, cipher_idx;
+ symmetric_key skey;
+
+ fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE);
+
+ buf = XMALLOC(MAC_SIZE*1024);
+ if (buf == NULL) {
+ fprintf(stderr, "\n\nout of heap yo\n\n");
+ exit(EXIT_FAILURE);
+ }
+
+ cipher_idx = find_cipher("aes");
+
+ yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng);
+ yarrow_read(key, 16, &yarrow_prng);
+ yarrow_read(IV, 16, &yarrow_prng);
+
+#ifdef LTC_EAX_MODE
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = eax_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) {
+ fprintf(stderr, "\nEAX error... %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "EAX \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
+#endif
+
+#ifdef LTC_OCB_MODE
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = ocb_encrypt_authenticate_memory(cipher_idx, key, 16, IV, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) {
+ fprintf(stderr, "\nOCB error... %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "OCB \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
+#endif
+
+#ifdef LTC_OCB3_MODE
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = ocb3_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 15, (unsigned char*)"", 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) {
+ fprintf(stderr, "\nOCB3 error... %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "OCB3 \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
+#endif
+
+#ifdef LTC_CCM_MODE
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = ccm_memory(cipher_idx, key, 16, NULL, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
+ fprintf(stderr, "\nCCM error... %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "CCM (no-precomp) \t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
+
+ cipher_descriptor[cipher_idx].setup(key, 16, 0, &skey);
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = ccm_memory(cipher_idx, key, 16, &skey, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
+ fprintf(stderr, "\nCCM error... %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "CCM (precomp) \t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
+ cipher_descriptor[cipher_idx].done(&skey);
+#endif
+
+#ifdef LTC_GCM_MODE
+ t2 = -1;
+ for (x = 0; x < 100; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = gcm_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, GCM_ENCRYPT)) != CRYPT_OK) {
+ fprintf(stderr, "\nGCM error... %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "GCM (no-precomp)\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
+
+ {
+ gcm_state gcm
+#ifdef LTC_GCM_TABLES_SSE2
+__attribute__ ((aligned (16)))
+#endif
+;
+
+ if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); }
+ t2 = -1;
+ for (x = 0; x < 10000; x++) {
+ t_start();
+ t1 = t_read();
+ z = 16;
+ if ((err = gcm_reset(&gcm)) != CRYPT_OK) {
+ fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ if ((err = gcm_add_iv(&gcm, IV, 16)) != CRYPT_OK) {
+ fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ if ((err = gcm_add_aad(&gcm, NULL, 0)) != CRYPT_OK) {
+ fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ if ((err = gcm_process(&gcm, buf, MAC_SIZE*1024, buf, GCM_ENCRYPT)) != CRYPT_OK) {
+ fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+
+ if ((err = gcm_done(&gcm, tag, &z)) != CRYPT_OK) {
+ fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ t1 = t_read() - t1;
+ if (t1 < t2) t2 = t1;
+ }
+ fprintf(stderr, "GCM (precomp)\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
+ }
+
+#endif
+ XFREE(buf);
+#else
+ LTC_UNUSED_PARAM(MAC_SIZE);
+ fprintf(stderr, "NO ENCMACs\n");
+#endif
+
+}
+
+static void time_encmacs(void)
+{
+ time_encmacs_(1);
+ time_encmacs_(4);
+ time_encmacs_(32);
+}
+
+#define LTC_TEST_FN(f) { f, #f }
+int main(int argc, char **argv)
+{
+int err;
+
+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(time_katja)
+};
+char *single_test = NULL;
+unsigned int i;
init_timer();
-reg_algs();
+register_all_ciphers();
+register_all_hashes();
+register_all_prngs();
#ifdef USE_LTM
ltc_mp = ltm_desc;
@@ -12,31 +1437,32 @@ reg_algs();
ltc_mp = tfm_desc;
#elif defined(USE_GMP)
ltc_mp = gmp_desc;
-#else
- extern ltc_math_descriptor EXT_MATH_LIB;
- ltc_mp = EXT_MATH_LIB;
-#endif
-
-time_keysched();
-time_cipher();
-time_cipher2();
-time_cipher3();
-time_cipher4();
-time_hash();
-time_macs();
-time_encmacs();
-time_prng();
-time_mult();
-time_sqr();
-time_rsa();
-time_ecc();
-#ifdef USE_LTM
-time_katja();
+#elif defined(EXT_MATH_LIB)
+ {
+ extern ltc_math_descriptor EXT_MATH_LIB;
+ ltc_mp = EXT_MATH_LIB;
+ }
#endif
+
+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));
+ exit(EXIT_FAILURE);
+}
+
+/* single test name from commandline */
+if (argc > 1) single_test = argv[1];
+
+for (i = 0; i < sizeof(test_functions)/sizeof(test_functions[0]); ++i) {
+ if (single_test && strstr(test_functions[i].name, single_test) == NULL) {
+ continue;
+ }
+ test_functions[i].fn();
+}
+
return EXIT_SUCCESS;
}
-/* $Source$ */
-/* $Revision$ */
-/* $Date$ */
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/libtomcrypt/demos/tv_gen.c b/libtomcrypt/demos/tv_gen.c
index 4518ebd..127c114 100644
--- a/libtomcrypt/demos/tv_gen.c
+++ b/libtomcrypt/demos/tv_gen.c
@@ -1,129 +1,25 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
#include <tomcrypt.h>
-void reg_algs(void)
-{
- int err;
-
-#ifdef LTC_RIJNDAEL
- register_cipher (&aes_desc);
-#endif
-#ifdef LTC_BLOWFISH
- register_cipher (&blowfish_desc);
-#endif
-#ifdef LTC_XTEA
- register_cipher (&xtea_desc);
-#endif
-#ifdef LTC_RC5
- register_cipher (&rc5_desc);
-#endif
-#ifdef LTC_RC6
- register_cipher (&rc6_desc);
-#endif
-#ifdef LTC_SAFERP
- register_cipher (&saferp_desc);
-#endif
-#ifdef LTC_TWOFISH
- register_cipher (&twofish_desc);
-#endif
-#ifdef LTC_SAFER
- register_cipher (&safer_k64_desc);
- register_cipher (&safer_sk64_desc);
- register_cipher (&safer_k128_desc);
- register_cipher (&safer_sk128_desc);
-#endif
-#ifdef LTC_RC2
- register_cipher (&rc2_desc);
-#endif
-#ifdef LTC_DES
- register_cipher (&des_desc);
- register_cipher (&des3_desc);
-#endif
-#ifdef LTC_CAST5
- register_cipher (&cast5_desc);
-#endif
-#ifdef LTC_NOEKEON
- register_cipher (&noekeon_desc);
-#endif
-#ifdef LTC_SKIPJACK
- register_cipher (&skipjack_desc);
-#endif
-#ifdef LTC_ANUBIS
- register_cipher (&anubis_desc);
-#endif
-#ifdef LTC_KHAZAD
- register_cipher (&khazad_desc);
-#endif
-
-#ifdef LTC_TIGER
- register_hash (&tiger_desc);
-#endif
-#ifdef LTC_MD2
- register_hash (&md2_desc);
-#endif
-#ifdef LTC_MD4
- register_hash (&md4_desc);
-#endif
-#ifdef LTC_MD5
- register_hash (&md5_desc);
-#endif
-#ifdef LTC_SHA1
- register_hash (&sha1_desc);
-#endif
-#ifdef LTC_SHA224
- register_hash (&sha224_desc);
-#endif
-#ifdef LTC_SHA256
- register_hash (&sha256_desc);
-#endif
-#ifdef LTC_SHA384
- register_hash (&sha384_desc);
-#endif
-#ifdef LTC_SHA512
- register_hash (&sha512_desc);
-#endif
-#ifdef LTC_RIPEMD128
- register_hash (&rmd128_desc);
-#endif
-#ifdef LTC_RIPEMD160
- register_hash (&rmd160_desc);
-#endif
-#ifdef LTC_WHIRLPOOL
- register_hash (&whirlpool_desc);
-#endif
-#ifdef LTC_CHC_HASH
- register_hash(&chc_desc);
- if ((err = chc_register(register_cipher(&aes_desc))) != CRYPT_OK) {
- printf("chc_register error: %s\n", error_to_string(err));
- exit(EXIT_FAILURE);
- }
-#endif
-
-#ifdef USE_LTM
- ltc_mp = ltm_desc;
-#elif defined(USE_TFM)
- ltc_mp = tfm_desc;
-#elif defined(USE_GMP)
- ltc_mp = gmp_desc;
-#else
- extern ltc_math_descriptor EXT_MATH_LIB;
- ltc_mp = EXT_MATH_LIB;
-#endif
-
-
-}
-
void hash_gen(void)
{
unsigned char md[MAXBLOCKSIZE], *buf;
unsigned long outlen, x, y, z;
FILE *out;
int err;
-
+
out = fopen("hash_tv.txt", "w");
if (out == NULL) {
perror("can't open hash_tv");
}
-
+
fprintf(out, "Hash Test Vectors:\n\nThese are the hashes of nn bytes '00 01 02 03 .. (nn-1)'\n\n");
for (x = 0; hash_descriptor[x].name != NULL; x++) {
buf = XMALLOC(2 * hash_descriptor[x].blocksize + 1);
@@ -160,16 +56,16 @@ void cipher_gen(void)
int err, kl, lastkl;
FILE *out;
symmetric_key skey;
-
+
out = fopen("cipher_tv.txt", "w");
-
- fprintf(out,
+
+ fprintf(out,
"Cipher Test Vectors\n\nThese are test encryptions with key of nn bytes '00 01 02 03 .. (nn-1)' and original PT of the same style.\n"
"The output of step N is used as the key and plaintext for step N+1 (key bytes repeated as required to fill the key)\n\n");
-
+
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
fprintf(out, "Cipher: %s\n", cipher_descriptor[x].name);
-
+
/* three modes, smallest, medium, large keys */
lastkl = 10000;
for (y = 0; y < 3; y++) {
@@ -199,7 +95,7 @@ void cipher_gen(void)
printf("setup error: %s\n", error_to_string(err));
exit(EXIT_FAILURE);
}
-
+
for (z = 0; (int)z < cipher_descriptor[x].block_length; z++) {
pt[z] = (unsigned char)z;
}
@@ -226,7 +122,7 @@ void cipher_gen(void)
fprintf(out, "\n");
}
fclose(out);
-}
+}
void hmac_gen(void)
{
@@ -234,17 +130,17 @@ void hmac_gen(void)
int x, y, z, err;
FILE *out;
unsigned long len;
-
+
out = fopen("hmac_tv.txt", "w");
- fprintf(out,
-"LTC_HMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are LTC_HMACed. The initial key is\n"
-"of the same format (the same length as the HASH output size). The LTC_HMAC key in step N+1 is the LTC_HMAC output of\n"
+ fprintf(out,
+"HMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are HMACed. The initial key is\n"
+"of the same format (the same length as the HASH output size). The HMAC key in step N+1 is the HMAC output of\n"
"step N.\n\n");
for (x = 0; hash_descriptor[x].name != NULL; x++) {
- fprintf(out, "LTC_HMAC-%s\n", hash_descriptor[x].name);
-
+ fprintf(out, "HMAC-%s\n", hash_descriptor[x].name);
+
/* initial key */
for (y = 0; y < (int)hash_descriptor[x].hashsize; y++) {
key[y] = (y&255);
@@ -255,7 +151,7 @@ void hmac_gen(void)
perror("Can't malloc memory");
exit(EXIT_FAILURE);
}
-
+
for (y = 0; y <= (int)(hash_descriptor[x].blocksize * 2); y++) {
for (z = 0; z < y; z++) {
input[z] = (unsigned char)(z & 255);
@@ -279,19 +175,20 @@ void hmac_gen(void)
}
fclose(out);
}
-
+
void omac_gen(void)
{
+#ifdef LTC_OMAC
unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2];
int err, x, y, z, kl;
FILE *out;
unsigned long len;
-
+
out = fopen("omac_tv.txt", "w");
- fprintf(out,
-"LTC_OMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are LTC_OMAC'ed. The initial key is\n"
-"of the same format (length specified per cipher). The LTC_OMAC key in step N+1 is the LTC_OMAC output of\n"
+ fprintf(out,
+"OMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is\n"
+"of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of\n"
"step N (repeated as required to fill the array).\n\n");
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
@@ -303,13 +200,13 @@ void omac_gen(void)
if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) {
kl = cipher_descriptor[x].max_key_length;
}
- fprintf(out, "LTC_OMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
-
+ fprintf(out, "OMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
+
/* initial key/block */
for (y = 0; y < kl; y++) {
key[y] = (y & 255);
}
-
+
for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) {
for (z = 0; z < y; z++) {
input[z] = (unsigned char)(z & 255);
@@ -333,20 +230,22 @@ void omac_gen(void)
fprintf(out, "\n");
}
fclose(out);
+#endif
}
void pmac_gen(void)
{
+#ifdef LTC_PMAC
unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2];
int err, x, y, z, kl;
FILE *out;
unsigned long len;
-
+
out = fopen("pmac_tv.txt", "w");
- fprintf(out,
-"PMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are LTC_OMAC'ed. The initial key is\n"
-"of the same format (length specified per cipher). The LTC_OMAC key in step N+1 is the LTC_OMAC output of\n"
+ fprintf(out,
+"PMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are PMAC'ed. The initial key is\n"
+"of the same format (length specified per cipher). The PMAC key in step N+1 is the PMAC output of\n"
"step N (repeated as required to fill the array).\n\n");
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
@@ -359,12 +258,12 @@ void pmac_gen(void)
kl = cipher_descriptor[x].max_key_length;
}
fprintf(out, "PMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
-
+
/* initial key/block */
for (y = 0; y < kl; y++) {
key[y] = (y & 255);
}
-
+
for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) {
for (z = 0; z < y; z++) {
input[z] = (unsigned char)(z & 255);
@@ -388,13 +287,15 @@ void pmac_gen(void)
fprintf(out, "\n");
}
fclose(out);
+#endif
}
void eax_gen(void)
{
+#ifdef LTC_EAX_MODE
int err, kl, x, y1, z;
FILE *out;
- unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], header[MAXBLOCKSIZE*2],
+ unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], header[MAXBLOCKSIZE*2],
plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
unsigned long len;
@@ -418,7 +319,7 @@ void eax_gen(void)
for (z = 0; z < kl; z++) {
key[z] = (z & 255);
}
-
+
for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
for (z = 0; z < y1; z++) {
plaintext[z] = (unsigned char)(z & 255);
@@ -448,13 +349,15 @@ void eax_gen(void)
fprintf(out, "\n");
}
fclose(out);
+#endif
}
void ocb_gen(void)
{
+#ifdef LTC_OCB_MODE
int err, kl, x, y1, z;
FILE *out;
- unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2],
+ unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2],
plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
unsigned long len;
@@ -483,7 +386,7 @@ void ocb_gen(void)
for (z = 0; z < cipher_descriptor[x].block_length; z++) {
nonce[z] = z;
}
-
+
for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
for (z = 0; z < y1; z++) {
plaintext[z] = (unsigned char)(z & 255);
@@ -511,14 +414,81 @@ void ocb_gen(void)
fprintf(out, "\n");
}
fclose(out);
+#endif
}
+void ocb3_gen(void)
+{
+#ifdef LTC_OCB3_MODE
+ int err, kl, x, y1, z, noncelen;
+ FILE *out;
+ unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2],
+ plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
+ unsigned long len;
+
+ out = fopen("ocb3_tv.txt", "w");
+ fprintf(out, "OCB3 Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs\n"
+ "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n"
+ "step repeated sufficiently. The nonce is fixed throughout. AAD is fixed to 3 bytes (ASCII) 'AAD'.\n\n");
+
+ for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+ kl = cipher_descriptor[x].block_length;
+
+ /* skip ciphers which do not have 64 or 128 bit block sizes */
+ if (kl != 16) continue;
+
+ if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) {
+ kl = cipher_descriptor[x].max_key_length;
+ }
+ fprintf(out, "OCB3-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
+
+ /* the key */
+ for (z = 0; z < kl; z++) {
+ key[z] = (z & 255);
+ }
+
+ /* fixed nonce */
+ noncelen = MIN(15, cipher_descriptor[x].block_length);
+ for (z = 0; z < noncelen; z++) {
+ nonce[z] = z;
+ }
+
+ for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
+ for (z = 0; z < y1; z++) {
+ plaintext[z] = (unsigned char)(z & 255);
+ }
+ len = 16;
+ if ((err = ocb3_encrypt_authenticate_memory(x, key, kl, nonce, noncelen, (unsigned char*)"AAD", 3, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) {
+ printf("Error OCB3'ing: %s\n", error_to_string(err));
+ exit(EXIT_FAILURE);
+ }
+ fprintf(out, "%3d: ", y1);
+ for (z = 0; z < y1; z++) {
+ fprintf(out, "%02X", plaintext[z]);
+ }
+ fprintf(out, ", ");
+ for (z = 0; z <(int)len; z++) {
+ fprintf(out, "%02X", tag[z]);
+ }
+ fprintf(out, "\n");
+
+ /* forward the key */
+ for (z = 0; z < kl; z++) {
+ key[z] = tag[z % len];
+ }
+ }
+ fprintf(out, "\n");
+ }
+ fclose(out);
+#endif
+}
void ccm_gen(void)
{
+#ifdef LTC_CCM_MODE
int err, kl, x, y1, z;
FILE *out;
- unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2],
+ unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2],
plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
unsigned long len;
@@ -547,7 +517,7 @@ void ccm_gen(void)
for (z = 0; z < cipher_descriptor[x].block_length; z++) {
nonce[z] = z;
}
-
+
for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
for (z = 0; z < y1; z++) {
plaintext[z] = (unsigned char)(z & 255);
@@ -557,6 +527,10 @@ void ccm_gen(void)
printf("Error CCM'ing: %s\n", error_to_string(err));
exit(EXIT_FAILURE);
}
+ if (len == 0) {
+ printf("Error CCM'ing: zero length\n");
+ exit(EXIT_FAILURE);
+ }
fprintf(out, "%3d: ", y1);
for (z = 0; z < y1; z++) {
fprintf(out, "%02X", plaintext[z]);
@@ -575,10 +549,12 @@ void ccm_gen(void)
fprintf(out, "\n");
}
fclose(out);
+#endif
}
void gcm_gen(void)
{
+#ifdef LTC_GCM_MODE
int err, kl, x, y1, z;
FILE *out;
unsigned char key[MAXBLOCKSIZE], plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
@@ -604,8 +580,8 @@ void gcm_gen(void)
for (z = 0; z < kl; z++) {
key[z] = (z & 255);
}
-
- for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
+
+ for (y1 = 1; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
for (z = 0; z < y1; z++) {
plaintext[z] = (unsigned char)(z & 255);
}
@@ -614,6 +590,10 @@ void gcm_gen(void)
printf("Error GCM'ing: %s\n", error_to_string(err));
exit(EXIT_FAILURE);
}
+ if (len == 0) {
+ printf("Error GCM'ing: zero length\n");
+ exit(EXIT_FAILURE);
+ }
fprintf(out, "%3d: ", y1);
for (z = 0; z < y1; z++) {
fprintf(out, "%02X", plaintext[z]);
@@ -632,19 +612,20 @@ void gcm_gen(void)
fprintf(out, "\n");
}
fclose(out);
+#endif
}
void base64_gen(void)
{
FILE *out;
- unsigned char dst[256], src[32];
- unsigned long x, y, len;
-
+ unsigned char dst[256], src[32], ch;
+ unsigned long x, len;
+
out = fopen("base64_tv.txt", "w");
fprintf(out, "Base64 vectors. These are the base64 encodings of the strings 00,01,02...NN-1\n\n");
for (x = 0; x <= 32; x++) {
- for (y = 0; y < x; y++) {
- src[y] = y;
+ for (ch = 0; ch < x; ch++) {
+ src[ch] = ch;
}
len = sizeof(dst);
base64_encode(src, x, dst, &len);
@@ -681,7 +662,7 @@ void ecc_gen(void)
mp_read_radix(modulus, (char *)ltc_ecc_sets[x].prime, 16);
mp_read_radix(G->x, (char *)ltc_ecc_sets[x].Gx, 16);
mp_read_radix(G->y, (char *)ltc_ecc_sets[x].Gy, 16);
- mp_set(G->z, 1);
+ mp_set(G->z, 1);
while (mp_cmp(k, order) == LTC_MP_LT) {
ltc_mp.ecc_ptmul(k, G, R, modulus, 1);
@@ -699,11 +680,12 @@ void ecc_gen(void)
void lrw_gen(void)
{
+#ifdef LTC_LRW_MODE
FILE *out;
unsigned char tweak[16], key[16], iv[16], buf[1024];
int x, y, err;
symmetric_LRW lrw;
-
+
/* initialize default key and tweak */
for (x = 0; x < 16; x++) {
tweak[x] = key[x] = iv[x] = x;
@@ -760,27 +742,61 @@ void lrw_gen(void)
lrw_done(&lrw);
}
fclose(out);
-}
+#endif
+}
int main(void)
{
- reg_algs();
+ register_all_ciphers();
+ register_all_hashes();
+ register_all_prngs();
+#ifdef USE_LTM
+ ltc_mp = ltm_desc;
+#elif defined(USE_TFM)
+ ltc_mp = tfm_desc;
+#elif defined(USE_GMP)
+ ltc_mp = gmp_desc;
+#elif defined(EXT_MATH_LIB)
+ extern ltc_math_descriptor EXT_MATH_LIB;
+ ltc_mp = EXT_MATH_LIB;
+#else
+ fprintf(stderr, "No MPI provider available\n");
+ exit(EXIT_FAILURE);
+#endif
+
printf("Generating hash vectors..."); fflush(stdout); hash_gen(); printf("done\n");
printf("Generating cipher vectors..."); fflush(stdout); cipher_gen(); printf("done\n");
- printf("Generating LTC_HMAC vectors..."); fflush(stdout); hmac_gen(); printf("done\n");
- printf("Generating LTC_OMAC vectors..."); fflush(stdout); omac_gen(); printf("done\n");
+ printf("Generating HMAC vectors..."); fflush(stdout); hmac_gen(); printf("done\n");
+#ifdef LTC_OMAC
+ printf("Generating OMAC vectors..."); fflush(stdout); omac_gen(); printf("done\n");
+#endif
+#ifdef LTC_PMAC
printf("Generating PMAC vectors..."); fflush(stdout); pmac_gen(); printf("done\n");
+#endif
+#ifdef LTC_EAX_MODE
printf("Generating EAX vectors..."); fflush(stdout); eax_gen(); printf("done\n");
+#endif
+#ifdef LTC_OCB_MODE
printf("Generating OCB vectors..."); fflush(stdout); ocb_gen(); printf("done\n");
+#endif
+#ifdef LTC_OCB3_MODE
+ printf("Generating OCB3 vectors..."); fflush(stdout); ocb3_gen(); printf("done\n");
+#endif
+#ifdef LTC_CCM_MODE
printf("Generating CCM vectors..."); fflush(stdout); ccm_gen(); printf("done\n");
+#endif
+#ifdef LTC_GCM_MODE
printf("Generating GCM vectors..."); fflush(stdout); gcm_gen(); printf("done\n");
- printf("Generating LTC_BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n");
+#endif
+ printf("Generating BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n");
printf("Generating MATH vectors..."); fflush(stdout); math_gen(); printf("done\n");
printf("Generating ECC vectors..."); fflush(stdout); ecc_gen(); printf("done\n");
+#ifdef LTC_LRW_MODE
printf("Generating LRW vectors..."); fflush(stdout); lrw_gen(); printf("done\n");
+#endif
return 0;
}
-/* $Source$ */
-/* $Revision$ */
-/* $Date$ */
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */