From ff6abc776c80cb7d93a02986c8252c8028186293 Mon Sep 17 00:00:00 2001 From: Karel Miko Date: Tue, 21 Mar 2017 19:42:54 +0100 Subject: [PATCH] RFC 7539 - ChaCha20 and Poly1305 + chacha based PRNG --- libtomcrypt_VS2008.vcproj | 100 +++++++ makefile | 34 ++- makefile.icc | 34 ++- makefile.mingw | 34 ++- makefile.msvc | 34 ++- makefile.shared | 34 ++- makefile.unix | 34 ++- .../chachapoly/chacha20poly1305_add_aad.c | 34 +++ .../chachapoly/chacha20poly1305_decrypt.c | 44 +++ .../chachapoly/chacha20poly1305_done.c | 41 +++ .../chachapoly/chacha20poly1305_encrypt.c | 44 +++ .../chachapoly/chacha20poly1305_init.c | 26 ++ .../chachapoly/chacha20poly1305_memory.c | 70 +++++ .../chachapoly/chacha20poly1305_setiv.c | 64 +++++ .../chacha20poly1305_setiv_rfc7905.c | 36 +++ .../chachapoly/chacha20poly1305_test.c | 70 +++++ src/headers/tomcrypt_cipher.h | 21 ++ src/headers/tomcrypt_custom.h | 8 + src/headers/tomcrypt_mac.h | 50 ++++ src/headers/tomcrypt_prng.h | 24 ++ src/mac/poly1305/poly1305.c | 264 ++++++++++++++++++ src/mac/poly1305/poly1305_file.c | 70 +++++ src/mac/poly1305/poly1305_memory.c | 49 ++++ src/mac/poly1305/poly1305_memory_multi.c | 63 +++++ src/mac/poly1305/poly1305_test.c | 50 ++++ src/misc/crypt/crypt.c | 9 + src/misc/crypt/crypt_sizes.c | 3 + src/prngs/chacha.c | 214 ++++++++++++++ src/stream/chacha/chacha_crypt.c | 90 ++++++ src/stream/chacha/chacha_ivctr32.c | 42 +++ src/stream/chacha/chacha_ivctr64.c | 42 +++ src/stream/chacha/chacha_keystream.c | 34 +++ src/stream/chacha/chacha_setup.c | 60 ++++ src/stream/chacha/chacha_test.c | 60 ++++ testprof/cipher_hash_test.c | 5 + testprof/mac_test.c | 6 + testprof/x86_prof.c | 6 + 37 files changed, 1831 insertions(+), 72 deletions(-) create mode 100644 src/encauth/chachapoly/chacha20poly1305_add_aad.c create mode 100644 src/encauth/chachapoly/chacha20poly1305_decrypt.c create mode 100644 src/encauth/chachapoly/chacha20poly1305_done.c create mode 100644 src/encauth/chachapoly/chacha20poly1305_encrypt.c create mode 100644 src/encauth/chachapoly/chacha20poly1305_init.c create mode 100644 src/encauth/chachapoly/chacha20poly1305_memory.c create mode 100644 src/encauth/chachapoly/chacha20poly1305_setiv.c create mode 100644 src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c create mode 100644 src/encauth/chachapoly/chacha20poly1305_test.c create mode 100644 src/mac/poly1305/poly1305.c create mode 100644 src/mac/poly1305/poly1305_file.c create mode 100644 src/mac/poly1305/poly1305_memory.c create mode 100644 src/mac/poly1305/poly1305_memory_multi.c create mode 100644 src/mac/poly1305/poly1305_test.c create mode 100644 src/prngs/chacha.c create mode 100644 src/stream/chacha/chacha_crypt.c create mode 100644 src/stream/chacha/chacha_ivctr32.c create mode 100644 src/stream/chacha/chacha_ivctr64.c create mode 100644 src/stream/chacha/chacha_keystream.c create mode 100644 src/stream/chacha/chacha_setup.c create mode 100644 src/stream/chacha/chacha_test.c diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj index 24f12d1f..3214b22f 100644 --- a/libtomcrypt_VS2008.vcproj +++ b/libtomcrypt_VS2008.vcproj @@ -591,6 +591,46 @@ > + + + + + + + + + + + + + + + + + + + + @@ -1147,6 +1187,30 @@ > + + + + + + + + + + + + @@ -2207,6 +2271,10 @@ + + @@ -2280,6 +2348,38 @@ > + + + + + + + + + + + + + + + + diff --git a/makefile b/makefile index d3b80d59..afe08d05 100644 --- a/makefile +++ b/makefile @@ -49,15 +49,20 @@ src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphe src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_add_aad.o \ src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o src/encauth/ccm/ccm_init.o \ src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o src/encauth/ccm/ccm_reset.o \ -src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ -src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \ -src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \ -src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \ -src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \ -src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o src/encauth/gcm/gcm_process.o \ -src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o \ -src/encauth/ocb/ocb_decrypt_verify_memory.o src/encauth/ocb/ocb_done_decrypt.o \ -src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ccm/ccm_test.o src/encauth/chachapoly/chacha20poly1305_add_aad.o \ +src/encauth/chachapoly/chacha20poly1305_decrypt.o src/encauth/chachapoly/chacha20poly1305_done.o \ +src/encauth/chachapoly/chacha20poly1305_encrypt.o src/encauth/chachapoly/chacha20poly1305_init.o \ +src/encauth/chachapoly/chacha20poly1305_memory.o src/encauth/chachapoly/chacha20poly1305_setiv.o \ +src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \ +src/encauth/chachapoly/chacha20poly1305_test.o src/encauth/eax/eax_addheader.o \ +src/encauth/eax/eax_decrypt.o src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ +src/encauth/eax/eax_encrypt.o src/encauth/eax/eax_encrypt_authenticate_memory.o \ +src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ +src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ +src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ +src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ +src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \ src/encauth/ocb3/ocb3_add_aad.o src/encauth/ocb3/ocb3_decrypt.o src/encauth/ocb3/ocb3_decrypt_last.o \ @@ -81,7 +86,9 @@ src/mac/omac/omac_process.o src/mac/omac/omac_test.o src/mac/pelican/pelican.o \ src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o src/mac/pmac/pmac_done.o \ src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ -src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/poly1305/poly1305.o \ +src/mac/poly1305/poly1305_file.o src/mac/poly1305/poly1305_memory.o \ +src/mac/poly1305/poly1305_memory_multi.o src/mac/poly1305/poly1305_test.o src/mac/xcbc/xcbc_done.o \ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ @@ -173,8 +180,11 @@ src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_en src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \ src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_radix.o src/pk/rsa/rsa_import_x509.o \ src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \ -src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ -src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o +src/pk/rsa/rsa_verify_hash.o src/prngs/chacha.o src/prngs/fortuna.o src/prngs/rc4.o \ +src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \ +src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_ivctr32.o \ +src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \ +src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o HEADERS=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \ diff --git a/makefile.icc b/makefile.icc index f7589e01..cc24d302 100644 --- a/makefile.icc +++ b/makefile.icc @@ -106,15 +106,20 @@ src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphe src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_add_aad.o \ src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o src/encauth/ccm/ccm_init.o \ src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o src/encauth/ccm/ccm_reset.o \ -src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ -src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \ -src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \ -src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \ -src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \ -src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o src/encauth/gcm/gcm_process.o \ -src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o \ -src/encauth/ocb/ocb_decrypt_verify_memory.o src/encauth/ocb/ocb_done_decrypt.o \ -src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ccm/ccm_test.o src/encauth/chachapoly/chacha20poly1305_add_aad.o \ +src/encauth/chachapoly/chacha20poly1305_decrypt.o src/encauth/chachapoly/chacha20poly1305_done.o \ +src/encauth/chachapoly/chacha20poly1305_encrypt.o src/encauth/chachapoly/chacha20poly1305_init.o \ +src/encauth/chachapoly/chacha20poly1305_memory.o src/encauth/chachapoly/chacha20poly1305_setiv.o \ +src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \ +src/encauth/chachapoly/chacha20poly1305_test.o src/encauth/eax/eax_addheader.o \ +src/encauth/eax/eax_decrypt.o src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ +src/encauth/eax/eax_encrypt.o src/encauth/eax/eax_encrypt_authenticate_memory.o \ +src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ +src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ +src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ +src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ +src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \ src/encauth/ocb3/ocb3_add_aad.o src/encauth/ocb3/ocb3_decrypt.o src/encauth/ocb3/ocb3_decrypt_last.o \ @@ -138,7 +143,9 @@ src/mac/omac/omac_process.o src/mac/omac/omac_test.o src/mac/pelican/pelican.o \ src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o src/mac/pmac/pmac_done.o \ src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ -src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/poly1305/poly1305.o \ +src/mac/poly1305/poly1305_file.o src/mac/poly1305/poly1305_memory.o \ +src/mac/poly1305/poly1305_memory_multi.o src/mac/poly1305/poly1305_test.o src/mac/xcbc/xcbc_done.o \ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ @@ -230,8 +237,11 @@ src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_en src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \ src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_radix.o src/pk/rsa/rsa_import_x509.o \ src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \ -src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ -src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o +src/pk/rsa/rsa_verify_hash.o src/prngs/chacha.o src/prngs/fortuna.o src/prngs/rc4.o \ +src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \ +src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_ivctr32.o \ +src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \ +src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o HEADERS=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \ diff --git a/makefile.mingw b/makefile.mingw index c18e362f..253c2829 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -42,15 +42,20 @@ src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphe src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_add_aad.o \ src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o src/encauth/ccm/ccm_init.o \ src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o src/encauth/ccm/ccm_reset.o \ -src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ -src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \ -src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \ -src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \ -src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \ -src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o src/encauth/gcm/gcm_process.o \ -src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o \ -src/encauth/ocb/ocb_decrypt_verify_memory.o src/encauth/ocb/ocb_done_decrypt.o \ -src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ccm/ccm_test.o src/encauth/chachapoly/chacha20poly1305_add_aad.o \ +src/encauth/chachapoly/chacha20poly1305_decrypt.o src/encauth/chachapoly/chacha20poly1305_done.o \ +src/encauth/chachapoly/chacha20poly1305_encrypt.o src/encauth/chachapoly/chacha20poly1305_init.o \ +src/encauth/chachapoly/chacha20poly1305_memory.o src/encauth/chachapoly/chacha20poly1305_setiv.o \ +src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \ +src/encauth/chachapoly/chacha20poly1305_test.o src/encauth/eax/eax_addheader.o \ +src/encauth/eax/eax_decrypt.o src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ +src/encauth/eax/eax_encrypt.o src/encauth/eax/eax_encrypt_authenticate_memory.o \ +src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ +src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ +src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ +src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ +src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \ src/encauth/ocb3/ocb3_add_aad.o src/encauth/ocb3/ocb3_decrypt.o src/encauth/ocb3/ocb3_decrypt_last.o \ @@ -74,7 +79,9 @@ src/mac/omac/omac_process.o src/mac/omac/omac_test.o src/mac/pelican/pelican.o \ src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o src/mac/pmac/pmac_done.o \ src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ -src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/poly1305/poly1305.o \ +src/mac/poly1305/poly1305_file.o src/mac/poly1305/poly1305_memory.o \ +src/mac/poly1305/poly1305_memory_multi.o src/mac/poly1305/poly1305_test.o src/mac/xcbc/xcbc_done.o \ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ @@ -166,8 +173,11 @@ src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_en src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \ src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_radix.o src/pk/rsa/rsa_import_x509.o \ src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \ -src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ -src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o +src/pk/rsa/rsa_verify_hash.o src/prngs/chacha.o src/prngs/fortuna.o src/prngs/rc4.o \ +src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \ +src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_ivctr32.o \ +src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \ +src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o HEADERS=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \ diff --git a/makefile.msvc b/makefile.msvc index cb325b10..786c8d6c 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -16,15 +16,20 @@ src/ciphers/rc6.obj src/ciphers/safer/safer.obj src/ciphers/safer/saferp.obj src src/ciphers/twofish/twofish.obj src/ciphers/xtea.obj src/encauth/ccm/ccm_add_aad.obj \ src/encauth/ccm/ccm_add_nonce.obj src/encauth/ccm/ccm_done.obj src/encauth/ccm/ccm_init.obj \ src/encauth/ccm/ccm_memory.obj src/encauth/ccm/ccm_process.obj src/encauth/ccm/ccm_reset.obj \ -src/encauth/ccm/ccm_test.obj src/encauth/eax/eax_addheader.obj src/encauth/eax/eax_decrypt.obj \ -src/encauth/eax/eax_decrypt_verify_memory.obj src/encauth/eax/eax_done.obj src/encauth/eax/eax_encrypt.obj \ -src/encauth/eax/eax_encrypt_authenticate_memory.obj src/encauth/eax/eax_init.obj \ -src/encauth/eax/eax_test.obj src/encauth/gcm/gcm_add_aad.obj src/encauth/gcm/gcm_add_iv.obj \ -src/encauth/gcm/gcm_done.obj src/encauth/gcm/gcm_gf_mult.obj src/encauth/gcm/gcm_init.obj \ -src/encauth/gcm/gcm_memory.obj src/encauth/gcm/gcm_mult_h.obj src/encauth/gcm/gcm_process.obj \ -src/encauth/gcm/gcm_reset.obj src/encauth/gcm/gcm_test.obj src/encauth/ocb/ocb_decrypt.obj \ -src/encauth/ocb/ocb_decrypt_verify_memory.obj src/encauth/ocb/ocb_done_decrypt.obj \ -src/encauth/ocb/ocb_done_encrypt.obj src/encauth/ocb/ocb_encrypt.obj \ +src/encauth/ccm/ccm_test.obj src/encauth/chachapoly/chacha20poly1305_add_aad.obj \ +src/encauth/chachapoly/chacha20poly1305_decrypt.obj src/encauth/chachapoly/chacha20poly1305_done.obj \ +src/encauth/chachapoly/chacha20poly1305_encrypt.obj src/encauth/chachapoly/chacha20poly1305_init.obj \ +src/encauth/chachapoly/chacha20poly1305_memory.obj src/encauth/chachapoly/chacha20poly1305_setiv.obj \ +src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.obj \ +src/encauth/chachapoly/chacha20poly1305_test.obj src/encauth/eax/eax_addheader.obj \ +src/encauth/eax/eax_decrypt.obj src/encauth/eax/eax_decrypt_verify_memory.obj src/encauth/eax/eax_done.obj \ +src/encauth/eax/eax_encrypt.obj src/encauth/eax/eax_encrypt_authenticate_memory.obj \ +src/encauth/eax/eax_init.obj src/encauth/eax/eax_test.obj src/encauth/gcm/gcm_add_aad.obj \ +src/encauth/gcm/gcm_add_iv.obj src/encauth/gcm/gcm_done.obj src/encauth/gcm/gcm_gf_mult.obj \ +src/encauth/gcm/gcm_init.obj src/encauth/gcm/gcm_memory.obj src/encauth/gcm/gcm_mult_h.obj \ +src/encauth/gcm/gcm_process.obj src/encauth/gcm/gcm_reset.obj src/encauth/gcm/gcm_test.obj \ +src/encauth/ocb/ocb_decrypt.obj src/encauth/ocb/ocb_decrypt_verify_memory.obj \ +src/encauth/ocb/ocb_done_decrypt.obj src/encauth/ocb/ocb_done_encrypt.obj src/encauth/ocb/ocb_encrypt.obj \ src/encauth/ocb/ocb_encrypt_authenticate_memory.obj src/encauth/ocb/ocb_init.obj src/encauth/ocb/ocb_ntz.obj \ src/encauth/ocb/ocb_shift_xor.obj src/encauth/ocb/ocb_test.obj src/encauth/ocb/s_ocb_done.obj \ src/encauth/ocb3/ocb3_add_aad.obj src/encauth/ocb3/ocb3_decrypt.obj src/encauth/ocb3/ocb3_decrypt_last.obj \ @@ -48,7 +53,9 @@ src/mac/omac/omac_process.obj src/mac/omac/omac_test.obj src/mac/pelican/pelican src/mac/pelican/pelican_memory.obj src/mac/pelican/pelican_test.obj src/mac/pmac/pmac_done.obj \ src/mac/pmac/pmac_file.obj src/mac/pmac/pmac_init.obj src/mac/pmac/pmac_memory.obj \ src/mac/pmac/pmac_memory_multi.obj src/mac/pmac/pmac_ntz.obj src/mac/pmac/pmac_process.obj \ -src/mac/pmac/pmac_shift_xor.obj src/mac/pmac/pmac_test.obj src/mac/xcbc/xcbc_done.obj \ +src/mac/pmac/pmac_shift_xor.obj src/mac/pmac/pmac_test.obj src/mac/poly1305/poly1305.obj \ +src/mac/poly1305/poly1305_file.obj src/mac/poly1305/poly1305_memory.obj \ +src/mac/poly1305/poly1305_memory_multi.obj src/mac/poly1305/poly1305_test.obj src/mac/xcbc/xcbc_done.obj \ src/mac/xcbc/xcbc_file.obj src/mac/xcbc/xcbc_init.obj src/mac/xcbc/xcbc_memory.obj \ src/mac/xcbc/xcbc_memory_multi.obj src/mac/xcbc/xcbc_process.obj src/mac/xcbc/xcbc_test.obj \ src/math/fp/ltc_ecc_fp_mulmod.obj src/math/gmp_desc.obj src/math/ltm_desc.obj src/math/multi.obj \ @@ -140,8 +147,11 @@ src/pk/pkcs1/pkcs_1_v1_5_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rs src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_get_size.obj \ src/pk/rsa/rsa_import.obj src/pk/rsa/rsa_import_radix.obj src/pk/rsa/rsa_import_x509.obj \ src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_sign_saltlen_get.obj \ -src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj src/prngs/rc4.obj src/prngs/rng_get_bytes.obj \ -src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj src/prngs/yarrow.obj +src/pk/rsa/rsa_verify_hash.obj src/prngs/chacha.obj src/prngs/fortuna.obj src/prngs/rc4.obj \ +src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj \ +src/prngs/yarrow.obj src/stream/chacha/chacha_crypt.obj src/stream/chacha/chacha_ivctr32.obj \ +src/stream/chacha/chacha_ivctr64.obj src/stream/chacha/chacha_keystream.obj \ +src/stream/chacha/chacha_setup.obj src/stream/chacha/chacha_test.obj HEADERS=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \ diff --git a/makefile.shared b/makefile.shared index d59c0dcb..79520471 100644 --- a/makefile.shared +++ b/makefile.shared @@ -39,15 +39,20 @@ src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphe src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_add_aad.o \ src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o src/encauth/ccm/ccm_init.o \ src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o src/encauth/ccm/ccm_reset.o \ -src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ -src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \ -src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \ -src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \ -src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \ -src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o src/encauth/gcm/gcm_process.o \ -src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o \ -src/encauth/ocb/ocb_decrypt_verify_memory.o src/encauth/ocb/ocb_done_decrypt.o \ -src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ccm/ccm_test.o src/encauth/chachapoly/chacha20poly1305_add_aad.o \ +src/encauth/chachapoly/chacha20poly1305_decrypt.o src/encauth/chachapoly/chacha20poly1305_done.o \ +src/encauth/chachapoly/chacha20poly1305_encrypt.o src/encauth/chachapoly/chacha20poly1305_init.o \ +src/encauth/chachapoly/chacha20poly1305_memory.o src/encauth/chachapoly/chacha20poly1305_setiv.o \ +src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \ +src/encauth/chachapoly/chacha20poly1305_test.o src/encauth/eax/eax_addheader.o \ +src/encauth/eax/eax_decrypt.o src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ +src/encauth/eax/eax_encrypt.o src/encauth/eax/eax_encrypt_authenticate_memory.o \ +src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ +src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ +src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ +src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ +src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \ src/encauth/ocb3/ocb3_add_aad.o src/encauth/ocb3/ocb3_decrypt.o src/encauth/ocb3/ocb3_decrypt_last.o \ @@ -71,7 +76,9 @@ src/mac/omac/omac_process.o src/mac/omac/omac_test.o src/mac/pelican/pelican.o \ src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o src/mac/pmac/pmac_done.o \ src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ -src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/poly1305/poly1305.o \ +src/mac/poly1305/poly1305_file.o src/mac/poly1305/poly1305_memory.o \ +src/mac/poly1305/poly1305_memory_multi.o src/mac/poly1305/poly1305_test.o src/mac/xcbc/xcbc_done.o \ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ @@ -163,8 +170,11 @@ src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_en src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \ src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_radix.o src/pk/rsa/rsa_import_x509.o \ src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \ -src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ -src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o +src/pk/rsa/rsa_verify_hash.o src/prngs/chacha.o src/prngs/fortuna.o src/prngs/rc4.o \ +src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \ +src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_ivctr32.o \ +src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \ +src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o HEADERS=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \ diff --git a/makefile.unix b/makefile.unix index 310bb1c1..884d13fa 100644 --- a/makefile.unix +++ b/makefile.unix @@ -47,15 +47,20 @@ src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphe src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_add_aad.o \ src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o src/encauth/ccm/ccm_init.o \ src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o src/encauth/ccm/ccm_reset.o \ -src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ -src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \ -src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \ -src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \ -src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \ -src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o src/encauth/gcm/gcm_process.o \ -src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o \ -src/encauth/ocb/ocb_decrypt_verify_memory.o src/encauth/ocb/ocb_done_decrypt.o \ -src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ +src/encauth/ccm/ccm_test.o src/encauth/chachapoly/chacha20poly1305_add_aad.o \ +src/encauth/chachapoly/chacha20poly1305_decrypt.o src/encauth/chachapoly/chacha20poly1305_done.o \ +src/encauth/chachapoly/chacha20poly1305_encrypt.o src/encauth/chachapoly/chacha20poly1305_init.o \ +src/encauth/chachapoly/chacha20poly1305_memory.o src/encauth/chachapoly/chacha20poly1305_setiv.o \ +src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \ +src/encauth/chachapoly/chacha20poly1305_test.o src/encauth/eax/eax_addheader.o \ +src/encauth/eax/eax_decrypt.o src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ +src/encauth/eax/eax_encrypt.o src/encauth/eax/eax_encrypt_authenticate_memory.o \ +src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ +src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ +src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ +src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ +src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ +src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \ src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \ src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \ src/encauth/ocb3/ocb3_add_aad.o src/encauth/ocb3/ocb3_decrypt.o src/encauth/ocb3/ocb3_decrypt_last.o \ @@ -79,7 +84,9 @@ src/mac/omac/omac_process.o src/mac/omac/omac_test.o src/mac/pelican/pelican.o \ src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o src/mac/pmac/pmac_done.o \ src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ -src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ +src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/poly1305/poly1305.o \ +src/mac/poly1305/poly1305_file.o src/mac/poly1305/poly1305_memory.o \ +src/mac/poly1305/poly1305_memory_multi.o src/mac/poly1305/poly1305_test.o src/mac/xcbc/xcbc_done.o \ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ @@ -171,8 +178,11 @@ src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_en src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \ src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_radix.o src/pk/rsa/rsa_import_x509.o \ src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \ -src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ -src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o +src/pk/rsa/rsa_verify_hash.o src/prngs/chacha.o src/prngs/fortuna.o src/prngs/rc4.o \ +src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \ +src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_ivctr32.o \ +src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \ +src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o HEADERS=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ src/headers/tomcrypt_cipher.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_hash.h \ diff --git a/src/encauth/chachapoly/chacha20poly1305_add_aad.c b/src/encauth/chachapoly/chacha20poly1305_add_aad.c new file mode 100644 index 00000000..f840d289 --- /dev/null +++ b/src/encauth/chachapoly/chacha20poly1305_add_aad.c @@ -0,0 +1,34 @@ +/* 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" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Add AAD to the ChaCha20Poly1305 state + @param st The ChaCha20Poly1305 state + @param in The additional authentication data to add to the ChaCha20Poly1305 state + @param inlen The length of the ChaCha20Poly1305 data. + @return CRYPT_OK on success + */ +int chacha20poly1305_add_aad(chachapoly_state *st, const unsigned char *in, unsigned long inlen) +{ + int err; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + + if (st->aadflg == 0) return CRYPT_ERROR; + if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err; + st->aadlen += (ulong64)inlen; + return CRYPT_OK; +} + +#endif diff --git a/src/encauth/chachapoly/chacha20poly1305_decrypt.c b/src/encauth/chachapoly/chacha20poly1305_decrypt.c new file mode 100644 index 00000000..e62dd6a5 --- /dev/null +++ b/src/encauth/chachapoly/chacha20poly1305_decrypt.c @@ -0,0 +1,44 @@ +/* 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" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Decrypt bytes of ciphertext with ChaCha20Poly1305 + @param st The ChaCha20Poly1305 state + @param in The ciphertext + @param inlen The length of the input (octets) + @param out [out] The plaintext (length inlen) + @return CRYPT_OK if successful +*/ +int chacha20poly1305_decrypt(chachapoly_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) +{ + unsigned char padzero[16] = { 0 }; + unsigned long padlen; + int err; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + + if (st->aadflg) { + if ((padlen = 16 - (st->aadlen % 16)) < 16) { + if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err; + } + st->aadflg = 0; /* no more AAD */ + } + if (st->aadflg) st->aadflg = 0; /* no more AAD */ + if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err; + if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err; + st->ctlen += (ulong64)inlen; + return CRYPT_OK; +} + +#endif diff --git a/src/encauth/chachapoly/chacha20poly1305_done.c b/src/encauth/chachapoly/chacha20poly1305_done.c new file mode 100644 index 00000000..fe25ab57 --- /dev/null +++ b/src/encauth/chachapoly/chacha20poly1305_done.c @@ -0,0 +1,41 @@ +/* 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" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Terminate a ChaCha20Poly1305 stream + @param st The ChaCha20Poly1305 state + @param tag [out] The destination for the MAC tag + @param taglen [in/out] The length of the MAC tag + @return CRYPT_OK on success + */ +int chacha20poly1305_done(chachapoly_state *st, unsigned char *tag, unsigned long *taglen) +{ + unsigned char padzero[16] = { 0 }; + unsigned long padlen; + unsigned char buf[16]; + int err; + + LTC_ARGCHK(st != NULL); + + padlen = 16 - (st->ctlen % 16); + if (padlen < 16) { + if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err; + } + STORE64L(st->aadlen, buf); + STORE64L(st->ctlen, buf + 8); + if ((err = poly1305_process(&st->poly, buf, 16)) != CRYPT_OK) return err; + if ((err = poly1305_done(&st->poly, tag, taglen)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +#endif diff --git a/src/encauth/chachapoly/chacha20poly1305_encrypt.c b/src/encauth/chachapoly/chacha20poly1305_encrypt.c new file mode 100644 index 00000000..b1c1adc6 --- /dev/null +++ b/src/encauth/chachapoly/chacha20poly1305_encrypt.c @@ -0,0 +1,44 @@ +/* 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" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Encrypt bytes of ciphertext with ChaCha20Poly1305 + @param st The ChaCha20Poly1305 state + @param in The plaintext + @param inlen The length of the input (octets) + @param out [out] The ciphertext (length inlen) + @return CRYPT_OK if successful +*/ +int chacha20poly1305_encrypt(chachapoly_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) +{ + unsigned char padzero[16] = { 0 }; + unsigned long padlen; + int err; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + + if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err; + if (st->aadflg) { + padlen = 16 - (st->aadlen % 16); + if (padlen < 16) { + if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err; + } + st->aadflg = 0; /* no more AAD */ + } + if ((err = poly1305_process(&st->poly, out, inlen)) != CRYPT_OK) return err; + st->ctlen += (ulong64)inlen; + return CRYPT_OK; +} + +#endif diff --git a/src/encauth/chachapoly/chacha20poly1305_init.c b/src/encauth/chachapoly/chacha20poly1305_init.c new file mode 100644 index 00000000..7cea6aa9 --- /dev/null +++ b/src/encauth/chachapoly/chacha20poly1305_init.c @@ -0,0 +1,26 @@ +/* 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" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Initialize an ChaCha20Poly1305 context (only the key) + @param st [out] The destination of the ChaCha20Poly1305 state + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int chacha20poly1305_init(chachapoly_state *st, const unsigned char *key, unsigned long keylen) +{ + return chacha_setup(&st->chacha, key, keylen, 20); +} + +#endif diff --git a/src/encauth/chachapoly/chacha20poly1305_memory.c b/src/encauth/chachapoly/chacha20poly1305_memory.c new file mode 100644 index 00000000..09ee01fb --- /dev/null +++ b/src/encauth/chachapoly/chacha20poly1305_memory.c @@ -0,0 +1,70 @@ +/* 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" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Process an entire GCM packet in one call. + @param key The secret key + @param keylen The length of the secret key + @param iv The initial vector + @param ivlen The length of the initial vector + @param aad The additional authentication data (header) + @param aadlen The length of the aad + @param in The plaintext + @param inlen The length of the plaintext (ciphertext length is the same) + @param out The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (CHCHA20POLY1305_ENCRYPT or CHCHA20POLY1305_DECRYPT) + @return CRYPT_OK on success + */ +int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *aad, unsigned long aadlen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, + unsigned char *tag, unsigned long *taglen, + int direction) +{ + chachapoly_state st; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(iv != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(tag != NULL); + + if ((err = chacha20poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = chacha20poly1305_setiv(&st, iv, ivlen)) != CRYPT_OK) { goto LBL_ERR; } + if (aad && aadlen > 0) { + if ((err = chacha20poly1305_add_aad(&st, aad, aadlen)) != CRYPT_OK) { goto LBL_ERR; } + } + if (direction == CHCHA20POLY1305_ENCRYPT) { + if ((err = chacha20poly1305_encrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } + } + else if (direction == CHCHA20POLY1305_DECRYPT) { + if ((err = chacha20poly1305_decrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } + } + else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + err = chacha20poly1305_done(&st, tag, taglen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(chachapoly_state)); +#endif + return err; +} + +#endif diff --git a/src/encauth/chachapoly/chacha20poly1305_setiv.c b/src/encauth/chachapoly/chacha20poly1305_setiv.c new file mode 100644 index 00000000..43c116bb --- /dev/null +++ b/src/encauth/chachapoly/chacha20poly1305_setiv.c @@ -0,0 +1,64 @@ +/* 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" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Set IV + counter data to the ChaCha20Poly1305 state and reset the context + @param st The ChaCha20Poly1305 state + @param iv The IV data to add + @param inlen The length of the IV (must be 12 or 8) + @return CRYPT_OK on success + */ +int chacha20poly1305_setiv(chachapoly_state *st, const unsigned char *iv, unsigned long ivlen) +{ + chacha_state tmp_st; + int i, err; + unsigned char polykey[32]; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(iv != NULL); + LTC_ARGCHK(ivlen == 12 || ivlen == 8); + + /* set IV for chacha20 */ + if (ivlen == 12) { + /* IV 96bit */ + if ((err = chacha_ivctr32(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err; + } + else { + /* IV 64bit */ + if ((err = chacha_ivctr64(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err; + } + + /* copy chacha20 key to temporary state */ + for(i = 0; i < 12; i++) tmp_st.input[i] = st->chacha.input[i]; + tmp_st.rounds = 20; + /* set IV */ + if (ivlen == 12) { + /* IV 32bit */ + if ((err = chacha_ivctr32(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err; + } + else { + /* IV 64bit */ + if ((err = chacha_ivctr64(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err; + } + /* (re)generate new poly1305 key */ + if ((err = chacha_keystream(&tmp_st, polykey, 32)) != CRYPT_OK) return err; + /* (re)initialise poly1305 */ + if ((err = poly1305_init(&st->poly, polykey, 32)) != CRYPT_OK) return err; + st->ctlen = 0; + st->aadlen = 0; + st->aadflg = 1; + + return CRYPT_OK; +} + +#endif diff --git a/src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c b/src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c new file mode 100644 index 00000000..5bb21563 --- /dev/null +++ b/src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.c @@ -0,0 +1,36 @@ +/* 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" + +#ifdef LTC_CHACHA20POLY1305_MODE + +/** + Set IV + counter data (with RFC7905-magic) to the ChaCha20Poly1305 state and reset the context + @param st The ChaCha20Poly1305 state + @param iv The IV data to add + @param inlen The length of the IV (must be 12 or 8) + @param sequence_number 64bit sequence number which is incorporated into IV as described in RFC7905 + @return CRYPT_OK on success + */ +int chacha20poly1305_setiv_rfc7905(chachapoly_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number) +{ + int i; + unsigned char combined_iv[12] = { 0 }; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(iv != NULL); + LTC_ARGCHK(ivlen == 12); + + STORE64L(sequence_number, combined_iv + 4); + for (i = 0; i < 12; i++) combined_iv[i] = iv[i] ^ combined_iv[i]; + return chacha20poly1305_setiv(st, combined_iv, 12); +} + +#endif diff --git a/src/encauth/chachapoly/chacha20poly1305_test.c b/src/encauth/chachapoly/chacha20poly1305_test.c new file mode 100644 index 00000000..ab5360b9 --- /dev/null +++ b/src/encauth/chachapoly/chacha20poly1305_test.c @@ -0,0 +1,70 @@ +/* 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" + +#ifdef LTC_CHACHA20POLY1305_MODE + +int chacha20poly1305_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + chachapoly_state st1, st2; + unsigned char k[] = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f }; + unsigned char iv[] = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 }; + unsigned char aad[] = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 }; + unsigned char enc[] = { 0xD3, 0x1A, 0x8D, 0x34, 0x64, 0x8E, 0x60, 0xDB, 0x7B, 0x86, 0xAF, 0xBC, 0x53, 0xEF, 0x7E, 0xC2, + 0xA4, 0xAD, 0xED, 0x51, 0x29, 0x6E, 0x08, 0xFE, 0xA9, 0xE2, 0xB5, 0xA7, 0x36, 0xEE, 0x62, 0xD6, + 0x3D, 0xBE, 0xA4, 0x5E, 0x8C, 0xA9, 0x67, 0x12, 0x82, 0xFA, 0xFB, 0x69, 0xDA, 0x92, 0x72, 0x8B, + 0x1A, 0x71, 0xDE, 0x0A, 0x9E, 0x06, 0x0B, 0x29, 0x05, 0xD6, 0xA5, 0xB6, 0x7E, 0xCD, 0x3B, 0x36, + 0x92, 0xDD, 0xBD, 0x7F, 0x2D, 0x77, 0x8B, 0x8C, 0x98, 0x03, 0xAE, 0xE3, 0x28, 0x09, 0x1B, 0x58, + 0xFA, 0xB3, 0x24, 0xE4, 0xFA, 0xD6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8B, 0x48, 0x31, 0xD7, 0xBC, + 0x3F, 0xF4, 0xDE, 0xF0, 0x8E, 0x4B, 0x7A, 0x9D, 0xE5, 0x76, 0xD2, 0x65, 0x86, 0xCE, 0xC6, 0x4B, + 0x61, 0x16 }; + unsigned char tag[] = { 0x1A, 0xE1, 0x0B, 0x59, 0x4F, 0x09, 0xE2, 0x6A, 0x7E, 0x90, 0x2E, 0xCB, 0xD0, 0x60, 0x06, 0x91 }; + char m[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."; + unsigned long mlen = strlen(m); + unsigned long len; + unsigned char ct[1000], pt[1000], emac[16], dmac[16]; + + /* encrypt */ + chacha20poly1305_init(&st1, k, sizeof(k)); + chacha20poly1305_setiv(&st1, iv, sizeof(iv)); + chacha20poly1305_add_aad(&st1, aad, sizeof(aad)); + /* encrypt piece by piece */ + chacha20poly1305_encrypt(&st1, (unsigned char *)m, 25, ct); + chacha20poly1305_encrypt(&st1, (unsigned char *)m + 25, 10, ct + 25); + chacha20poly1305_encrypt(&st1, (unsigned char *)m + 35, 35, ct + 35); + chacha20poly1305_encrypt(&st1, (unsigned char *)m + 70, 5, ct + 70); + chacha20poly1305_encrypt(&st1, (unsigned char *)m + 75, 5, ct + 75); + chacha20poly1305_encrypt(&st1, (unsigned char *)m + 80, mlen - 80, ct + 80); + len = sizeof(emac); + chacha20poly1305_done(&st1, emac, &len); + + if (compare_testvector(ct, mlen, enc, sizeof(enc), "ENC-CT", 1) != 0) return CRYPT_FAIL_TESTVECTOR; + if (compare_testvector(emac, len, tag, sizeof(tag), "ENC-TAG", 2) != 0) return CRYPT_FAIL_TESTVECTOR; + + /* decrypt */ + chacha20poly1305_init(&st2, k, len = sizeof(k)); + chacha20poly1305_setiv(&st2, iv, len = sizeof(iv)); + chacha20poly1305_add_aad(&st2, aad, len = sizeof(aad)); + chacha20poly1305_decrypt(&st2, ct, 21, pt); + chacha20poly1305_decrypt(&st2, ct + 21, mlen - 21, pt + 21); + len = sizeof(dmac); + chacha20poly1305_done(&st2, dmac, &len); + + if (compare_testvector(pt, mlen, m, mlen, "DEC-PT", 3) != 0) return CRYPT_FAIL_TESTVECTOR; + if (compare_testvector(dmac, len, tag, sizeof(tag), "DEC-TAG", 4) != 0) return CRYPT_FAIL_TESTVECTOR; + + return CRYPT_OK; +#endif +}; + +#endif diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index c9c68322..36d0c0cc 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -937,6 +937,27 @@ int cipher_is_valid(int idx); LTC_MUTEX_PROTO(ltc_cipher_mutex) +/* ---- stream ciphers ---- */ + +#ifdef LTC_CHACHA + +typedef struct { + ulong32 input[16]; + unsigned char kstream[64]; + unsigned long ksleft; + unsigned long ivlen; + int rounds; +} chacha_state; + +int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds); +int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter); +int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter); +int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int chacha_keystream(chacha_state *st, unsigned char *out, unsigned long outlen); +int chacha_test(void); + +#endif /* LTC_CHACHA */ + /* $Source$ */ /* $Revision$ */ /* $Date$ */ diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 8b8ad617..1d55322b 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -189,6 +189,8 @@ #define LTC_KASUMI #define LTC_MULTI2 #define LTC_CAMELLIA +/* ChaCha is special (a stream cipher) */ +#define LTC_CHACHA #endif /* LTC_NO_CIPHERS */ @@ -255,6 +257,7 @@ #define LTC_XCBC #define LTC_F9_MODE #define LTC_PELICAN +#define LTC_POLY1305 /* ---> Encrypt + Authenticate Modes <--- */ @@ -264,6 +267,7 @@ #define LTC_OCB3_MODE #define LTC_CCM_MODE #define LTC_GCM_MODE +#define LTC_CHACHA20POLY1305_MODE /* Use 64KiB tables */ #ifndef LTC_NO_TABLES @@ -504,6 +508,10 @@ #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled #endif +#if defined(LTC_CHACHA20POLY1305_MODE) && (!defined(LTC_CHACHA) || !defined(LTC_POLY1305)) + #error LTC_CHACHA20POLY1305_MODE requires LTC_CHACHA + LTC_POLY1305 +#endif + /* THREAD management */ #ifdef LTC_PTHREAD diff --git a/src/headers/tomcrypt_mac.h b/src/headers/tomcrypt_mac.h index 1486aad3..e2b4a9f7 100644 --- a/src/headers/tomcrypt_mac.h +++ b/src/headers/tomcrypt_mac.h @@ -96,6 +96,26 @@ void pmac_shift_xor(pmac_state *pmac); #endif /* PMAC */ +#ifdef LTC_POLY1305 +typedef struct { + ulong32 r[5]; + ulong32 h[5]; + ulong32 pad[4]; + unsigned long leftover; + unsigned char buffer[16]; + int final; +} poly_state; + +int poly1305_init(poly_state *st, const unsigned char *key, unsigned long keylen); +int poly1305_process(poly_state *st, const unsigned char *in, unsigned long inlen); +int poly1305_done(poly_state *st, unsigned char *mac, unsigned long *maclen); +int poly1305_test(void); +int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen); +int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...); +int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen); +int poly1305_test(void); +#endif /* LTC_POLY1305 */ + #ifdef LTC_EAX_MODE #if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE)) @@ -477,6 +497,36 @@ int f9_test(void); #endif +#ifdef LTC_CHACHA20POLY1305_MODE + +typedef struct { + poly_state poly; + chacha_state chacha; + ulong64 aadlen; + ulong64 ctlen; + int aadflg; +} chachapoly_state; + +#define CHCHA20POLY1305_ENCRYPT 0 +#define CHCHA20POLY1305_DECRYPT 1 + +int chacha20poly1305_init(chachapoly_state *st, const unsigned char *key, unsigned long keylen); +int chacha20poly1305_setiv(chachapoly_state *st, const unsigned char *iv, unsigned long ivlen); +int chacha20poly1305_setiv_rfc7905(chachapoly_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number); +int chacha20poly1305_add_aad(chachapoly_state *st, const unsigned char *in, unsigned long inlen); +int chacha20poly1305_encrypt(chachapoly_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int chacha20poly1305_decrypt(chachapoly_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int chacha20poly1305_done(chachapoly_state *st, unsigned char *tag, unsigned long *taglen); +int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *aad, unsigned long aadlen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, + unsigned char *tag, unsigned long *taglen, + int direction); +int chacha20poly1305_test(void); + +#endif /* LTC_CHACHA20POLY1305_MODE */ /* $Source$ */ /* $Revision$ */ diff --git a/src/headers/tomcrypt_prng.h b/src/headers/tomcrypt_prng.h index dc2cc7e0..e50f06c9 100644 --- a/src/headers/tomcrypt_prng.h +++ b/src/headers/tomcrypt_prng.h @@ -15,6 +15,15 @@ struct rc4_prng { }; #endif +#ifdef LTC_CHACHA +struct chacha_prng { + chacha_state s; /* chacha state */ + unsigned char ent[40]; /* entropy buffer */ + unsigned long idx; /* entropy counter */ + short ready; /* ready flag 0-1 */ +}; +#endif + #ifdef LTC_FORTUNA struct fortuna_prng { hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */ @@ -55,6 +64,9 @@ typedef union Prng_state { #ifdef LTC_RC4 struct rc4_prng rc4; #endif +#ifdef LTC_CHACHA + struct chacha_prng chacha; +#endif #ifdef LTC_FORTUNA struct fortuna_prng fortuna; #endif @@ -154,6 +166,18 @@ int rc4_test(void); extern const struct ltc_prng_descriptor rc4_desc; #endif +#ifdef LTC_CHACHA +int chacha_prng_start(prng_state *prng); +int chacha_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int chacha_prng_ready(prng_state *prng); +unsigned long chacha_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int chacha_prng_done(prng_state *prng); +int chacha_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int chacha_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int chacha_prng_test(void); +extern const struct ltc_prng_descriptor chacha_prng_desc; +#endif + #ifdef LTC_SPRNG int sprng_start(prng_state *prng); int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); diff --git a/src/mac/poly1305/poly1305.c b/src/mac/poly1305/poly1305.c new file mode 100644 index 00000000..abb0f335 --- /dev/null +++ b/src/mac/poly1305/poly1305.c @@ -0,0 +1,264 @@ +/* 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. + */ + +/* The implementation is based on: + * Public Domain poly1305 from Andrew Moon + * https://github.com/floodyberry/poly1305-donna + */ + +#include "tomcrypt.h" + +#ifdef LTC_POLY1305 + +/* internal only */ +static void _poly1305_block(poly_state *st, const unsigned char *in, unsigned long inlen) +{ + const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */ + ulong32 r0,r1,r2,r3,r4; + ulong32 s1,s2,s3,s4; + ulong32 h0,h1,h2,h3,h4; + ulong32 tmp; + ulong64 d0,d1,d2,d3,d4; + ulong32 c; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + r3 = st->r[3]; + r4 = st->r[4]; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + while (inlen >= 16) { + /* h += in[i] */ + LOAD32L(tmp, in+ 0); h0 += (tmp ) & 0x3ffffff; + LOAD32L(tmp, in+ 3); h1 += (tmp >> 2) & 0x3ffffff; + LOAD32L(tmp, in+ 6); h2 += (tmp >> 4) & 0x3ffffff; + LOAD32L(tmp, in+ 9); h3 += (tmp >> 6) & 0x3ffffff; + LOAD32L(tmp, in+12); h4 += (tmp >> 8) | hibit; + + /* h *= r */ + d0 = ((ulong64)h0 * r0) + ((ulong64)h1 * s4) + ((ulong64)h2 * s3) + ((ulong64)h3 * s2) + ((ulong64)h4 * s1); + d1 = ((ulong64)h0 * r1) + ((ulong64)h1 * r0) + ((ulong64)h2 * s4) + ((ulong64)h3 * s3) + ((ulong64)h4 * s2); + d2 = ((ulong64)h0 * r2) + ((ulong64)h1 * r1) + ((ulong64)h2 * r0) + ((ulong64)h3 * s4) + ((ulong64)h4 * s3); + d3 = ((ulong64)h0 * r3) + ((ulong64)h1 * r2) + ((ulong64)h2 * r1) + ((ulong64)h3 * r0) + ((ulong64)h4 * s4); + d4 = ((ulong64)h0 * r4) + ((ulong64)h1 * r3) + ((ulong64)h2 * r2) + ((ulong64)h3 * r1) + ((ulong64)h4 * r0); + + /* (partial) h %= p */ + c = (ulong32)(d0 >> 26); h0 = (ulong32)d0 & 0x3ffffff; + d1 += c; c = (ulong32)(d1 >> 26); h1 = (ulong32)d1 & 0x3ffffff; + d2 += c; c = (ulong32)(d2 >> 26); h2 = (ulong32)d2 & 0x3ffffff; + d3 += c; c = (ulong32)(d3 >> 26); h3 = (ulong32)d3 & 0x3ffffff; + d4 += c; c = (ulong32)(d4 >> 26); h4 = (ulong32)d4 & 0x3ffffff; + h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; + h1 += c; + + in += 16; + inlen -= 16; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; + st->h[3] = h3; + st->h[4] = h4; +} + +/** + Initialize an POLY1305 context. + @param st The POLY1305 state + @param key The secret key + @param keylen The length of the secret key (octets) + @return CRYPT_OK if successful +*/ +int poly1305_init(poly_state *st, const unsigned char *key, unsigned long keylen) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(keylen == 32); + + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + LOAD32L(st->r[0], key + 0); st->r[0] = (st->r[0] ) & 0x3ffffff; + LOAD32L(st->r[1], key + 3); st->r[1] = (st->r[1] >> 2) & 0x3ffff03; + LOAD32L(st->r[2], key + 6); st->r[2] = (st->r[2] >> 4) & 0x3ffc0ff; + LOAD32L(st->r[3], key + 9); st->r[3] = (st->r[3] >> 6) & 0x3f03fff; + LOAD32L(st->r[4], key + 12); st->r[4] = (st->r[4] >> 8) & 0x00fffff; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + + /* save pad for later */ + LOAD32L(st->pad[0], key + 16); + LOAD32L(st->pad[1], key + 20); + LOAD32L(st->pad[2], key + 24); + LOAD32L(st->pad[3], key + 28); + + st->leftover = 0; + st->final = 0; + return CRYPT_OK; +} + +/** + Process data through POLY1305 + @param st The POLY1305 state + @param in The data to send through HMAC + @param inlen The length of the data to HMAC (octets) + @return CRYPT_OK if successful +*/ +int poly1305_process(poly_state *st, const unsigned char *in, unsigned long inlen) +{ + unsigned long i; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + + /* handle leftover */ + if (st->leftover) { + unsigned long want = (16 - st->leftover); + if (want > inlen) want = inlen; + for (i = 0; i < want; i++) st->buffer[st->leftover + i] = in[i]; + inlen -= want; + in += want; + st->leftover += want; + if (st->leftover < 16) return CRYPT_OK; + _poly1305_block(st, st->buffer, 16); + st->leftover = 0; + } + + /* process full blocks */ + if (inlen >= 16) { + unsigned long want = (inlen & ~(16 - 1)); + _poly1305_block(st, in, want); + in += want; + inlen -= want; + } + + /* store leftover */ + if (inlen) { + for (i = 0; i < inlen; i++) st->buffer[st->leftover + i] = in[i]; + st->leftover += inlen; + } + return CRYPT_OK; +} + +/** + Terminate a POLY1305 session + @param st The POLY1305 state + @param out [out] The destination of the POLY1305 authentication tag + @param outlen [in/out] The max size and resulting size of the POLY1305 authentication tag + @return CRYPT_OK if successful +*/ +int poly1305_done(poly_state *st, unsigned char *mac, unsigned long *maclen) +{ + ulong32 h0,h1,h2,h3,h4,c; + ulong32 g0,g1,g2,g3,g4; + ulong64 f; + ulong32 mask; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + LTC_ARGCHK(*maclen >= 16); + + /* process the remaining block */ + if (st->leftover) { + unsigned long i = st->leftover; + st->buffer[i++] = 1; + for (; i < 16; i++) st->buffer[i] = 0; + st->final = 1; + _poly1305_block(st, st->buffer, 16); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + c = h1 >> 26; h1 = h1 & 0x3ffffff; + h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; + h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; + h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; + h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; + g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; + g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; + g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; + g4 = h4 + c - (1UL << 26); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> 31) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; + + /* h = h % (2^128) */ + h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; + h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; + h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; + h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; + + /* mac = (h + pad) % (2^128) */ + f = (ulong64)h0 + st->pad[0] ; h0 = (ulong32)f; + f = (ulong64)h1 + st->pad[1] + (f >> 32); h1 = (ulong32)f; + f = (ulong64)h2 + st->pad[2] + (f >> 32); h2 = (ulong32)f; + f = (ulong64)h3 + st->pad[3] + (f >> 32); h3 = (ulong32)f; + + STORE32L(h0, mac + 0); + STORE32L(h1, mac + 4); + STORE32L(h2, mac + 8); + STORE32L(h3, mac + 12); + + /* zero out the state */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + st->r[0] = 0; + st->r[1] = 0; + st->r[2] = 0; + st->r[3] = 0; + st->r[4] = 0; + st->pad[0] = 0; + st->pad[1] = 0; + st->pad[2] = 0; + st->pad[3] = 0; + + *maclen = 16; + return CRYPT_OK; +} + +#endif diff --git a/src/mac/poly1305/poly1305_file.c b/src/mac/poly1305/poly1305_file.c new file mode 100644 index 00000000..f11854e1 --- /dev/null +++ b/src/mac/poly1305/poly1305_file.c @@ -0,0 +1,70 @@ +/* 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. + */ + +/* The implementation is based on: + * Public Domain poly1305 from Andrew Moon + * https://github.com/floodyberry/poly1305-donna + */ + +#include "tomcrypt.h" + +#ifdef LTC_POLY1305 + +/** + POLY1305 a file + @param fname The name of the file you wish to POLY1305 + @param key The secret key + @param keylen The length of the secret key + @param out [out] The POLY1305 authentication tag + @param outlen [in/out] The max size and resulting size of the authentication tag + @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled +*/ +int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) +{ +#ifdef LTC_NO_FILE + return CRYPT_NOP; +#else + poly_state st; + FILE *in; + unsigned char *buf; + size_t x; + int err; + + LTC_ARGCHK(fname != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + if ((in = fopen(fname, "rb")) == NULL) { return CRYPT_FILE_NOTFOUND; } + if ((buf = XMALLOC(8196)) == NULL) { return CRYPT_MEM; } + if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = poly1305_process(&st, buf, (unsigned long)x)) != CRYPT_OK) { + fclose(in); + goto LBL_ERR; + } + } while (x == sizeof(buf)); + if (fclose(in) != 0) { + err = CRYPT_ERROR; + goto LBL_ERR; + } + err = poly1305_done(&st, mac, maclen); + +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(poly_state)); +#endif + XFREE(buf); + return err; +#endif +}; + +#endif diff --git a/src/mac/poly1305/poly1305_memory.c b/src/mac/poly1305/poly1305_memory.c new file mode 100644 index 00000000..4ff2fe1a --- /dev/null +++ b/src/mac/poly1305/poly1305_memory.c @@ -0,0 +1,49 @@ +/* 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. + */ + +/* The implementation is based on: + * Public Domain poly1305 from Andrew Moon + * https://github.com/floodyberry/poly1305-donna + */ + +#include "tomcrypt.h" + +#ifdef LTC_POLY1305 + +/** + POLY1305 a block of memory to produce the authentication tag + @param key The secret key + @param keylen The length of the secret key (octets) + @param in The data to POLY1305 + @param inlen The length of the data to POLY1305 (octets) + @param mac [out] Destination of the authentication tag + @param maclen [in/out] Max size and resulting size of authentication tag + @return CRYPT_OK if successful +*/ +int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen) +{ + poly_state st; + int err; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = poly1305_process(&st, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } + err = poly1305_done(&st, mac, maclen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(poly_state)); +#endif + return err; +}; + +#endif diff --git a/src/mac/poly1305/poly1305_memory_multi.c b/src/mac/poly1305/poly1305_memory_multi.c new file mode 100644 index 00000000..a8daec89 --- /dev/null +++ b/src/mac/poly1305/poly1305_memory_multi.c @@ -0,0 +1,63 @@ +/* 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. + */ + +/* The implementation is based on: + * Public Domain poly1305 from Andrew Moon + * https://github.com/floodyberry/poly1305-donna + */ + +#include "tomcrypt.h" +#include + +#ifdef LTC_POLY1305 + +/** + POLY1305 multiple blocks of memory to produce the authentication tag + @param key The secret key + @param keylen The length of the secret key (octets) + @param out [out] Destination of the authentication tag + @param outlen [in/out] Max size and resulting size of authentication tag + @param in The data to POLY1305 + @param inlen The length of the data to POLY1305 (octets) + @param ... tuples of (data,len) pairs to POLY1305, terminated with a (NULL,x) (x=don't care) + @return CRYPT_OK if successful +*/ +int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...) +{ + poly_state st; + int err; + va_list args; + const unsigned char *curptr; + unsigned long curlen; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(mac != NULL); + LTC_ARGCHK(maclen != NULL); + + va_start(args, inlen); + curptr = in; + curlen = inlen; + if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } + for (;;) { + if ((err = poly1305_process(&st, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } + curptr = va_arg(args, const unsigned char*); + if (curptr == NULL) break; + curlen = va_arg(args, unsigned long); + } + err = poly1305_done(&st, mac, maclen); +LBL_ERR: +#ifdef LTC_CLEAN_STACK + zeromem(&st, sizeof(poly_state)); +#endif + va_end(args); + return err; +}; + +#endif diff --git a/src/mac/poly1305/poly1305_test.c b/src/mac/poly1305/poly1305_test.c new file mode 100644 index 00000000..218ee2e2 --- /dev/null +++ b/src/mac/poly1305/poly1305_test.c @@ -0,0 +1,50 @@ +/* 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. + */ + +/* The implementation is based on: + * Public Domain poly1305 from Andrew Moon + * https://github.com/floodyberry/poly1305-donna + */ + +#include "tomcrypt.h" + +#ifdef LTC_POLY1305 + +int poly1305_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + /* https://tools.ietf.org/html/rfc7539#section-2.5.2 */ + unsigned char k[] = { 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8, 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd, 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b }; + unsigned char tag[] = { 0xA8, 0x06, 0x1D, 0xC1, 0x30, 0x51, 0x36, 0xC6, 0xC2, 0x2B, 0x8B, 0xAF, 0x0C, 0x01, 0x27, 0xA9 }; + char m[] = "Cryptographic Forum Research Group"; + unsigned long len = 16, mlen = strlen(m); + unsigned char out[1000]; + poly_state st; + /* process piece by piece */ + poly1305_init(&st, k, 32); + poly1305_process(&st, (unsigned char*)m, 5); + poly1305_process(&st, (unsigned char*)m + 5, 4); + poly1305_process(&st, (unsigned char*)m + 9, 3); + poly1305_process(&st, (unsigned char*)m + 12, 2); + poly1305_process(&st, (unsigned char*)m + 14, 1); + poly1305_process(&st, (unsigned char*)m + 15, mlen - 15); + poly1305_done(&st, out, &len); + if (compare_testvector(out, len, tag, sizeof(tag), "POLY1305-TV1", 1) != 0) return CRYPT_FAIL_TESTVECTOR; + /* process in one go */ + poly1305_init(&st, k, 32); + poly1305_process(&st, (unsigned char*)m, mlen); + poly1305_done(&st, out, &len); + if (compare_testvector(out, len, tag, sizeof(tag), "POLY1305-TV2", 1) != 0) return CRYPT_FAIL_TESTVECTOR; + return CRYPT_OK; +#endif +}; + +#endif diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index 192cad20..d97d101d 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -124,6 +124,9 @@ const char *crypt_build_settings = #if defined(LTC_CAMELLIA) " Camellia\n" #endif +#if defined(LTC_CHACHA) + " ChaCha\n" +#endif "\nHashes built-in:\n" #if defined(LTC_SHA3) @@ -230,6 +233,9 @@ const char *crypt_build_settings = #if defined(LTC_F9_MODE) " F9\n" #endif +#if defined(LTC_POLY1305) + " POLY1305\n" +#endif "\nENC + AUTH modes:\n" #if defined(LTC_EAX_MODE) @@ -254,6 +260,9 @@ const char *crypt_build_settings = #endif "\n" #endif +#if defined(LTC_CHACHA20POLY1305_MODE) + " CHACHA20POLY1305\n" +#endif "\nPRNG:\n" #if defined(LTC_YARROW) diff --git a/src/misc/crypt/crypt_sizes.c b/src/misc/crypt/crypt_sizes.c index 9a5cdd9c..15b437fc 100755 --- a/src/misc/crypt/crypt_sizes.c +++ b/src/misc/crypt/crypt_sizes.c @@ -223,6 +223,9 @@ static const crypt_size _crypt_sizes[] = { #ifdef LTC_FORTUNA _SZ_STRINGIFY_S(fortuna_prng), #endif +#ifdef LTC_CHACHA + _SZ_STRINGIFY_S(chacha_prng), +#endif #ifdef LTC_RC4 _SZ_STRINGIFY_S(rc4_prng), #endif diff --git a/src/prngs/chacha.c b/src/prngs/chacha.c new file mode 100644 index 00000000..2d2d2868 --- /dev/null +++ b/src/prngs/chacha.c @@ -0,0 +1,214 @@ +/* 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" + +#ifdef LTC_CHACHA + +const struct ltc_prng_descriptor chacha_prng_desc = +{ + "chacha", + sizeof(chacha_state), + &chacha_prng_start, + &chacha_prng_add_entropy, + &chacha_prng_ready, + &chacha_prng_read, + &chacha_prng_done, + &chacha_prng_export, + &chacha_prng_import, + &chacha_prng_test +}; + +/** + Start the PRNG + @param prng[out] The PRNG state to initialize + @return CRYPT_OK if successful +*/ +int chacha_prng_start(prng_state *prng) +{ + LTC_ARGCHK(prng != NULL); + prng->chacha.ready = 0; + XMEMSET(&prng->chacha.ent, 0, 40); + prng->chacha.idx = 0; + return CRYPT_OK; +} + +/** + Add entropy to the PRNG state + @param in The data to add + @param inlen Length of the data to add + @param prng PRNG state to update + @return CRYPT_OK if successful +*/ +int chacha_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + unsigned char buf[40]; + unsigned long i; + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen > 0); + + if (prng->chacha.ready) { + /* chacha_prng_ready() was already called, do "rekey" operation */ + if ((err = chacha_keystream(&prng->chacha.s, buf, 40)) != CRYPT_OK) return err; + for(i = 0; i < inlen; i++) buf[i % 40] ^= in[i]; + /* key 32 bytes, 20 rounds */ + if ((err = chacha_setup(&prng->chacha.s, buf, 32, 20)) != CRYPT_OK) return err; + /* iv 8 bytes */ + if ((err = chacha_ivctr64(&prng->chacha.s, buf + 32, 8, 0)) != CRYPT_OK) return err; + } + else { + /* chacha_prng_ready() was not called yet, add entropy to ent buffer */ + while (inlen--) prng->chacha.ent[prng->chacha.idx++ % 40] ^= *in++; + } + + return CRYPT_OK; +} + +/** + Make the PRNG ready to read from + @param prng The PRNG to make active + @return CRYPT_OK if successful +*/ +int chacha_prng_ready(prng_state *prng) +{ + int err; + + LTC_ARGCHK(prng != NULL); + + /* key 32 bytes, 20 rounds */ + if ((err = chacha_setup(&prng->chacha.s, prng->chacha.ent, 32, 20)) != CRYPT_OK) return err; + /* iv 8 bytes */ + if ((err = chacha_ivctr64(&prng->chacha.s, prng->chacha.ent + 32, 8, 0)) != CRYPT_OK) return err; + XMEMSET(&prng->chacha.ent, 0, 40); + prng->chacha.ready = 1; + prng->chacha.idx = 0; + return CRYPT_OK; +} + +/** + Read from the PRNG + @param out Destination + @param outlen Length of output + @param prng The active PRNG to read from + @return Number of octets read +*/ +unsigned long chacha_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng) +{ + if (chacha_keystream(&prng->chacha.s, out, outlen) != CRYPT_OK) return 0; + return outlen; +} + +/** + Terminate the PRNG + @param prng The PRNG to terminate + @return CRYPT_OK if successful +*/ +int chacha_prng_done(prng_state *prng) +{ + LTC_UNUSED_PARAM(prng); + prng->chacha.ready = 0; + XMEMSET(&prng->chacha.s, 0, sizeof(chacha_state)); + return CRYPT_OK; +} + +/** + Export the PRNG state + @param out [out] Destination + @param outlen [in/out] Max size and resulting size of the state + @param prng The PRNG to export + @return CRYPT_OK if successful +*/ +int chacha_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) +{ + unsigned long len = sizeof(chacha_state); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(prng != NULL); + + if (!prng->chacha.ready) { + return CRYPT_ERROR; + } + if (*outlen < len) { + *outlen = len; + return CRYPT_BUFFER_OVERFLOW; + } + XMEMCPY(out, &prng->chacha.s, len); + *outlen = len; + return CRYPT_OK; +} + +/** + Import a PRNG state + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +int chacha_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + unsigned long len = sizeof(chacha_state); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); + + if (inlen != len) return CRYPT_INVALID_ARG; + XMEMCPY(&prng->chacha.s, in, inlen); + prng->chacha.ready = 1; + return CRYPT_OK; +} + +/** + PRNG self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled +*/ +int chacha_prng_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + prng_state st; + unsigned char en[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32 }; + unsigned char dmp[300]; + unsigned long dmplen = sizeof(dmp); + unsigned char out[500]; + unsigned char t1[] = { 0x59, 0xb2, 0x26, 0x95, 0x2b, 0x01, 0x8f, 0x05, 0xbe, 0xd8 }; + unsigned char t2[] = { 0x30, 0x34, 0x5c, 0x6e, 0x56, 0x18, 0x8c, 0x46, 0xbe, 0x8a }; + + chacha_prng_start(&st); + chacha_prng_add_entropy(en, sizeof(en), &st); /* add entropy to uninitialized prng */ + chacha_prng_ready(&st); + chacha_prng_read(out, 10, &st); /* 10 bytes for testing */ + if (compare_testvector(out, 10, t1, sizeof(t1), "CHACHA-PRNG", 1) != 0) return CRYPT_FAIL_TESTVECTOR; + chacha_prng_read(out, 500, &st); + chacha_prng_add_entropy(en, sizeof(en), &st); /* add entropy to already initialized prng */ + chacha_prng_read(out, 500, &st); + chacha_prng_export(dmp, &dmplen, &st); + chacha_prng_read(out, 500, &st); /* skip 500 bytes */ + chacha_prng_read(out, 10, &st); /* 10 bytes for testing */ + if (compare_testvector(out, 10, t2, sizeof(t2), "CHACHA-PRNG", 2) != 0) return CRYPT_FAIL_TESTVECTOR; + chacha_prng_done(&st); + + XMEMSET(&st, 0xFF, sizeof(st)); /* just to be sure */ + chacha_prng_import(dmp, dmplen, &st); + chacha_prng_read(out, 500, &st); /* skip 500 bytes */ + chacha_prng_read(out, 10, &st); /* 10 bytes for testing */ + if (compare_testvector(out, 10, t2, sizeof(t2), "CHACHA-PRNG", 3) != 0) return CRYPT_FAIL_TESTVECTOR; + chacha_prng_done(&st); + + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/stream/chacha/chacha_crypt.c b/src/stream/chacha/chacha_crypt.c new file mode 100644 index 00000000..dbd7e9cb --- /dev/null +++ b/src/stream/chacha/chacha_crypt.c @@ -0,0 +1,90 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +#define QUARTERROUND(a,b,c,d) \ + x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \ + x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \ + x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 8); \ + x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 7); + +static void _chacha_block(unsigned char *output, const ulong32 *input, int rounds) +{ + ulong32 x[16]; + int i; + XMEMCPY(x, input, sizeof(x)); + for (i = rounds; i > 0; i -= 2) { + QUARTERROUND(0, 4, 8,12) + QUARTERROUND(1, 5, 9,13) + QUARTERROUND(2, 6,10,14) + QUARTERROUND(3, 7,11,15) + QUARTERROUND(0, 5,10,15) + QUARTERROUND(1, 6,11,12) + QUARTERROUND(2, 7, 8,13) + QUARTERROUND(3, 4, 9,14) + } + for (i = 0; i < 16; ++i) { + x[i] += input[i]; + STORE32L(x[i], output + 4 * i); + } +} + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with ChaCha + @param st The ChaCha state + @param in The plaintext (or ciphertext) + @param inlen The length of the input (octets) + @param out [out] The ciphertext (or plaintext), length inlen + @return CRYPT_OK if successful +*/ +int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) +{ + unsigned char buf[64]; + unsigned long i, j; + + if (inlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + + if (st->ksleft > 0) { + j = MIN(st->ksleft, inlen); + for (i = 0; i < j; ++i, st->ksleft--) out[i] = in[i] ^ st->kstream[64 - st->ksleft]; + inlen -= j; + if (inlen == 0) return CRYPT_OK; + out += j; + in += j; + } + for (;;) { + _chacha_block(buf, st->input, st->rounds); + /* increment the counter */ + if (!++st->input[12] && !++st->input[13] && !++st->input[14]) { ++st->input[15]; } + if (inlen <= 64) { + for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i]; + st->ksleft = 64 - inlen; + for (i = inlen; i < 64; ++i) st->kstream[i] = buf[i]; + return CRYPT_OK; + } + for (i = 0; i < 64; ++i) out[i] = in[i] ^ buf[i]; + inlen -= 64; + out += 64; + in += 64; + } + return CRYPT_OK; +}; + +#endif diff --git a/src/stream/chacha/chacha_ivctr32.c b/src/stream/chacha/chacha_ivctr32.c new file mode 100644 index 00000000..64dc8385 --- /dev/null +++ b/src/stream/chacha/chacha_ivctr32.c @@ -0,0 +1,42 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +/** + Set IV + counter data to the ChaCha state + @param st The ChaCha20 state + @param iv The IV data to add + @param inlen The length of the IV (must be 12) + @param counter 32bit (unsigned) initial counter value + @return CRYPT_OK on success + */ +int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(iv != NULL); + /* 96bit IV + 32bit counter */ + LTC_ARGCHK(ivlen == 12); + + st->input[12] = counter; + LOAD32L(st->input[13], iv + 0); + LOAD32L(st->input[14], iv + 4); + LOAD32L(st->input[15], iv + 8); + st->ksleft = 0; + return CRYPT_OK; +}; + +#endif diff --git a/src/stream/chacha/chacha_ivctr64.c b/src/stream/chacha/chacha_ivctr64.c new file mode 100644 index 00000000..c2826bb7 --- /dev/null +++ b/src/stream/chacha/chacha_ivctr64.c @@ -0,0 +1,42 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +/** + Set IV + counter data to the ChaCha state + @param st The ChaCha20 state + @param iv The IV data to add + @param inlen The length of the IV (must be 8) + @param counter 64bit (unsigned) initial counter value + @return CRYPT_OK on success + */ +int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter) +{ + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(iv != NULL); + /* 64bit IV + 64bit counter */ + LTC_ARGCHK(ivlen == 8); + + st->input[12] = (ulong32)(counter & 0xFFFFFFFF); + st->input[13] = (ulong32)(counter >> 32); + LOAD32L(st->input[14], iv + 0); + LOAD32L(st->input[15], iv + 4); + st->ksleft = 0; + return CRYPT_OK; +}; + +#endif diff --git a/src/stream/chacha/chacha_keystream.c b/src/stream/chacha/chacha_keystream.c new file mode 100644 index 00000000..b45323f2 --- /dev/null +++ b/src/stream/chacha/chacha_keystream.c @@ -0,0 +1,34 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +/** + Generate a stream of random bytes via ChaCha + @param st The ChaCha20 state + @param out [out] The output buffer + @param outlen The output length + @return CRYPT_OK on success + */ +int chacha_keystream(chacha_state *st, unsigned char *out, unsigned long outlen) +{ + if (outlen == 0) return CRYPT_OK; /* nothing to do */ + LTC_ARGCHK(out != NULL); + XMEMSET(out, 0, outlen); + return chacha_crypt(st, out, outlen, out); +} + +#endif diff --git a/src/stream/chacha/chacha_setup.c b/src/stream/chacha/chacha_setup.c new file mode 100644 index 00000000..f56f667a --- /dev/null +++ b/src/stream/chacha/chacha_setup.c @@ -0,0 +1,60 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +/** + Initialize an ChaCha context (only the key) + @param st [out] The destination of the ChaCha state + @param key The secret key + @param keylen The length of the secret key (octets) + @param rounds Number of rounds (e.g. 20 for ChaCha20) + @return CRYPT_OK if successful +*/ +int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds) +{ + const char *constants; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(keylen == 32 || keylen == 16); + + LOAD32L(st->input[4], key + 0); + LOAD32L(st->input[5], key + 4); + LOAD32L(st->input[6], key + 8); + LOAD32L(st->input[7], key + 12); + if (keylen == 32) { /* 256bit */ + key += 16; + constants = sigma; + } else { /* 128bit */ + constants = tau; + } + LOAD32L(st->input[8], key + 0); + LOAD32L(st->input[9], key + 4); + LOAD32L(st->input[10], key + 8); + LOAD32L(st->input[11], key + 12); + LOAD32L(st->input[0], constants + 0); + LOAD32L(st->input[1], constants + 4); + LOAD32L(st->input[2], constants + 8); + LOAD32L(st->input[3], constants + 12); + st->rounds = rounds; /* e.g. 20 for chacha20 */ + return CRYPT_OK; +}; + +#endif diff --git a/src/stream/chacha/chacha_test.c b/src/stream/chacha/chacha_test.c new file mode 100644 index 00000000..49a35f54 --- /dev/null +++ b/src/stream/chacha/chacha_test.c @@ -0,0 +1,60 @@ +/* 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. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt.h" + +#ifdef LTC_CHACHA + +int chacha_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + unsigned long len; + unsigned char out[1000]; + /* https://tools.ietf.org/html/rfc7539#section-2.4.2 */ + unsigned char k[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; + unsigned char n[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00 }; + unsigned char ct[] = { 0x6E, 0x2E, 0x35, 0x9A, 0x25, 0x68, 0xF9, 0x80, 0x41, 0xBA, 0x07, 0x28, 0xDD, 0x0D, 0x69, 0x81, + 0xE9, 0x7E, 0x7A, 0xEC, 0x1D, 0x43, 0x60, 0xC2, 0x0A, 0x27, 0xAF, 0xCC, 0xFD, 0x9F, 0xAE, 0x0B, + 0xF9, 0x1B, 0x65, 0xC5, 0x52, 0x47, 0x33, 0xAB, 0x8F, 0x59, 0x3D, 0xAB, 0xCD, 0x62, 0xB3, 0x57, + 0x16, 0x39, 0xD6, 0x24, 0xE6, 0x51, 0x52, 0xAB, 0x8F, 0x53, 0x0C, 0x35, 0x9F, 0x08, 0x61, 0xD8, + 0x07, 0xCA, 0x0D, 0xBF, 0x50, 0x0D, 0x6A, 0x61, 0x56, 0xA3, 0x8E, 0x08, 0x8A, 0x22, 0xB6, 0x5E, + 0x52, 0xBC, 0x51, 0x4D, 0x16, 0xCC, 0xF8, 0x06, 0x81, 0x8C, 0xE9, 0x1A, 0xB7, 0x79, 0x37, 0x36, + 0x5A, 0xF9, 0x0B, 0xBF, 0x74, 0xA3, 0x5B, 0xE6, 0xB4, 0x0B, 0x8E, 0xED, 0xF2, 0x78, 0x5E, 0x42, + 0x87, 0x4D }; + char pt[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."; + chacha_state st; + + len = strlen(pt); + /* crypt piece by piece */ + chacha_setup(&st, k, sizeof(k), 20); + chacha_ivctr32(&st, n, sizeof(n), 1); + chacha_crypt(&st, (unsigned char*)pt, 35, out); + chacha_crypt(&st, (unsigned char*)pt + 35, 35, out + 35); + chacha_crypt(&st, (unsigned char*)pt + 70, 5, out + 70); + chacha_crypt(&st, (unsigned char*)pt + 75, 5, out + 75); + chacha_crypt(&st, (unsigned char*)pt + 80, len - 80, out + 80); + if (compare_testvector(out, len, ct, sizeof(ct), "CHACHA-TV1", 1) != 0) return CRYPT_FAIL_TESTVECTOR; + /* crypt in one go */ + chacha_setup(&st, k, sizeof(k), 20); + chacha_ivctr32(&st, n, sizeof(n), 1); + chacha_crypt(&st, (unsigned char*)pt, len, out); + if (compare_testvector(out, len, ct, sizeof(ct), "CHACHA-TV2", 1) != 0) return CRYPT_FAIL_TESTVECTOR; + return CRYPT_OK; +#endif +} + +#endif diff --git a/testprof/cipher_hash_test.c b/testprof/cipher_hash_test.c index 36d19886..d7f582ab 100644 --- a/testprof/cipher_hash_test.c +++ b/testprof/cipher_hash_test.c @@ -14,6 +14,11 @@ int cipher_hash_test(void) DOX(cipher_descriptor[x].test(), cipher_descriptor[x].name); } +#ifdef LTC_CHACHA + /* ChaCha is a special case (stream cipher) */ + DO(chacha_test()); +#endif + /* test hashes */ for (x = 0; hash_descriptor[x].name != NULL; x++) { DOX(hash_descriptor[x].test(), hash_descriptor[x].name); diff --git a/testprof/mac_test.c b/testprof/mac_test.c index d6666b2d..e8897cac 100644 --- a/testprof/mac_test.c +++ b/testprof/mac_test.c @@ -35,6 +35,12 @@ int mac_test(void) #endif #ifdef LTC_PELICAN DO(pelican_test()); +#endif +#ifdef LTC_POLY1305 + DO(poly1305_test()); +#endif +#ifdef LTC_CHACHA20POLY1305_MODE + DO(chacha20poly1305_test()); #endif return 0; } diff --git a/testprof/x86_prof.c b/testprof/x86_prof.c index 0d2e0fc1..d4c6fe6c 100644 --- a/testprof/x86_prof.c +++ b/testprof/x86_prof.c @@ -330,6 +330,9 @@ static void _unregister_all(void) #ifdef LTC_RC4 unregister_prng(&rc4_desc); #endif +#ifdef LTC_CHACHA + unregister_prng(&chacha_prng_desc); +#endif #ifdef LTC_SOBER128 unregister_prng(&sober128_desc); #endif @@ -497,6 +500,9 @@ register_prng(&fortuna_desc); #ifdef LTC_RC4 register_prng(&rc4_desc); #endif +#ifdef LTC_CHACHA +register_prng(&chacha_prng_desc); +#endif #ifdef LTC_SOBER128 register_prng(&sober128_desc); #endif