From b79ae63408c4e9d3414e3ee8a78b3ecf137411b4 Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Tue, 8 Aug 2017 00:12:55 +0200 Subject: [PATCH 01/17] add missing items to crypt_sizes --- src/misc/crypt/crypt_sizes.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/misc/crypt/crypt_sizes.c b/src/misc/crypt/crypt_sizes.c index 4b3d077..45f029c 100644 --- a/src/misc/crypt/crypt_sizes.c +++ b/src/misc/crypt/crypt_sizes.c @@ -180,6 +180,15 @@ static const crypt_size _crypt_sizes[] = { #ifdef LTC_PMAC _SZ_STRINGIFY_T(pmac_state), #endif +#ifdef LTC_POLY1305 + _SZ_STRINGIFY_T(poly1305_state), +#endif +#ifdef LTC_BLAKE2SMAC + _SZ_STRINGIFY_T(blake2smac_state), +#endif +#ifdef LTC_BLAKE2BMAC + _SZ_STRINGIFY_T(blake2bmac_state), +#endif #ifdef LTC_XCBC _SZ_STRINGIFY_T(xcbc_state), #endif @@ -189,6 +198,9 @@ static const crypt_size _crypt_sizes[] = { #ifdef LTC_OCB3_MODE _SZ_STRINGIFY_T(ocb3_state), #endif +#ifdef LTC_CHACHA20POLY1305_MODE + _SZ_STRINGIFY_T(chacha20poly1305_state), +#endif #ifdef LTC_GCM_MODE _SZ_STRINGIFY_T(gcm_state), #endif @@ -196,10 +208,7 @@ static const crypt_size _crypt_sizes[] = { _SZ_STRINGIFY_T(eax_state), #endif #ifdef LTC_CCM_MODE -/* not defined */ -#endif -#ifdef LRW_MODE -/* not defined */ + _SZ_STRINGIFY_T(ccm_state), #endif /* asymmetric keys */ @@ -242,6 +251,16 @@ static const crypt_size _crypt_sizes[] = { /* sprng has no state as it uses other potentially available sources */ /* like /dev/random. See Developers Guide for more info. */ +#ifdef LTC_SOBER128_STREAM + _SZ_STRINGIFY_T(sober128_state), +#endif +#ifdef LTC_RC4_STREAM + _SZ_STRINGIFY_T(rc4_state), +#endif +#ifdef LTC_CHACHA + _SZ_STRINGIFY_T(chacha_state), +#endif + #ifdef LTC_ADLER32 _SZ_STRINGIFY_T(adler32_state), #endif From 9f02fde06eb2cbf21999e5632c46b083c7c7a717 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 8 Aug 2017 10:27:21 +0200 Subject: [PATCH 02/17] improve sizes demo a bit --- demos/sizes.c | 74 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 20 deletions(-) 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$ */ From 7a2aabf47e4361b14254ccdf44ae3343b39786ac Mon Sep 17 00:00:00 2001 From: Larry Bugbee Date: Tue, 8 Aug 2017 19:02:11 +0200 Subject: [PATCH 03/17] update crypt_constants.c --- src/misc/crypt/crypt_constants.c | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/misc/crypt/crypt_constants.c b/src/misc/crypt/crypt_constants.c index 5fe0ecc..9c1b5ae 100644 --- a/src/misc/crypt/crypt_constants.c +++ b/src/misc/crypt/crypt_constants.c @@ -26,9 +26,13 @@ typedef struct { #define _C_STRINGIFY(s) { #s, s } static const crypt_constant _crypt_constants[] = { + _C_STRINGIFY(PK_PUBLIC), _C_STRINGIFY(PK_PRIVATE), + {"LTC_ENCRYPT", 0}, /* good for all other xxx_ENCRYPT prefixes */ + {"LTC_DECRYPT", 1}, /* good for all other xxx_DECRYPT prefixes */ + _C_STRINGIFY(PKA_RSA), _C_STRINGIFY(PKA_DSA), @@ -42,6 +46,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 +90,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 +123,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), From a3a199e14bbc064187d7375f1183e51e0a073a22 Mon Sep 17 00:00:00 2001 From: Larry Bugbee Date: Tue, 8 Aug 2017 19:04:04 +0200 Subject: [PATCH 04/17] update crypt_sizes.c --- src/misc/crypt/crypt_sizes.c | 127 +++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 58 deletions(-) diff --git a/src/misc/crypt/crypt_sizes.c b/src/misc/crypt/crypt_sizes.c index 45f029c..fa3e684 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,55 +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_POLY1305 _SZ_STRINGIFY_T(poly1305_state), #endif -#ifdef LTC_BLAKE2SMAC - _SZ_STRINGIFY_T(blake2smac_state), -#endif -#ifdef LTC_BLAKE2BMAC - _SZ_STRINGIFY_T(blake2bmac_state), -#endif -#ifdef LTC_XCBC - _SZ_STRINGIFY_T(xcbc_state), +#ifdef LTC_EAX_MODE + _SZ_STRINGIFY_T(eax_state), #endif #ifdef LTC_OCB_MODE _SZ_STRINGIFY_T(ocb_state), @@ -198,17 +200,23 @@ static const crypt_size _crypt_sizes[] = { #ifdef LTC_OCB3_MODE _SZ_STRINGIFY_T(ocb3_state), #endif -#ifdef LTC_CHACHA20POLY1305_MODE - _SZ_STRINGIFY_T(chacha20poly1305_state), +#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 - _SZ_STRINGIFY_T(ccm_state), +#ifdef LTC_XCBC + _SZ_STRINGIFY_T(xcbc_state), +#endif +#ifdef LTC_F9_MODE + _SZ_STRINGIFY_T(f9_state), +#endif +#ifdef LTC_CHACHA20POLY1305_MODE + _SZ_STRINGIFY_T(chacha20poly1305_state), #endif /* asymmetric keys */ @@ -219,16 +227,27 @@ static const crypt_size _crypt_sizes[] = { _SZ_STRINGIFY_T(dsa_key), #endif #ifdef LTC_MDH + _SZ_STRINGIFY_T(ltc_dh_set_type), _SZ_STRINGIFY_T(dh_key), #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 +#ifdef LTC_SOURCE + _SZ_STRINGIFY_T(oid_st), +#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), @@ -251,22 +270,14 @@ static const crypt_size _crypt_sizes[] = { /* sprng has no state as it uses other potentially available sources */ /* like /dev/random. See Developers Guide for more info. */ -#ifdef LTC_SOBER128_STREAM - _SZ_STRINGIFY_T(sober128_state), -#endif -#ifdef LTC_RC4_STREAM - _SZ_STRINGIFY_T(rc4_state), -#endif -#ifdef LTC_CHACHA - _SZ_STRINGIFY_T(chacha_state), -#endif - #ifdef LTC_ADLER32 _SZ_STRINGIFY_T(adler32_state), #endif #ifdef LTC_CRC32 _SZ_STRINGIFY_T(crc32_state), #endif + + }; /* crypt_get_size() From 22822417c9499008e059427da0b4acf06c59b48a Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 8 Aug 2017 19:26:19 +0200 Subject: [PATCH 05/17] really define LTC_{DE,EN}CRYPT --- src/headers/tomcrypt_cfg.h | 5 +++++ src/headers/tomcrypt_cipher.h | 4 ++-- src/headers/tomcrypt_mac.h | 12 ++++++------ src/misc/crypt/crypt_constants.c | 4 ++-- 4 files changed, 15 insertions(+), 10 deletions(-) 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/misc/crypt/crypt_constants.c b/src/misc/crypt/crypt_constants.c index 9c1b5ae..18be43c 100644 --- a/src/misc/crypt/crypt_constants.c +++ b/src/misc/crypt/crypt_constants.c @@ -30,8 +30,8 @@ static const crypt_constant _crypt_constants[] = { _C_STRINGIFY(PK_PUBLIC), _C_STRINGIFY(PK_PRIVATE), - {"LTC_ENCRYPT", 0}, /* good for all other xxx_ENCRYPT prefixes */ - {"LTC_DECRYPT", 1}, /* good for all other xxx_DECRYPT prefixes */ + _C_STRINGIFY(LTC_ENCRYPT), + _C_STRINGIFY(LTC_DECRYPT), _C_STRINGIFY(PKA_RSA), _C_STRINGIFY(PKA_DSA), From d22b20833e5fd64b4d6d420ca63d2375909a3d53 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 8 Aug 2017 19:26:38 +0200 Subject: [PATCH 06/17] we don't expose internal structs --- src/misc/crypt/crypt_sizes.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/misc/crypt/crypt_sizes.c b/src/misc/crypt/crypt_sizes.c index fa3e684..609bb8d 100644 --- a/src/misc/crypt/crypt_sizes.c +++ b/src/misc/crypt/crypt_sizes.c @@ -238,9 +238,6 @@ static const crypt_size _crypt_sizes[] = { #ifdef LTC_MKAT _SZ_STRINGIFY_T(katja_key), #endif -#ifdef LTC_SOURCE - _SZ_STRINGIFY_T(oid_st), -#endif /* DER handling */ #ifdef LTC_DER From 91e5e8350be8e39516a9f38705f88c7b85bc6b6e Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Tue, 8 Aug 2017 19:35:11 +0200 Subject: [PATCH 07/17] ltc_dh_set_type can be hidden as well --- src/headers/tomcrypt_pk.h | 14 +++++++------- src/misc/crypt/crypt_sizes.c | 1 - 2 files changed, 7 insertions(+), 8 deletions(-) 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_sizes.c b/src/misc/crypt/crypt_sizes.c index 609bb8d..20ca471 100644 --- a/src/misc/crypt/crypt_sizes.c +++ b/src/misc/crypt/crypt_sizes.c @@ -227,7 +227,6 @@ static const crypt_size _crypt_sizes[] = { _SZ_STRINGIFY_T(dsa_key), #endif #ifdef LTC_MDH - _SZ_STRINGIFY_T(ltc_dh_set_type), _SZ_STRINGIFY_T(dh_key), #endif #ifdef LTC_MECC From 9f548c9928a96eaa353d95c98d8164254c04d5a1 Mon Sep 17 00:00:00 2001 From: Larry Bugbee Date: Wed, 9 Aug 2017 11:13:13 +0200 Subject: [PATCH 08/17] update demo_dynamic.py --- demos/demo_dynamic.py | 132 +++++++++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 39 deletions(-) mode change 100755 => 100644 demos/demo_dynamic.py diff --git a/demos/demo_dynamic.py b/demos/demo_dynamic.py old mode 100755 new mode 100644 index 97e4855..ffb3017 --- a/demos/demo_dynamic.py +++ b/demos/demo_dynamic.py @@ -1,7 +1,7 @@ """ - demo_dynamic.py v1 + demo_dynamic.py v2 This program demonstrates Python's use of the dynamic language support additions to LTC, namely access to LTC @@ -19,26 +19,21 @@ 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: - - 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 + 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 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. Larry Bugbee - March 2014 + March 2014 v1 + August 2017 v2 """ @@ -46,15 +41,23 @@ 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)) @@ -69,7 +72,8 @@ print # 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 @@ -85,7 +89,8 @@ if 1: print -if 1: +if SHOW_ALL_SIZES: + print '-'*60 print ' all supported sizes:' # get size to allocate for sizes output list @@ -105,7 +110,8 @@ if 1: # get individually named constants and sizes # print selected constants -if 1: +if SHOW_SELECTED_CONSTANTS: + print '-'*60 print '\n selected constants:' names = [ @@ -122,7 +128,8 @@ if 1: print ' %-25s %d' % (name, value) # print selected sizes -if 1: +if SHOW_SELECTED_SIZES: + print '-'*60 print '\n selected sizes:' names = [ @@ -143,14 +150,18 @@ if 1: #--------------------------------------------------------------- #--------------------------------------------------------------- -# 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') @@ -160,23 +171,31 @@ if 0: #--------------------------------------------------------------- #--------------------------------------------------------------- -# 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 + +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,19 +204,54 @@ 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) + 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' % 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' % 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" \n' + print template % (rounds, plain, cipher.encode('hex')) From a247583e6362c78b70626cde3eb9ac5fc0e1703c Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 9 Aug 2017 11:18:13 +0200 Subject: [PATCH 09/17] add error-codes to crypt_constants --- src/misc/crypt/crypt_constants.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/misc/crypt/crypt_constants.c b/src/misc/crypt/crypt_constants.c index 18be43c..44f196e 100644 --- a/src/misc/crypt/crypt_constants.c +++ b/src/misc/crypt/crypt_constants.c @@ -27,6 +27,33 @@ typedef struct { 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), From d5d4cadbde8ff39b0601840f26918fa7042c7282 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 9 Aug 2017 11:20:16 +0200 Subject: [PATCH 10/17] PKA_{D,R}SA shouldn't be public --- src/misc/crypt/crypt_constants.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/misc/crypt/crypt_constants.c b/src/misc/crypt/crypt_constants.c index 44f196e..a6c4b46 100644 --- a/src/misc/crypt/crypt_constants.c +++ b/src/misc/crypt/crypt_constants.c @@ -60,9 +60,6 @@ static const crypt_constant _crypt_constants[] = { _C_STRINGIFY(LTC_ENCRYPT), _C_STRINGIFY(LTC_DECRYPT), - _C_STRINGIFY(PKA_RSA), - _C_STRINGIFY(PKA_DSA), - #ifdef LTC_PKCS_1 {"LTC_PKCS_1", 1}, /* Block types */ From 35925eada534e5a3a1fcc1a158e42178fd88a11e Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 9 Aug 2017 11:48:59 +0200 Subject: [PATCH 11/17] improve constants demo --- demos/constants.c | 76 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 21 deletions(-) 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; } From 87d876f6ac2e32e6f3aa34ee86a2efc5e5e89e24 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 9 Aug 2017 12:10:42 +0200 Subject: [PATCH 12/17] add comment about usage to demo_dynamic [skip ci] --- demos/demo_dynamic.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/demos/demo_dynamic.py b/demos/demo_dynamic.py index ffb3017..69507d3 100644 --- a/demos/demo_dynamic.py +++ b/demos/demo_dynamic.py @@ -24,6 +24,10 @@ 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 From 695c3b235d5fc193cf4216524dac730470e53e3c Mon Sep 17 00:00:00 2001 From: Larry Bugbee Date: Thu, 10 Aug 2017 16:40:28 -0700 Subject: [PATCH 13/17] Update demo_dynamic.py added error strings (with function returning a string type) and a decryption to ChCha. --- demos/demo_dynamic.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/demos/demo_dynamic.py b/demos/demo_dynamic.py index 69507d3..3989e7c 100644 --- a/demos/demo_dynamic.py +++ b/demos/demo_dynamic.py @@ -1,7 +1,7 @@ """ - demo_dynamic.py v2 + demo_dynamic.py v2b This program demonstrates Python's use of the dynamic language support additions to LTC, namely access to LTC @@ -33,11 +33,12 @@ 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 v1 - August 2017 v2 + August 2017 v2b """ @@ -195,6 +196,13 @@ def _get_constant(name): 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): @@ -213,15 +221,17 @@ class ChaCha(object): 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' % err) + 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' % err) + raise Exception('LTC.chacha_crypt(), err = %d, "%s"' % (err, _err2str(err))) return dataout.raw # - - - - - - - - - - - - - @@ -254,8 +264,15 @@ if SHOW_CHACHA_EXAMPLE: cha.set_iv32(iv) cipher = cha.crypt(plain) - template = '\n ChaCha%d ciphertext for "%s" is "%s" \n' + 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) From ee55c4e51c5fe01eab94f73a2841df8b501e0635 Mon Sep 17 00:00:00 2001 From: Larry Bugbee Date: Fri, 11 Aug 2017 01:21:59 -0700 Subject: [PATCH 14/17] minor cleanup and formatting changes --- demos/demo_dynamic.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/demos/demo_dynamic.py b/demos/demo_dynamic.py index 3989e7c..7333beb 100644 --- a/demos/demo_dynamic.py +++ b/demos/demo_dynamic.py @@ -58,7 +58,8 @@ SHOW_CHACHA_EXAMPLE = True print print(' demo_dynamic.py') -#--------------------------------------------------------------- + +#------------------------------------------------------------------------------- # load the .dylib libname = 'tomcrypt' @@ -71,8 +72,7 @@ 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. @@ -84,7 +84,7 @@ if SHOW_ALL_CONSTANTS: # 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. @@ -101,7 +101,7 @@ if SHOW_ALL_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. @@ -111,7 +111,7 @@ if SHOW_ALL_SIZES: print -#--------------------------------------------------------------- +#------------------------------------------------------------------------------- # get individually named constants and sizes # print selected constants @@ -131,6 +131,7 @@ if SHOW_SELECTED_CONSTANTS: rc = LTC.crypt_get_constant(name, byref(const_value)) value = const_value.value print ' %-25s %d' % (name, value) + print # print selected sizes if SHOW_SELECTED_SIZES: @@ -151,10 +152,11 @@ if SHOW_SELECTED_SIZES: rc = LTC.crypt_get_size(name, byref(size_value)) value = size_value.value print ' %-25s %d' % (name, 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 @@ -170,12 +172,10 @@ if SHOW_BUILD_OPTIONS_ALGS: 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 Python code can be written to access # LTC's implementation of SHA256 and ChaCha, @@ -235,7 +235,7 @@ class ChaCha(object): return dataout.raw # - - - - - - - - - - - - - -# a SHA256 app fragment... +# a SHA256 app fragment # from wrapper import * # uncomment in real life @@ -251,7 +251,7 @@ if SHOW_SHA256_EXAMPLE: print template % (data, md.encode('hex')) # - - - - - - - - - - - - - -# a ChaCha app fragment... +# a ChaCha app fragment if SHOW_CHACHA_EXAMPLE: print '-'*60 @@ -274,8 +274,10 @@ if SHOW_CHACHA_EXAMPLE: 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 - -#--------------------------------------------------------------- -#--------------------------------------------------------------- -#--------------------------------------------------------------- +#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- From bab115c631ee076d50123871cb779fe0a0c74836 Mon Sep 17 00:00:00 2001 From: Larry Bugbee Date: Fri, 11 Aug 2017 01:27:21 -0700 Subject: [PATCH 15/17] converted demo_dynamic.py to Python3 --- demos/demo_dynamic.py3 | 314 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 demos/demo_dynamic.py3 diff --git a/demos/demo_dynamic.py3 b/demos/demo_dynamic.py3 new file mode 100644 index 0000000..3dc318e --- /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 + +#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- From 8b703c15058e620c527488280dd63e9f1fb3d4ee Mon Sep 17 00:00:00 2001 From: Larry Bugbee Date: Fri, 11 Aug 2017 02:16:26 -0700 Subject: [PATCH 16/17] remove traling space for Travis --- demos/demo_dynamic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/demo_dynamic.py b/demos/demo_dynamic.py index 7333beb..ce404b6 100644 --- a/demos/demo_dynamic.py +++ b/demos/demo_dynamic.py @@ -266,7 +266,7 @@ if SHOW_CHACHA_EXAMPLE: 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) From 6bbb450d40a4eecbb578a9e906cc9f643e880021 Mon Sep 17 00:00:00 2001 From: Larry Bugbee Date: Fri, 11 Aug 2017 02:17:31 -0700 Subject: [PATCH 17/17] remove trailing space --- demos/demo_dynamic.py3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/demo_dynamic.py3 b/demos/demo_dynamic.py3 index 3dc318e..568790a 100644 --- a/demos/demo_dynamic.py3 +++ b/demos/demo_dynamic.py3 @@ -298,7 +298,7 @@ if SHOW_CHACHA_EXAMPLE: 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)