diff --git a/demos/constants.c b/demos/constants.c index 32af20b..d5d3622 100644 --- a/demos/constants.c +++ b/demos/constants.c @@ -8,6 +8,12 @@ */ #include "tomcrypt.h" +#if _POSIX_C_SOURCE >= 200112L +#include +#else +#define basename(x) x +#endif + /** @file demo_crypt_constants.c @@ -17,33 +23,61 @@ Larry Bugbee, February 2013 */ +static void _print_line(const char* cmd, const char* desc) +{ + printf(" %-16s - %s\n", cmd, desc); +} -int main(void) { - /* 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; +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); + 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 */ + /* 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); + 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); + /* 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("", "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; + return 0; } diff --git a/demos/demo_dynamic.py b/demos/demo_dynamic.py old mode 100755 new mode 100644 index 97e4855..ce404b6 --- a/demos/demo_dynamic.py +++ b/demos/demo_dynamic.py @@ -1,7 +1,7 @@ """ - demo_dynamic.py v1 + demo_dynamic.py v2b This program demonstrates Python's use of the dynamic language support additions to LTC, namely access to LTC @@ -19,26 +19,26 @@ load multiple .dylibs, but it does not support this level of tight coupling between otherwise independent libraries.) - My .dylib was created on OSX with the following steps: + 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 - 1- compile LTC to a .a static lib: - CFLAGS="-DLTM_DESC -DUSE_LTM" make - - 2- link LTC and LTM into a single .dylib: - ar2dylib_with tomcrypt tommath - where ar2dylib_with is a shell script that combines - the LTC .a with the LTM .dylib + 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 depend - on a mathlib. For example, public key crypto - needs a mathlib; hashing and symmetric encryption - do not. + 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 written for Python 2.7. + This code was written for Python 2.7 with the ctypes standard + library. Larry Bugbee - March 2014 + March 2014 v1 + August 2017 v2b """ @@ -46,15 +46,24 @@ 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') + + +#------------------------------------------------------------------------------- # load the .dylib libname = 'tomcrypt' libpath = find_library(libname) - -print -print(' demo_dynamic.py') print print(' path to library %s: %s' % (libname, libpath)) @@ -63,19 +72,19 @@ 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 1: +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 \n' % str_len.value + 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. @@ -85,13 +94,14 @@ if 1: print -if 1: +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 \n' % str_len.value + 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. @@ -101,11 +111,12 @@ if 1: print -#--------------------------------------------------------------- +#------------------------------------------------------------------------------- # get individually named constants and sizes # print selected constants -if 1: +if SHOW_SELECTED_CONSTANTS: + print '-'*60 print '\n selected constants:' names = [ @@ -120,9 +131,11 @@ if 1: rc = LTC.crypt_get_constant(name, byref(const_value)) value = const_value.value print ' %-25s %d' % (name, value) + print # print selected sizes -if 1: +if SHOW_SELECTED_SIZES: + print '-'*60 print '\n selected sizes:' names = [ @@ -139,44 +152,62 @@ if 1: rc = LTC.crypt_get_size(name, byref(size_value)) value = size_value.value print ' %-25s %d' % (name, value) + print -#--------------------------------------------------------------- -#--------------------------------------------------------------- -# ctypes getting a list of this build's supported algorithms -# and compiler switches +#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- +# 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 -if 0: - print '\n%s' % ('-'*60) +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') - print - -#--------------------------------------------------------------- -#--------------------------------------------------------------- -# here is an example of how a wrapper can make Python access -# more Pythonic +#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- +# here is an example of how Python code can be written to access +# LTC's implementation of SHA256 and ChaCha, # - - - - - - - - - - - - - -# a wrapper fragment... +# definitions def _get_size(name): size = c_int(0) rc = LTC.crypt_get_size(name, byref(size)) + if rc != 0: + raise Exception('LTC.crypt_get_size(%s) rc = %d' % (name, rc)) return size.value -sha256_state_struct_size = _get_size('sha256_state') -sha512_state_struct_size = _get_size('sha512_state') +def _get_constant(name): + constant = c_int(0) + rc = LTC.crypt_get_constant(name, byref(constant)) + if rc != 0: + raise Exception('LTC.crypt_get_constant(%s) rc = %d' % (name, rc)) + return constant.value + +def _err2str(err): + # define return type + errstr = LTC.error_to_string + errstr.restype = c_char_p + # get and return err string + return errstr(err) + +CRYPT_OK = _get_constant('CRYPT_OK') class SHA256(object): def __init__(self): - self.state = c_buffer(sha256_state_struct_size) + self.state = c_buffer(_get_size('sha256_state')) LTC.sha256_init(byref(self.state)) def update(self, data): LTC.sha256_process(byref(self.state), data, len(data)) @@ -185,22 +216,68 @@ class SHA256(object): 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('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 + # - - - - - - - - - - - - - -# an app fragment... +# a SHA256 app fragment # from wrapper import * # uncomment in real life -data = 'hello world' +if SHOW_SHA256_EXAMPLE: + print '-'*60 + data = 'hello world' -sha256 = SHA256() -sha256.update(data) -md = sha256.digest() + sha256 = SHA256() + sha256.update(data) + md = sha256.digest() -template = '\n\n the SHA256 digest for "%s" is %s \n' -print template % (data, md.encode('hex')) + template = '\n the SHA256 digest for "%s" is %s \n' + print template % (data, md.encode('hex')) +# - - - - - - - - - - - - - +# a ChaCha app fragment +if SHOW_CHACHA_EXAMPLE: + print '-'*60 + key = 'hownowbrowncow\x00\x00' # exactly 16 or 32 bytes + rounds = 12 # common values: 8, 12, 20 + iv = '123456789012' # exactly 12 bytes + plain = '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, cipher.encode('hex')) + + # reset to decrypt + cha.set_iv32(iv) + decrypted = cha.crypt(cipher) + + template = ' ChaCha%d decoded text for "%s" is "%s" \n' + print template % (rounds, plain, decrypted) + +# 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/demos/demo_dynamic.py3 b/demos/demo_dynamic.py3 new file mode 100644 index 0000000..568790a --- /dev/null +++ b/demos/demo_dynamic.py3 @@ -0,0 +1,314 @@ + + +""" + demo_dynamic.py3 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 was modified so that + it would run under both Python 2.7 and 3.6. You might want + to run a diff on the .py and .py3 files to see the differences + between the two languages. + + 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 .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 + +# print selected constants +if SHOW_SELECTED_CONSTANTS: + print('-'*60) + print('\n selected constants:') + + names = [ + b'ENDIAN_LITTLE', + b'ENDIAN_64BITWORD', + b'PK_PUBLIC', + b'MAX_RSA_SIZE', + 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(' ') + +# print selected sizes +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/demos/sizes.c b/demos/sizes.c index bc3f8a5..c2c07ef 100644 --- a/demos/sizes.c +++ b/demos/sizes.c @@ -6,8 +6,14 @@ * The library is free for all purposes without any express * guarantee it works. */ + #include "tomcrypt.h" +#if _POSIX_C_SOURCE >= 200112L +#include +#else +#define basename(x) x +#endif /** @file demo_crypt_sizes.c @@ -15,29 +21,57 @@ like Python - Larry Bugbee, February 2013 */ +static void _print_line(const char* cmd, const char* desc) +{ + printf(" %-16s - %s\n", cmd, desc); +} -int main(void) { +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); - /* 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 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); - return 0; + /* 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("", "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$ */ diff --git a/src/headers/tomcrypt_cfg.h b/src/headers/tomcrypt_cfg.h index d4000d1..8c0866b 100644 --- a/src/headers/tomcrypt_cfg.h +++ b/src/headers/tomcrypt_cfg.h @@ -64,6 +64,11 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); #define ARGTYPE 0 #endif +#undef LTC_ENCRYPT +#define LTC_ENCRYPT 0 +#undef LTC_DECRYPT +#define LTC_DECRYPT 1 + /* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code * * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes. diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index 3834f4f..6839e2d 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -875,8 +875,8 @@ int ctr_test(void); #ifdef LTC_LRW_MODE -#define LRW_ENCRYPT 0 -#define LRW_DECRYPT 1 +#define LRW_ENCRYPT LTC_ENCRYPT +#define LRW_DECRYPT LTC_DECRYPT int lrw_start( int cipher, const unsigned char *IV, diff --git a/src/headers/tomcrypt_mac.h b/src/headers/tomcrypt_mac.h index 3fe431f..4081cc7 100644 --- a/src/headers/tomcrypt_mac.h +++ b/src/headers/tomcrypt_mac.h @@ -311,8 +311,8 @@ void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const #ifdef LTC_CCM_MODE -#define CCM_ENCRYPT 0 -#define CCM_DECRYPT 1 +#define CCM_ENCRYPT LTC_ENCRYPT +#define CCM_DECRYPT LTC_DECRYPT typedef struct { symmetric_key K; @@ -378,8 +378,8 @@ extern const unsigned char gcm_shift_table[]; #ifdef LTC_GCM_MODE -#define GCM_ENCRYPT 0 -#define GCM_DECRYPT 1 +#define GCM_ENCRYPT LTC_ENCRYPT +#define GCM_DECRYPT LTC_DECRYPT #define LTC_GCM_MODE_IV 0 #define LTC_GCM_MODE_AAD 1 @@ -542,8 +542,8 @@ typedef struct { int aadflg; } chacha20poly1305_state; -#define CHCHA20POLY1305_ENCRYPT 0 -#define CHCHA20POLY1305_DECRYPT 1 +#define CHCHA20POLY1305_ENCRYPT LTC_ENCRYPT +#define CHCHA20POLY1305_DECRYPT LTC_DECRYPT int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen); int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen); diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index 00a6c13..3171efd 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -198,13 +198,6 @@ int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); /* ---- DH Routines ---- */ #ifdef LTC_MDH -typedef struct { - int size; - char *name, *base, *prime; -} ltc_dh_set_type; - -extern const ltc_dh_set_type ltc_dh_sets[]; - typedef struct { int type; void *x; @@ -235,6 +228,13 @@ void dh_free(dh_key *key); int dh_export_key(void *out, unsigned long *outlen, int type, dh_key *key); #ifdef LTC_SOURCE +typedef struct { + int size; + char *name, *base, *prime; +} ltc_dh_set_type; + +extern const ltc_dh_set_type ltc_dh_sets[]; + /* internal helper functions */ int dh_check_pubkey(dh_key *key); #endif diff --git a/src/misc/crypt/crypt_constants.c b/src/misc/crypt/crypt_constants.c index 5fe0ecc..a6c4b46 100644 --- a/src/misc/crypt/crypt_constants.c +++ b/src/misc/crypt/crypt_constants.c @@ -26,11 +26,39 @@ typedef struct { #define _C_STRINGIFY(s) { #s, s } static const crypt_constant _crypt_constants[] = { + + _C_STRINGIFY(CRYPT_OK), + _C_STRINGIFY(CRYPT_ERROR), + _C_STRINGIFY(CRYPT_NOP), + _C_STRINGIFY(CRYPT_INVALID_KEYSIZE), + _C_STRINGIFY(CRYPT_INVALID_ROUNDS), + _C_STRINGIFY(CRYPT_FAIL_TESTVECTOR), + _C_STRINGIFY(CRYPT_BUFFER_OVERFLOW), + _C_STRINGIFY(CRYPT_INVALID_PACKET), + _C_STRINGIFY(CRYPT_INVALID_PRNGSIZE), + _C_STRINGIFY(CRYPT_ERROR_READPRNG), + _C_STRINGIFY(CRYPT_INVALID_CIPHER), + _C_STRINGIFY(CRYPT_INVALID_HASH), + _C_STRINGIFY(CRYPT_INVALID_PRNG), + _C_STRINGIFY(CRYPT_MEM), + _C_STRINGIFY(CRYPT_PK_TYPE_MISMATCH), + _C_STRINGIFY(CRYPT_PK_NOT_PRIVATE), + _C_STRINGIFY(CRYPT_INVALID_ARG), + _C_STRINGIFY(CRYPT_FILE_NOTFOUND), + _C_STRINGIFY(CRYPT_PK_INVALID_TYPE), + _C_STRINGIFY(CRYPT_OVERFLOW), + _C_STRINGIFY(CRYPT_UNUSED1), + _C_STRINGIFY(CRYPT_UNUSED2), + _C_STRINGIFY(CRYPT_PK_INVALID_SIZE), + _C_STRINGIFY(CRYPT_INVALID_PRIME_SIZE), + _C_STRINGIFY(CRYPT_PK_INVALID_PADDING), + _C_STRINGIFY(CRYPT_HASH_OVERFLOW), + _C_STRINGIFY(PK_PUBLIC), _C_STRINGIFY(PK_PRIVATE), - _C_STRINGIFY(PKA_RSA), - _C_STRINGIFY(PKA_DSA), + _C_STRINGIFY(LTC_ENCRYPT), + _C_STRINGIFY(LTC_DECRYPT), #ifdef LTC_PKCS_1 {"LTC_PKCS_1", 1}, @@ -42,6 +70,7 @@ static const crypt_constant _crypt_constants[] = { _C_STRINGIFY(LTC_PKCS_1_V1_5), _C_STRINGIFY(LTC_PKCS_1_OAEP), _C_STRINGIFY(LTC_PKCS_1_PSS), + _C_STRINGIFY(LTC_PKCS_1_V1_5_NA1), #else {"LTC_PKCS_1", 0}, #endif @@ -85,6 +114,31 @@ static const crypt_constant _crypt_constants[] = { _C_STRINGIFY(LTC_MILLER_RABIN_REPS), #endif +#ifdef LTC_DER +/* DER handling */ + _C_STRINGIFY(LTC_ASN1_EOL), + _C_STRINGIFY(LTC_ASN1_BOOLEAN), + _C_STRINGIFY(LTC_ASN1_INTEGER), + _C_STRINGIFY(LTC_ASN1_SHORT_INTEGER), + _C_STRINGIFY(LTC_ASN1_BIT_STRING), + _C_STRINGIFY(LTC_ASN1_OCTET_STRING), + _C_STRINGIFY(LTC_ASN1_NULL), + _C_STRINGIFY(LTC_ASN1_OBJECT_IDENTIFIER), + _C_STRINGIFY(LTC_ASN1_IA5_STRING), + _C_STRINGIFY(LTC_ASN1_PRINTABLE_STRING), + _C_STRINGIFY(LTC_ASN1_UTF8_STRING), + _C_STRINGIFY(LTC_ASN1_UTCTIME), + _C_STRINGIFY(LTC_ASN1_CHOICE), + _C_STRINGIFY(LTC_ASN1_SEQUENCE), + _C_STRINGIFY(LTC_ASN1_SET), + _C_STRINGIFY(LTC_ASN1_SETOF), + _C_STRINGIFY(LTC_ASN1_RAW_BIT_STRING), + _C_STRINGIFY(LTC_ASN1_TELETEX_STRING), + _C_STRINGIFY(LTC_ASN1_CONSTRUCTED), + _C_STRINGIFY(LTC_ASN1_CONTEXT_SPECIFIC), + _C_STRINGIFY(LTC_ASN1_GENERALIZEDTIME), +#endif + #ifdef LTC_CTR_MODE {"LTC_CTR_MODE", 1}, _C_STRINGIFY(CTR_COUNTER_LITTLE_ENDIAN), @@ -93,6 +147,14 @@ static const crypt_constant _crypt_constants[] = { #else {"LTC_CTR_MODE", 0}, #endif +#ifdef LTC_GCM_MODE + _C_STRINGIFY(LTC_GCM_MODE_IV), + _C_STRINGIFY(LTC_GCM_MODE_AAD), + _C_STRINGIFY(LTC_GCM_MODE_TEXT), +#endif + + _C_STRINGIFY(LTC_MP_NO), + _C_STRINGIFY(LTC_MP_YES), _C_STRINGIFY(MAXBLOCKSIZE), _C_STRINGIFY(TAB_SIZE), diff --git a/src/misc/crypt/crypt_sizes.c b/src/misc/crypt/crypt_sizes.c index 4b3d077..20ca471 100644 --- a/src/misc/crypt/crypt_sizes.c +++ b/src/misc/crypt/crypt_sizes.c @@ -30,8 +30,11 @@ static const crypt_size _crypt_sizes[] = { /* hash state sizes */ _SZ_STRINGIFY_S(ltc_hash_descriptor), _SZ_STRINGIFY_T(hash_state), -#ifdef LTC_SHA256 - _SZ_STRINGIFY_S(sha256_state), +#ifdef LTC_CHC_HASH + _SZ_STRINGIFY_S(chc_state), +#endif +#ifdef LTC_WHIRLPOOL + _SZ_STRINGIFY_S(whirlpool_state), #endif #ifdef LTC_SHA3 _SZ_STRINGIFY_S(sha3_state), @@ -39,17 +42,23 @@ static const crypt_size _crypt_sizes[] = { #ifdef LTC_SHA512 _SZ_STRINGIFY_S(sha512_state), #endif -#ifdef LTC_WHIRLPOOL - _SZ_STRINGIFY_S(whirlpool_state), +#ifdef LTC_SHA256 + _SZ_STRINGIFY_S(sha256_state), #endif -#ifdef LTC_MD2 - _SZ_STRINGIFY_S(md2_state), +#ifdef LTC_SHA1 + _SZ_STRINGIFY_S(sha1_state), +#endif +#ifdef LTC_MD5 + _SZ_STRINGIFY_S(md5_state), #endif #ifdef LTC_MD4 _SZ_STRINGIFY_S(md4_state), #endif -#ifdef LTC_MD5 - _SZ_STRINGIFY_S(md5_state), +#ifdef LTC_MD2 + _SZ_STRINGIFY_S(md2_state), +#endif +#ifdef LTC_TIGER + _SZ_STRINGIFY_S(tiger_state), #endif #ifdef LTC_RIPEMD128 _SZ_STRINGIFY_S(rmd128_state), @@ -63,21 +72,12 @@ static const crypt_size _crypt_sizes[] = { #ifdef LTC_RIPEMD320 _SZ_STRINGIFY_S(rmd320_state), #endif -#ifdef LTC_SHA1 - _SZ_STRINGIFY_S(sha1_state), -#endif -#ifdef LTC_TIGER - _SZ_STRINGIFY_S(tiger_state), -#endif #ifdef LTC_BLAKE2S _SZ_STRINGIFY_S(blake2s_state), #endif #ifdef LTC_BLAKE2B _SZ_STRINGIFY_S(blake2b_state), #endif -#ifdef LTC_CHC_HASH - _SZ_STRINGIFY_S(chc_state), -#endif /* block cipher key sizes */ _SZ_STRINGIFY_S(ltc_cipher_descriptor), @@ -142,46 +142,57 @@ static const crypt_size _crypt_sizes[] = { #endif /* mode sizes */ -#ifdef LTC_CBC_MODE - _SZ_STRINGIFY_T(symmetric_CBC), +#ifdef LTC_ECB_MODE + _SZ_STRINGIFY_T(symmetric_ECB), #endif #ifdef LTC_CFB_MODE _SZ_STRINGIFY_T(symmetric_CFB), #endif +#ifdef LTC_OFB_MODE + _SZ_STRINGIFY_T(symmetric_OFB), +#endif +#ifdef LTC_CBC_MODE + _SZ_STRINGIFY_T(symmetric_CBC), +#endif #ifdef LTC_CTR_MODE _SZ_STRINGIFY_T(symmetric_CTR), #endif -#ifdef LTC_ECB_MODE - _SZ_STRINGIFY_T(symmetric_ECB), -#endif -#ifdef LTC_F8_MODE - _SZ_STRINGIFY_T(symmetric_F8), -#endif #ifdef LTC_LRW_MODE _SZ_STRINGIFY_T(symmetric_LRW), #endif -#ifdef LTC_OFB_MODE - _SZ_STRINGIFY_T(symmetric_OFB), +#ifdef LTC_F8_MODE + _SZ_STRINGIFY_T(symmetric_F8), +#endif +#ifdef LTC_XTS_MODE + _SZ_STRINGIFY_T(symmetric_xts), +#endif + + /* stream cipher sizes */ +#ifdef LTC_CHACHA + _SZ_STRINGIFY_T(chacha_state), +#endif +#ifdef LTC_RC4_STREAM + _SZ_STRINGIFY_T(rc4_state), +#endif +#ifdef LTC_SOBER128_STREAM + _SZ_STRINGIFY_T(sober128_state), #endif /* MAC sizes -- no states for ccm, lrw */ -#ifdef LTC_F9_MODE - _SZ_STRINGIFY_T(f9_state), -#endif #ifdef LTC_HMAC _SZ_STRINGIFY_T(hmac_state), #endif #ifdef LTC_OMAC _SZ_STRINGIFY_T(omac_state), #endif -#ifdef LTC_PELICAN - _SZ_STRINGIFY_T(pelican_state), -#endif #ifdef LTC_PMAC _SZ_STRINGIFY_T(pmac_state), #endif -#ifdef LTC_XCBC - _SZ_STRINGIFY_T(xcbc_state), +#ifdef LTC_POLY1305 + _SZ_STRINGIFY_T(poly1305_state), +#endif +#ifdef LTC_EAX_MODE + _SZ_STRINGIFY_T(eax_state), #endif #ifdef LTC_OCB_MODE _SZ_STRINGIFY_T(ocb_state), @@ -189,17 +200,23 @@ static const crypt_size _crypt_sizes[] = { #ifdef LTC_OCB3_MODE _SZ_STRINGIFY_T(ocb3_state), #endif +#ifdef LTC_CCM_MODE + _SZ_STRINGIFY_T(ccm_state), +#endif #ifdef LTC_GCM_MODE _SZ_STRINGIFY_T(gcm_state), #endif -#ifdef LTC_EAX_MODE - _SZ_STRINGIFY_T(eax_state), +#ifdef LTC_PELICAN + _SZ_STRINGIFY_T(pelican_state), #endif -#ifdef LTC_CCM_MODE -/* not defined */ +#ifdef LTC_XCBC + _SZ_STRINGIFY_T(xcbc_state), #endif -#ifdef LRW_MODE -/* not defined */ +#ifdef LTC_F9_MODE + _SZ_STRINGIFY_T(f9_state), +#endif +#ifdef LTC_CHACHA20POLY1305_MODE + _SZ_STRINGIFY_T(chacha20poly1305_state), #endif /* asymmetric keys */ @@ -214,13 +231,20 @@ static const crypt_size _crypt_sizes[] = { #endif #ifdef LTC_MECC _SZ_STRINGIFY_T(ltc_ecc_set_type), - _SZ_STRINGIFY_T(ecc_key), _SZ_STRINGIFY_T(ecc_point), + _SZ_STRINGIFY_T(ecc_key), #endif #ifdef LTC_MKAT _SZ_STRINGIFY_T(katja_key), #endif + /* DER handling */ +#ifdef LTC_DER + _SZ_STRINGIFY_T(ltc_asn1_list), /* a list entry */ + _SZ_STRINGIFY_T(ltc_utctime), + _SZ_STRINGIFY_T(ltc_generalizedtime), +#endif + /* prng state sizes */ _SZ_STRINGIFY_S(ltc_prng_descriptor), _SZ_STRINGIFY_T(prng_state), @@ -248,6 +272,8 @@ static const crypt_size _crypt_sizes[] = { #ifdef LTC_CRC32 _SZ_STRINGIFY_T(crc32_state), #endif + + }; /* crypt_get_size()