diff --git a/doc/crypt.tex b/doc/crypt.tex index cd001dbab..816ee0047 100644 --- a/doc/crypt.tex +++ b/doc/crypt.tex @@ -5631,6 +5631,7 @@ \subsection{Signature Formats} \hline LTC\_ECCSIG\_ANSIX962 & ASN.1 encoded, ANSI X9.62 \\ \hline LTC\_ECCSIG\_RFC7518 & raw R, S values as defined in RFC7518 \\ \hline LTC\_ECCSIG\_ETH27 & raw R, S, V values (V has 27 added) \\ +\hline LTC\_ECCSIG\_RFC5656 & SSH+ECDSA format as defined in RFC5656 \\ \hline \end{tabular} \end{center} @@ -7792,7 +7793,7 @@ \subsubsection{Endianness} There are also options you can specify from the \textit{tomcrypt\_custom.h} header file. \subsection{X memory routines} -\index{XMALLOC}\index{XREALLOC}\index{XCALLOC}\index{XFREE}\index{XMEMSET}\index{XMEMCPY}\index{XMEMMOVE}\index{XMEMCMP}\index{XSTRCMP} +\index{XMALLOC}\index{XREALLOC}\index{XCALLOC}\index{XFREE}\index{XMEMSET}\index{XMEMCPY}\index{XMEMMOVE}\index{XMEMCMP}\index{XSTRCMP}\index{XSTRNCPY} At the top of tomcrypt\_custom.h are a series of macros denoted as XMALLOC, XCALLOC, XREALLOC, XFREE, and so on. They resolve to the name of the respective functions from the standard C library by default. This lets you substitute in your own memory routines. If you substitute in your own functions they must behave like the standard C library functions in terms of what they expect as input and diff --git a/helper.pl b/helper.pl index 90b743e88..22fac916a 100755 --- a/helper.pl +++ b/helper.pl @@ -53,6 +53,8 @@ sub check_source { push @{$troubles->{unwanted_memmove}}, $lineno if $file =~ /^src\/.*\.c$/ && $l =~ /\bmemmove\s*\(/; push @{$troubles->{unwanted_memcmp}}, $lineno if $file =~ /^src\/.*\.c$/ && $l =~ /\bmemcmp\s*\(/; push @{$troubles->{unwanted_strcmp}}, $lineno if $file =~ /^src\/.*\.c$/ && $l =~ /\bstrcmp\s*\(/; + push @{$troubles->{unwanted_strcpy}}, $lineno if $file =~ /^src\/.*\.c$/ && $l =~ /\bstrcpy\s*\(/; + push @{$troubles->{unwanted_strncpy}}, $lineno if $file =~ /^src\/.*\.c$/ && $l =~ /\bstrncpy\s*\(/; push @{$troubles->{unwanted_clock}}, $lineno if $file =~ /^src\/.*\.c$/ && $l =~ /\bclock\s*\(/; push @{$troubles->{unwanted_qsort}}, $lineno if $file =~ /^src\/.*\.c$/ && $l =~ /\bqsort\s*\(/; push @{$troubles->{sizeof_no_brackets}}, $lineno if $file =~ /^src\/.*\.c$/ && $l =~ /\bsizeof\s*[^\(]/; diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj index 1f07c419d..8bc1c62c9 100644 --- a/libtomcrypt_VS2008.vcproj +++ b/libtomcrypt_VS2008.vcproj @@ -1607,6 +1607,18 @@ > + + + + + + + + diff --git a/makefile.mingw b/makefile.mingw index 8cad94e91..9d0a70f9d 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -112,7 +112,8 @@ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/ src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \ src/misc/padding/padding_pad.o src/misc/pbes/pbes.o src/misc/pbes/pbes1.o src/misc/pbes/pbes2.o \ src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o src/misc/pkcs5/pkcs_5_1.o \ -src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \ +src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/ssh/ssh_decode_sequence_multi.o \ +src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \ src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \ src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \ src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o \ @@ -184,18 +185,19 @@ src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o src/ src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o src/pk/ecc/ecc_import_pkcs8.o \ src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_recover_key.o \ src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o src/pk/ecc/ecc_set_key.o \ -src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \ -src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o \ -src/pk/ecc/ltc_ecc_is_point.o src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o \ -src/pk/ecc/ltc_ecc_mul2add.o src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o \ -src/pk/ecc/ltc_ecc_points.o src/pk/ecc/ltc_ecc_projective_add_point.o \ -src/pk/ecc/ltc_ecc_projective_dbl_point.o src/pk/ecc/ltc_ecc_verify_key.o src/pk/pkcs1/pkcs_1_i2osp.o \ -src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o \ -src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \ -src/pk/pkcs1/pkcs_1_v1_5_decode.o src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o \ -src/pk/rsa/rsa_encrypt_key.o 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_pkcs8.o \ -src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \ +src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o \ +src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \ +src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ +src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ +src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ +src/pk/ecc/ltc_ecc_verify_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ +src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +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_pkcs8.o src/pk/rsa/rsa_import_x509.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.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/chacha20.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_done.o \ @@ -218,7 +220,7 @@ tests/common.o tests/der_test.o tests/dh_test.o tests/dsa_test.o tests/ecc_test. tests/mac_test.o tests/misc_test.o tests/modes_test.o tests/mpi_test.o tests/multi_test.o tests/no_prng.o \ tests/padding_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o tests/pkcs_1_oaep_test.o \ tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o tests/rotate_test.o tests/rsa_test.o \ -tests/store_test.o tests/test.o +tests/ssh_test.o tests/store_test.o tests/test.o #The following headers will be installed by "make install" HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ diff --git a/makefile.msvc b/makefile.msvc index e819c2ccf..6b2c10061 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -105,7 +105,8 @@ src/misc/crypt/crypt_unregister_prng.obj src/misc/error_to_string.obj src/misc/h src/misc/hkdf/hkdf_test.obj src/misc/mem_neq.obj src/misc/padding/padding_depad.obj \ src/misc/padding/padding_pad.obj src/misc/pbes/pbes.obj src/misc/pbes/pbes1.obj src/misc/pbes/pbes2.obj \ src/misc/pkcs12/pkcs12_kdf.obj src/misc/pkcs12/pkcs12_utf8_to_utf16.obj src/misc/pkcs5/pkcs_5_1.obj \ -src/misc/pkcs5/pkcs_5_2.obj src/misc/pkcs5/pkcs_5_test.obj src/misc/zeromem.obj src/modes/cbc/cbc_decrypt.obj \ +src/misc/pkcs5/pkcs_5_2.obj src/misc/pkcs5/pkcs_5_test.obj src/misc/ssh/ssh_decode_sequence_multi.obj \ +src/misc/ssh/ssh_encode_sequence_multi.obj src/misc/zeromem.obj src/modes/cbc/cbc_decrypt.obj \ src/modes/cbc/cbc_done.obj src/modes/cbc/cbc_encrypt.obj src/modes/cbc/cbc_getiv.obj \ src/modes/cbc/cbc_setiv.obj src/modes/cbc/cbc_start.obj src/modes/cfb/cfb_decrypt.obj \ src/modes/cfb/cfb_done.obj src/modes/cfb/cfb_encrypt.obj src/modes/cfb/cfb_getiv.obj \ @@ -177,18 +178,19 @@ src/pk/ecc/ecc_free.obj src/pk/ecc/ecc_get_key.obj src/pk/ecc/ecc_get_oid_str.ob src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_import_openssl.obj src/pk/ecc/ecc_import_pkcs8.obj \ src/pk/ecc/ecc_import_x509.obj src/pk/ecc/ecc_make_key.obj src/pk/ecc/ecc_recover_key.obj \ src/pk/ecc/ecc_set_curve.obj src/pk/ecc/ecc_set_curve_internal.obj src/pk/ecc/ecc_set_key.obj \ -src/pk/ecc/ecc_shared_secret.obj src/pk/ecc/ecc_sign_hash.obj src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_test.obj \ -src/pk/ecc/ecc_verify_hash.obj src/pk/ecc/ltc_ecc_export_point.obj src/pk/ecc/ltc_ecc_import_point.obj \ -src/pk/ecc/ltc_ecc_is_point.obj src/pk/ecc/ltc_ecc_is_point_at_infinity.obj src/pk/ecc/ltc_ecc_map.obj \ -src/pk/ecc/ltc_ecc_mul2add.obj src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj \ -src/pk/ecc/ltc_ecc_points.obj src/pk/ecc/ltc_ecc_projective_add_point.obj \ -src/pk/ecc/ltc_ecc_projective_dbl_point.obj src/pk/ecc/ltc_ecc_verify_key.obj src/pk/pkcs1/pkcs_1_i2osp.obj \ -src/pk/pkcs1/pkcs_1_mgf1.obj src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj \ -src/pk/pkcs1/pkcs_1_os2ip.obj src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj \ -src/pk/pkcs1/pkcs_1_v1_5_decode.obj src/pk/pkcs1/pkcs_1_v1_5_encode.obj src/pk/rsa/rsa_decrypt_key.obj \ -src/pk/rsa/rsa_encrypt_key.obj 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_pkcs8.obj \ -src/pk/rsa/rsa_import_x509.obj src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_set.obj src/pk/rsa/rsa_sign_hash.obj \ +src/pk/ecc/ecc_shared_secret.obj src/pk/ecc/ecc_sign_hash.obj src/pk/ecc/ecc_sizes.obj \ +src/pk/ecc/ecc_ssh_ecdsa_encode_name.obj src/pk/ecc/ecc_test.obj src/pk/ecc/ecc_verify_hash.obj \ +src/pk/ecc/ltc_ecc_export_point.obj src/pk/ecc/ltc_ecc_import_point.obj src/pk/ecc/ltc_ecc_is_point.obj \ +src/pk/ecc/ltc_ecc_is_point_at_infinity.obj src/pk/ecc/ltc_ecc_map.obj src/pk/ecc/ltc_ecc_mul2add.obj \ +src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \ +src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \ +src/pk/ecc/ltc_ecc_verify_key.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \ +src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \ +src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/pkcs1/pkcs_1_v1_5_decode.obj \ +src/pk/pkcs1/pkcs_1_v1_5_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \ +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_pkcs8.obj src/pk/rsa/rsa_import_x509.obj \ +src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_set.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/chacha20.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_done.obj \ @@ -211,7 +213,7 @@ tests/common.obj tests/der_test.obj tests/dh_test.obj tests/dsa_test.obj tests/e tests/mac_test.obj tests/misc_test.obj tests/modes_test.obj tests/mpi_test.obj tests/multi_test.obj tests/no_prng.obj \ tests/padding_test.obj tests/pkcs_1_eme_test.obj tests/pkcs_1_emsa_test.obj tests/pkcs_1_oaep_test.obj \ tests/pkcs_1_pss_test.obj tests/pkcs_1_test.obj tests/prng_test.obj tests/rotate_test.obj tests/rsa_test.obj \ -tests/store_test.obj tests/test.obj +tests/ssh_test.obj tests/store_test.obj tests/test.obj #The following headers will be installed by "make install" HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ diff --git a/makefile.unix b/makefile.unix index 5f911050d..20f9a0d9b 100644 --- a/makefile.unix +++ b/makefile.unix @@ -122,7 +122,8 @@ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/ src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \ src/misc/padding/padding_pad.o src/misc/pbes/pbes.o src/misc/pbes/pbes1.o src/misc/pbes/pbes2.o \ src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o src/misc/pkcs5/pkcs_5_1.o \ -src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \ +src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/ssh/ssh_decode_sequence_multi.o \ +src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \ src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \ src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \ src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o \ @@ -194,18 +195,19 @@ src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o src/ src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o src/pk/ecc/ecc_import_pkcs8.o \ src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_recover_key.o \ src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o src/pk/ecc/ecc_set_key.o \ -src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \ -src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o \ -src/pk/ecc/ltc_ecc_is_point.o src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o \ -src/pk/ecc/ltc_ecc_mul2add.o src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o \ -src/pk/ecc/ltc_ecc_points.o src/pk/ecc/ltc_ecc_projective_add_point.o \ -src/pk/ecc/ltc_ecc_projective_dbl_point.o src/pk/ecc/ltc_ecc_verify_key.o src/pk/pkcs1/pkcs_1_i2osp.o \ -src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o \ -src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \ -src/pk/pkcs1/pkcs_1_v1_5_decode.o src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o \ -src/pk/rsa/rsa_encrypt_key.o 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_pkcs8.o \ -src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \ +src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o \ +src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \ +src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ +src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ +src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ +src/pk/ecc/ltc_ecc_verify_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ +src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +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_pkcs8.o src/pk/rsa/rsa_import_x509.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.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/chacha20.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_done.o \ @@ -228,7 +230,7 @@ tests/common.o tests/der_test.o tests/dh_test.o tests/dsa_test.o tests/ecc_test. tests/mac_test.o tests/misc_test.o tests/modes_test.o tests/mpi_test.o tests/multi_test.o tests/no_prng.o \ tests/padding_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o tests/pkcs_1_oaep_test.o \ tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o tests/rotate_test.o tests/rsa_test.o \ -tests/store_test.o tests/test.o +tests/ssh_test.o tests/store_test.o tests/test.o #The following headers will be installed by "make install" HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ diff --git a/makefile_include.mk b/makefile_include.mk index f6345eb8b..4bcec2206 100644 --- a/makefile_include.mk +++ b/makefile_include.mk @@ -282,7 +282,8 @@ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/ src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \ src/misc/padding/padding_pad.o src/misc/pbes/pbes.o src/misc/pbes/pbes1.o src/misc/pbes/pbes2.o \ src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o src/misc/pkcs5/pkcs_5_1.o \ -src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \ +src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/ssh/ssh_decode_sequence_multi.o \ +src/misc/ssh/ssh_encode_sequence_multi.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \ src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \ src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \ src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o \ @@ -354,18 +355,19 @@ src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o src/ src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o src/pk/ecc/ecc_import_pkcs8.o \ src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_recover_key.o \ src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o src/pk/ecc/ecc_set_key.o \ -src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \ -src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o \ -src/pk/ecc/ltc_ecc_is_point.o src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o \ -src/pk/ecc/ltc_ecc_mul2add.o src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o \ -src/pk/ecc/ltc_ecc_points.o src/pk/ecc/ltc_ecc_projective_add_point.o \ -src/pk/ecc/ltc_ecc_projective_dbl_point.o src/pk/ecc/ltc_ecc_verify_key.o src/pk/pkcs1/pkcs_1_i2osp.o \ -src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o \ -src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o \ -src/pk/pkcs1/pkcs_1_v1_5_decode.o src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o \ -src/pk/rsa/rsa_encrypt_key.o 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_pkcs8.o \ -src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \ +src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o \ +src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \ +src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ +src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ +src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ +src/pk/ecc/ltc_ecc_verify_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ +src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ +src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ +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_pkcs8.o src/pk/rsa/rsa_import_x509.o \ +src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.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/chacha20.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_done.o \ @@ -388,7 +390,7 @@ tests/common.o tests/der_test.o tests/dh_test.o tests/dsa_test.o tests/ecc_test. tests/mac_test.o tests/misc_test.o tests/modes_test.o tests/mpi_test.o tests/multi_test.o tests/no_prng.o \ tests/padding_test.o tests/pkcs_1_eme_test.o tests/pkcs_1_emsa_test.o tests/pkcs_1_oaep_test.o \ tests/pkcs_1_pss_test.o tests/pkcs_1_test.o tests/prng_test.o tests/rotate_test.o tests/rsa_test.o \ -tests/store_test.o tests/test.o +tests/ssh_test.o tests/store_test.o tests/test.o # The following headers will be installed by "make install" HEADERS_PUB=src/headers/tomcrypt.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cfg.h \ diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 1ec2a304b..aedf08bc3 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -43,7 +43,10 @@ #define XMEM_NEQ mem_neq #endif #ifndef XSTRCMP -#define XSTRCMP strcmp +#define XSTRCMP strcmp +#endif +#ifndef XSTRNCPY +#define XSTRNCPY strncpy #endif #ifndef XCLOCK @@ -56,7 +59,7 @@ #if ( defined(malloc) || defined(realloc) || defined(calloc) || defined(free) || \ defined(memset) || defined(memcpy) || defined(memcmp) || defined(strcmp) || \ - defined(clock) || defined(qsort) ) && !defined(LTC_NO_PROTOTYPES) + defined(strncpy) || defined(clock) || defined(qsort) ) && !defined(LTC_NO_PROTOTYPES) #define LTC_NO_PROTOTYPES #endif @@ -494,6 +497,8 @@ #define LTC_CRC32 +#define LTC_SSH + #define LTC_PADDING #define LTC_PBES diff --git a/src/headers/tomcrypt_misc.h b/src/headers/tomcrypt_misc.h index a5dd130ee..78e233d77 100644 --- a/src/headers/tomcrypt_misc.h +++ b/src/headers/tomcrypt_misc.h @@ -154,6 +154,23 @@ int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded int padding_depad(const unsigned char *data, unsigned long *length, unsigned long mode); #endif /* LTC_PADDING */ +#ifdef LTC_SSH +typedef enum ssh_data_type_ { + LTC_SSHDATA_BYTE, + LTC_SSHDATA_BOOLEAN, + LTC_SSHDATA_UINT32, + LTC_SSHDATA_UINT64, + LTC_SSHDATA_STRING, + LTC_SSHDATA_MPINT, + LTC_SSHDATA_NAMELIST, + LTC_SSHDATA_EOL +} ssh_data_type; + +/* VA list handy helpers with tuples of */ +int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); +int ssh_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); +#endif /* LTC_SSH */ + int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); /* ref: $Format:%D$ */ diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index 64b39db52..49eeda595 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -251,7 +251,9 @@ typedef enum ecc_signature_type_ { /* raw R, S values */ LTC_ECCSIG_RFC7518 = 0x1, /* raw R, S, V (+27) values */ - LTC_ECCSIG_ETH27 = 0x2 + LTC_ECCSIG_ETH27 = 0x2, + /* SSH + ECDSA signature format defined by RFC5656 */ + LTC_ECCSIG_RFC5656 = 0x3, } ecc_signature_type; /** the ECC params provided */ diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index 5da8f7299..e536d579e 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -226,6 +226,10 @@ int ecc_copy_curve(const ecc_key *srckey, ecc_key *key); int ecc_set_curve_by_size(int size, ecc_key *key); int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key); +#ifdef LTC_SSH +int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key); +#endif + /* low level functions */ ecc_point *ltc_ecc_new_point(void); void ltc_ecc_del_point(ecc_point *p); diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index a90732fad..b6b25c1e2 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -452,6 +452,9 @@ const char *crypt_build_settings = " PBES1 " " PBES2 " #endif +#if defined(LTC_SSH) + " SSH " +#endif #if defined(LTC_DEVRANDOM) " LTC_DEVRANDOM " #endif diff --git a/src/misc/ssh/ssh_decode_sequence_multi.c b/src/misc/ssh/ssh_decode_sequence_multi.c new file mode 100644 index 000000000..f01a03199 --- /dev/null +++ b/src/misc/ssh/ssh_decode_sequence_multi.c @@ -0,0 +1,161 @@ +/* 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_private.h" +#include + +/** + @file ssh_decode_sequence_multi.c + SSH data type representation as per RFC4251, Russ Williams +*/ + +#ifdef LTC_SSH + +/** + Decode a SSH sequence using a VA list + @param in Data to decode + @param inlen Length of buffer to decode + @remark <...> is of the form (int, void*) except for string + @return CRYPT_OK on success +*/ +int ssh_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) +{ + int err; + va_list args; + ssh_data_type type; + void *vdata; + unsigned char *cdata; + char *sdata; + ulong32 *u32data; + ulong64 *u64data; + unsigned long size, bufsize; + + LTC_ARGCHK(in != NULL); + + /* Decode values from buffer */ + va_start(args, inlen); + while ((type = (ssh_data_type)va_arg(args, int)) != LTC_SSHDATA_EOL) { + /* Size of length field */ + if (type == LTC_SSHDATA_STRING || + type == LTC_SSHDATA_NAMELIST || + type == LTC_SSHDATA_MPINT) + { + /* Check we'll not read too far */ + if (inlen < 4) { + err = CRYPT_BUFFER_OVERFLOW; + goto error; + } + } + + /* Calculate (or read) length of data */ + size = (unsigned long)-1; + switch (type) { + case LTC_SSHDATA_BYTE: + case LTC_SSHDATA_BOOLEAN: + size = 1; + break; + case LTC_SSHDATA_UINT32: + size = 4; + break; + case LTC_SSHDATA_UINT64: + size = 8; + break; + case LTC_SSHDATA_STRING: + case LTC_SSHDATA_NAMELIST: + case LTC_SSHDATA_MPINT: + LOAD32H(size, in); + in += 4; + inlen -= 4; + break; + + case LTC_SSHDATA_EOL: + /* Should never get here */ + err = CRYPT_INVALID_ARG; + goto error; + } + + /* Check we'll not read too far */ + if (inlen < size) { + err = CRYPT_BUFFER_OVERFLOW; + goto error; + } else { + inlen -= size; + } + + /* Read data */ + switch (type) { + case LTC_SSHDATA_BYTE: + cdata = va_arg(args, unsigned char*); + *cdata = *in++; + break; + case LTC_SSHDATA_BOOLEAN: + cdata = va_arg(args, unsigned char*); + /* + The value 0 represents FALSE, and the value 1 represents TRUE. All non-zero values MUST be + interpreted as TRUE; however, applications MUST NOT store values other than 0 and 1. + */ + *cdata = (*in++)?1:0; + break; + case LTC_SSHDATA_UINT32: + u32data = va_arg(args, ulong32*); + LOAD32H(*u32data, in); + in += 4; + break; + case LTC_SSHDATA_UINT64: + u64data = va_arg(args, ulong64*); + LOAD64H(*u64data, in); + in += 8; + break; + case LTC_SSHDATA_STRING: + case LTC_SSHDATA_NAMELIST: + sdata = va_arg(args, char*); + bufsize = va_arg(args, unsigned long); + if (size >= bufsize) { + err = CRYPT_BUFFER_OVERFLOW; + goto error; + } + if (size > 0) { + XSTRNCPY(sdata, (const char *)in, size); + sdata[size] = '\0'; /* strncpy doesn't NUL-terminate */ + } else { + *sdata = '\0'; + } + in += size; + break; + case LTC_SSHDATA_MPINT: + vdata = va_arg(args, void*); + if (size == 0) { + if ((err = mp_set(vdata, 0)) != CRYPT_OK) { goto error; } + } else if ((in[0] & 0x80) != 0) { + /* Negative number - not supported */ + err = CRYPT_INVALID_PACKET; + goto error; + } else { + if ((err = mp_read_unsigned_bin(vdata, (unsigned char *)in, size)) != CRYPT_OK) { goto error; } + } + in += size; + break; + + case LTC_SSHDATA_EOL: + /* Should never get here */ + err = CRYPT_INVALID_ARG; + goto error; + } + } + err = CRYPT_OK; + +error: + va_end(args); + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/misc/ssh/ssh_encode_sequence_multi.c b/src/misc/ssh/ssh_encode_sequence_multi.c new file mode 100644 index 000000000..0fe237850 --- /dev/null +++ b/src/misc/ssh/ssh_encode_sequence_multi.c @@ -0,0 +1,168 @@ +/* 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_private.h" +#include + +/** + @file ssh_encode_sequence_multi.c + SSH data type representation as per RFC4251, Russ Williams +*/ + +#ifdef LTC_SSH + +/** + Encode a SSH sequence using a VA list + @param out [out] Destination for data + @param outlen [in/out] Length of buffer and resulting length of output + @remark <...> is of the form (int, void*) + @return CRYPT_OK on success +*/ +int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) +{ + int err; + va_list args; + unsigned long size; + ssh_data_type type; + void *vdata; + const char *sdata; + int idata; + ulong32 u32data; + ulong64 u64data; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* Check values and calculate output size */ + size = 0; + va_start(args, outlen); + while ((type = (ssh_data_type)va_arg(args, int)) != LTC_SSHDATA_EOL) { + switch (type) { + case LTC_SSHDATA_BYTE: + case LTC_SSHDATA_BOOLEAN: /* Both stored as 1 byte */ + LTC_UNUSED_PARAM( va_arg(args, int) ); + size++; + break; + case LTC_SSHDATA_UINT32: + LTC_UNUSED_PARAM( va_arg(args, ulong32) ); + size += 4; + break; + case LTC_SSHDATA_UINT64: + LTC_UNUSED_PARAM( va_arg(args, ulong64) ); + size += 8; + break; + case LTC_SSHDATA_STRING: + case LTC_SSHDATA_NAMELIST: + sdata = va_arg(args, char*); + size += 4; + size += strlen(sdata); + break; + case LTC_SSHDATA_MPINT: + vdata = va_arg(args, void*); + /* Calculate size */ + size += 4; + if (mp_iszero(vdata) != LTC_MP_YES) { + size += mp_unsigned_bin_size(vdata); + if ((mp_count_bits(vdata) & 7) == 0) size++; /* Zero padding if high bit set */ + } + break; + + case LTC_SSHDATA_EOL: /* Should never get here */ + err = CRYPT_INVALID_ARG; + goto error; + } + } + va_end(args); + + /* Check we have sufficient space */ + if (*outlen < size) { + *outlen = size; + err = CRYPT_BUFFER_OVERFLOW; + goto errornoargs; + } + *outlen = size; + + /* Encode values into buffer */ + va_start(args, outlen); + while ((type = (ssh_data_type)va_arg(args, int)) != LTC_SSHDATA_EOL) { + switch (type) { + case LTC_SSHDATA_BYTE: + idata = va_arg(args, int); + + *out++ = (unsigned char)(idata & 255); + break; + case LTC_SSHDATA_BOOLEAN: + idata = va_arg(args, int); + + /* + The value 0 represents FALSE, and the value 1 represents TRUE. All non-zero values MUST be + interpreted as TRUE; however, applications MUST NOT store values other than 0 and 1. + */ + *out++ = (idata)?1:0; + break; + case LTC_SSHDATA_UINT32: + u32data = va_arg(args, ulong32); + STORE32H(u32data, out); + out += 4; + break; + case LTC_SSHDATA_UINT64: + u64data = va_arg(args, ulong64); + STORE64H(u64data, out); + out += 8; + break; + case LTC_SSHDATA_STRING: + case LTC_SSHDATA_NAMELIST: + sdata = va_arg(args, char*); + size = strlen(sdata); + STORE32H(size, out); + out += 4; + XSTRNCPY((char *)out, sdata, size); + out += size; + break; + case LTC_SSHDATA_MPINT: + vdata = va_arg(args, void*); + if (mp_iszero(vdata) == LTC_MP_YES) { + STORE32H(0, out); + out += 4; + } else { + size = mp_unsigned_bin_size(vdata); + if ((mp_count_bits(vdata) & 7) == 0) { + /* Zero padding if high bit set */ + STORE32H(size+1, out); + out += 4; + *out++ = 0; + } else { + STORE32H(size, out); + out += 4; + } + if ((err = mp_to_unsigned_bin(vdata, out)) != CRYPT_OK) { + err = CRYPT_ERROR; + goto error; + } + out += size; + } + break; + + case LTC_SSHDATA_EOL: /* Should never get here */ + err = CRYPT_INVALID_ARG; + goto error; + } + } + err = CRYPT_OK; + +error: + va_end(args); +errornoargs: + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/pk/ecc/ecc_recover_key.c b/src/pk/ecc/ecc_recover_key.c index 25562a239..d3a70df7a 100644 --- a/src/pk/ecc/ecc_recover_key.c +++ b/src/pk/ecc/ecc_recover_key.c @@ -92,8 +92,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, } else if (sigformat == LTC_ECCSIG_ETH27) { /* Ethereum (v,r,s) format */ - if (key->dp.oidlen != 5 || key->dp.oid[0] != 1 || key->dp.oid[1] != 3 || - key->dp.oid[2] != 132 || key->dp.oid[3] != 0 || key->dp.oid[4] != 10) { + if (pk_oid_cmp_with_ulong("1.3.132.0.10", key->dp.oid, key->dp.oidlen) != CRYPT_OK) { /* Only valid for secp256k1 - OID 1.3.132.0.10 */ err = CRYPT_ERROR; goto error; } @@ -112,6 +111,27 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, if ((err = mp_read_unsigned_bin(r, (unsigned char *)sig, 32)) != CRYPT_OK) { goto error; } if ((err = mp_read_unsigned_bin(s, (unsigned char *)sig+32, 32)) != CRYPT_OK) { goto error; } } +#ifdef LTC_SSH + else if (sigformat == LTC_ECCSIG_RFC5656) { + char name[64], name2[64]; + unsigned long namelen = sizeof(name2); + + /* Decode as SSH data sequence, per RFC4251 */ + if ((err = ssh_decode_sequence_multi(sig, siglen, + LTC_SSHDATA_STRING, name, 64, + LTC_SSHDATA_MPINT, r, + LTC_SSHDATA_MPINT, s, + LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) { goto error; } + + + /* Check curve matches identifier string */ + if ((err = ecc_ssh_ecdsa_encode_name(name2, &namelen, key)) != CRYPT_OK) { goto error; } + if (XSTRCMP(name,name2) != 0) { + err = CRYPT_INVALID_ARG; + goto error; + } + } +#endif else { /* Unknown signature format */ err = CRYPT_ERROR; diff --git a/src/pk/ecc/ecc_sign_hash.c b/src/pk/ecc/ecc_sign_hash.c index 6764dae66..c7a808d8d 100644 --- a/src/pk/ecc/ecc_sign_hash.c +++ b/src/pk/ecc/ecc_sign_hash.c @@ -141,8 +141,7 @@ int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, } else if (sigformat == LTC_ECCSIG_ETH27) { /* Ethereum (v,r,s) format */ - if (key->dp.oidlen != 5 || key->dp.oid[0] != 1 || key->dp.oid[1] != 3 || - key->dp.oid[2] != 132 || key->dp.oid[3] != 0 || key->dp.oid[4] != 10) { + if (pk_oid_cmp_with_ulong("1.3.132.0.10", key->dp.oid, key->dp.oidlen) != CRYPT_OK) { /* Only valid for secp256k1 - OID 1.3.132.0.10 */ err = CRYPT_ERROR; goto errnokey; } @@ -156,6 +155,21 @@ int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, *outlen = 65; err = CRYPT_OK; } +#ifdef LTC_SSH + else if (sigformat == LTC_ECCSIG_RFC5656) { + /* Get identifier string */ + char name[64]; + unsigned long namelen = sizeof(name); + if ((err = ecc_ssh_ecdsa_encode_name(name, &namelen, key)) != CRYPT_OK) { goto errnokey; } + + /* Store as SSH data sequence, per RFC4251 */ + err = ssh_encode_sequence_multi(out, outlen, + LTC_SSHDATA_STRING, name, + LTC_SSHDATA_MPINT, r, + LTC_SSHDATA_MPINT, s, + LTC_SSHDATA_EOL, NULL); + } +#endif else { /* Unknown signature format */ err = CRYPT_ERROR; diff --git a/src/pk/ecc/ecc_ssh_ecdsa_encode_name.c b/src/pk/ecc/ecc_ssh_ecdsa_encode_name.c new file mode 100644 index 000000000..048f29d24 --- /dev/null +++ b/src/pk/ecc/ecc_ssh_ecdsa_encode_name.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_private.h" + +/** + @file ecc_ssh_ecdsa_encode_name.c + Curve/OID to SSH+ECDSA name string mapping per RFC5656 + Russ Williams +*/ + +/** + Curve/OID to SSH+ECDSA name string mapping + @param buffer [out] The destination for the name + @param buflen [in/out] The max size and resulting size (including terminator) of the name + @param key A public or private ECC key + @return CRYPT_OK if successful +*/ +int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key) +{ + char oidstr[64]; + unsigned long oidlen = sizeof(oidstr); + unsigned long size = 0; + int err; + + LTC_ARGCHK(buffer != NULL); + LTC_ARGCHK(buflen != NULL); + LTC_ARGCHK(key != NULL); + + /* Get the OID of the curve */ + if ((err = ecc_get_oid_str(oidstr, &oidlen, key)) != CRYPT_OK) goto error; + + /* Check for three named curves: nistp256, nistp384, nistp521 */ + if (XSTRCMP("1.2.840.10045.3.1.7", oidstr) == 0) { + /* nistp256 - secp256r1 - OID 1.2.840.10045.3.1.7 */ + size = snprintf(buffer, *buflen, "ecdsa-sha2-nistp256"); + } + else if (XSTRCMP("1.3.132.0.34", oidstr) == 0) { + /* nistp384 - secp384r1 - OID 1.3.132.0.34 */ + size = snprintf(buffer, *buflen, "ecdsa-sha2-nistp384"); + } + else if (XSTRCMP("1.3.132.0.35", oidstr) == 0) { + /* nistp521 - secp521r1 - OID 1.3.132.0.35 */ + size = snprintf(buffer, *buflen, "ecdsa-sha2-nistp521"); + } else { + /* Otherwise we use the OID... */ + size = snprintf(buffer, *buflen, "ecdsa-sha2-%s", oidstr); + } + + /* snprintf returns size that would have been written, but limits to buflen-1 chars plus terminator */ + if (size >= *buflen) { + err = CRYPT_BUFFER_OVERFLOW; + } else { + err = CRYPT_OK; + } + *buflen = size + 1; /* the string length + NUL byte */ + +error: + return err; +} + + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/pk/ecc/ecc_verify_hash.c b/src/pk/ecc/ecc_verify_hash.c index 98b8ac1ce..e89db8c0e 100644 --- a/src/pk/ecc/ecc_verify_hash.c +++ b/src/pk/ecc/ecc_verify_hash.c @@ -86,8 +86,7 @@ int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, } else if (sigformat == LTC_ECCSIG_ETH27) { /* Ethereum (v,r,s) format */ - if (key->dp.oidlen != 5 || key->dp.oid[0] != 1 || key->dp.oid[1] != 3 || - key->dp.oid[2] != 132 || key->dp.oid[3] != 0 || key->dp.oid[4] != 10) { + if (pk_oid_cmp_with_ulong("1.3.132.0.10", key->dp.oid, key->dp.oidlen) != CRYPT_OK) { /* Only valid for secp256k1 - OID 1.3.132.0.10 */ err = CRYPT_ERROR; goto error; } @@ -98,6 +97,27 @@ int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, if ((err = mp_read_unsigned_bin(r, (unsigned char *)sig, 32)) != CRYPT_OK) { goto error; } if ((err = mp_read_unsigned_bin(s, (unsigned char *)sig+32, 32)) != CRYPT_OK) { goto error; } } +#ifdef LTC_SSH + else if (sigformat == LTC_ECCSIG_RFC5656) { + char name[64], name2[64]; + unsigned long namelen = sizeof(name2); + + /* Decode as SSH data sequence, per RFC4251 */ + if ((err = ssh_decode_sequence_multi(sig, siglen, + LTC_SSHDATA_STRING, name, 64, + LTC_SSHDATA_MPINT, r, + LTC_SSHDATA_MPINT, s, + LTC_SSHDATA_EOL, NULL)) != CRYPT_OK) { goto error; } + + + /* Check curve matches identifier string */ + if ((err = ecc_ssh_ecdsa_encode_name(name2, &namelen, key)) != CRYPT_OK) { goto error; } + if (XSTRCMP(name,name2) != 0) { + err = CRYPT_INVALID_ARG; + goto error; + } + } +#endif else { /* Unknown signature format */ err = CRYPT_ERROR; diff --git a/tests/common.h b/tests/common.h index d44949328..5f2ac3cc7 100644 --- a/tests/common.h +++ b/tests/common.h @@ -23,6 +23,7 @@ extern prng_state yarrow_prng; #define SHOULD_FAIL(x) do { run_cmd((x) != CRYPT_OK ? CRYPT_OK : CRYPT_FAIL_TESTVECTOR, __LINE__, __FILE__, #x, NULL); } while (0) #endif +#define COMPARE_TESTVECTOR(i, il, s, sl, wa, wi) do { DO(do_compare_testvector((i), (il), (s), (sl), (wa), (wi))); } while(0) #if !((defined(_WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__)) #define LTC_TEST_READDIR diff --git a/tests/ecc_test.c b/tests/ecc_test.c index f0bf41d35..d017f720b 100644 --- a/tests/ecc_test.c +++ b/tests/ecc_test.c @@ -37,6 +37,93 @@ static unsigned int sizes[] = { #endif }; +static const char* curvenames[] = { +#ifdef LTC_ECC_SECP112R1 + "SECP112R1", "ECC-112", + "secp112r1", /* name is case-insensitive */ + "S E C-P-1_1_2r1", /* should pass fuzzy matching */ +#endif +#ifdef LTC_ECC_SECP112R2 + "SECP112R2", +#endif +#ifdef LTC_ECC_SECP128R1 + "SECP128R1", "ECC-128", +#endif +#ifdef LTC_ECC_SECP128R2 + "SECP128R2", +#endif +#ifdef LTC_ECC_SECP160R1 + "SECP160R1", "ECC-160", +#endif +#ifdef LTC_ECC_SECP160R2 + "SECP160R2", +#endif +#ifdef LTC_ECC_SECP160K1 + "SECP160K1", +#endif +#ifdef LTC_ECC_BRAINPOOLP160R1 + "BRAINPOOLP160R1", +#endif +#ifdef LTC_ECC_SECP192R1 + "SECP192R1", "NISTP192", "PRIME192V1", "ECC-192", "P-192", +#endif +#ifdef LTC_ECC_PRIME192V2 + "PRIME192V2", +#endif +#ifdef LTC_ECC_PRIME192V3 + "PRIME192V3", +#endif +#ifdef LTC_ECC_SECP192K1 + "SECP192K1", +#endif +#ifdef LTC_ECC_BRAINPOOLP192R1 + "BRAINPOOLP192R1", +#endif +#ifdef LTC_ECC_SECP224R1 + "SECP224R1", "NISTP224", "ECC-224", "P-224", +#endif +#ifdef LTC_ECC_SECP224K1 + "SECP224K1", +#endif +#ifdef LTC_ECC_BRAINPOOLP224R1 + "BRAINPOOLP224R1", +#endif +#ifdef LTC_ECC_PRIME239V1 + "PRIME239V1", +#endif +#ifdef LTC_ECC_PRIME239V2 + "PRIME239V2", +#endif +#ifdef LTC_ECC_PRIME239V3 + "PRIME239V3", +#endif +#ifdef LTC_ECC_SECP256R1 + "SECP256R1", "NISTP256", "PRIME256V1", "ECC-256", "P-256", +#endif +#ifdef LTC_ECC_SECP256K1 + "SECP256K1", +#endif +#ifdef LTC_ECC_BRAINPOOLP256R1 + "BRAINPOOLP256R1", +#endif +#ifdef LTC_ECC_BRAINPOOLP320R1 + "BRAINPOOLP320R1", +#endif +#ifdef LTC_ECC_SECP384R1 + "SECP384R1", "NISTP384", "ECC-384", "P-384", +#endif +#ifdef LTC_ECC_BRAINPOOLP384R1 + "BRAINPOOLP384R1", +#endif +#ifdef LTC_ECC_BRAINPOOLP512R1 + "BRAINPOOLP512R1", +#endif +#ifdef LTC_ECC_SECP521R1 + "SECP521R1", "NISTP521", "ECC-521", "P-521", +#endif +}; + + #ifdef LTC_ECC_SHAMIR static int _ecc_test_shamir(void) { @@ -423,91 +510,6 @@ static int _ecc_key_cmp(const int should_type, const ecc_key *should, const ecc_ static int _ecc_new_api(void) { - const char* names[] = { -#ifdef LTC_ECC_SECP112R1 - "SECP112R1", "ECC-112", - "secp112r1", /* name is case-insensitive */ - "S E C-P-1_1_2r1", /* should pass fuzzy matching */ -#endif -#ifdef LTC_ECC_SECP112R2 - "SECP112R2", -#endif -#ifdef LTC_ECC_SECP128R1 - "SECP128R1", "ECC-128", -#endif -#ifdef LTC_ECC_SECP128R2 - "SECP128R2", -#endif -#ifdef LTC_ECC_SECP160R1 - "SECP160R1", "ECC-160", -#endif -#ifdef LTC_ECC_SECP160R2 - "SECP160R2", -#endif -#ifdef LTC_ECC_SECP160K1 - "SECP160K1", -#endif -#ifdef LTC_ECC_BRAINPOOLP160R1 - "BRAINPOOLP160R1", -#endif -#ifdef LTC_ECC_SECP192R1 - "SECP192R1", "NISTP192", "PRIME192V1", "ECC-192", "P-192", -#endif -#ifdef LTC_ECC_PRIME192V2 - "PRIME192V2", -#endif -#ifdef LTC_ECC_PRIME192V3 - "PRIME192V3", -#endif -#ifdef LTC_ECC_SECP192K1 - "SECP192K1", -#endif -#ifdef LTC_ECC_BRAINPOOLP192R1 - "BRAINPOOLP192R1", -#endif -#ifdef LTC_ECC_SECP224R1 - "SECP224R1", "NISTP224", "ECC-224", "P-224", -#endif -#ifdef LTC_ECC_SECP224K1 - "SECP224K1", -#endif -#ifdef LTC_ECC_BRAINPOOLP224R1 - "BRAINPOOLP224R1", -#endif -#ifdef LTC_ECC_PRIME239V1 - "PRIME239V1", -#endif -#ifdef LTC_ECC_PRIME239V2 - "PRIME239V2", -#endif -#ifdef LTC_ECC_PRIME239V3 - "PRIME239V3", -#endif -#ifdef LTC_ECC_SECP256R1 - "SECP256R1", "NISTP256", "PRIME256V1", "ECC-256", "P-256", -#endif -#ifdef LTC_ECC_SECP256K1 - "SECP256K1", -#endif -#ifdef LTC_ECC_BRAINPOOLP256R1 - "BRAINPOOLP256R1", -#endif -#ifdef LTC_ECC_BRAINPOOLP320R1 - "BRAINPOOLP320R1", -#endif -#ifdef LTC_ECC_SECP384R1 - "SECP384R1", "NISTP384", "ECC-384", "P-384", -#endif -#ifdef LTC_ECC_BRAINPOOLP384R1 - "BRAINPOOLP384R1", -#endif -#ifdef LTC_ECC_BRAINPOOLP512R1 - "BRAINPOOLP512R1", -#endif -#ifdef LTC_ECC_SECP521R1 - "SECP521R1", "NISTP521", "ECC-521", "P-521", -#endif - }; int i, j, stat; const ltc_ecc_curve* dp; ecc_key key, privkey, pubkey; @@ -516,8 +518,8 @@ static int _ecc_new_api(void) unsigned char data16[16] = { 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1 }; unsigned long len16; - for (i = 0; i < (int)(sizeof(names)/sizeof(names[0])); i++) { - DO(ecc_find_curve(names[i], &dp)); + for (i = 0; i < (int)(sizeof(curvenames)/sizeof(curvenames[0])); i++) { + DO(ecc_find_curve(curvenames[i], &dp)); /* make new key */ DO(ecc_make_key_ex(&yarrow_prng, find_prng ("yarrow"), &key, dp)); len = sizeof(buf); @@ -572,6 +574,16 @@ static int _ecc_new_api(void) DO(ecc_verify_hash(buf, len, data16, 16, &stat, &pubkey)); if (stat != 1) return CRYPT_FAIL_TESTVECTOR; +#ifdef LTC_SSH + /* test SSH+ECDSA/RFC5656 signature */ + len = sizeof(buf); + DO(ecc_sign_hash_ex(data16, 16, buf, &len, &yarrow_prng, find_prng ("yarrow"), + LTC_ECCSIG_RFC5656, NULL, &privkey)); + stat = 0; + DO(ecc_verify_hash_ex(buf, len, data16, 16, LTC_ECCSIG_RFC5656, &stat, &pubkey)); + if (stat != 1) return CRYPT_FAIL_TESTVECTOR; +#endif + #ifdef LTC_ECC_SHAMIR if (strcmp(ltc_mp.name, "TomsFastMath") != 0) { /* XXX-FIXME: TFM does not support sqrtmod_prime */ @@ -1477,91 +1489,6 @@ static int _ecc_import_export(void) { #ifdef LTC_ECC_SHAMIR static int _ecc_test_recovery(void) { - const char* names[] = { -#ifdef LTC_ECC_SECP112R1 - "SECP112R1", "ECC-112", - "secp112r1", /* name is case-insensitive */ - "S E C-P-1_1_2r1", /* should pass fuzzy matching */ -#endif -#ifdef LTC_ECC_SECP112R2 - "SECP112R2", -#endif -#ifdef LTC_ECC_SECP128R1 - "SECP128R1", "ECC-128", -#endif -#ifdef LTC_ECC_SECP128R2 - "SECP128R2", -#endif -#ifdef LTC_ECC_SECP160R1 - "SECP160R1", "ECC-160", -#endif -#ifdef LTC_ECC_SECP160R2 - "SECP160R2", -#endif -#ifdef LTC_ECC_SECP160K1 - "SECP160K1", -#endif -#ifdef LTC_ECC_BRAINPOOLP160R1 - "BRAINPOOLP160R1", -#endif -#ifdef LTC_ECC_SECP192R1 - "SECP192R1", "NISTP192", "PRIME192V1", "ECC-192", "P-192", -#endif -#ifdef LTC_ECC_PRIME192V2 - "PRIME192V2", -#endif -#ifdef LTC_ECC_PRIME192V3 - "PRIME192V3", -#endif -#ifdef LTC_ECC_SECP192K1 - "SECP192K1", -#endif -#ifdef LTC_ECC_BRAINPOOLP192R1 - "BRAINPOOLP192R1", -#endif -#ifdef LTC_ECC_SECP224R1 - "SECP224R1", "NISTP224", "ECC-224", "P-224", -#endif -#ifdef LTC_ECC_SECP224K1 - "SECP224K1", -#endif -#ifdef LTC_ECC_BRAINPOOLP224R1 - "BRAINPOOLP224R1", -#endif -#ifdef LTC_ECC_PRIME239V1 - "PRIME239V1", -#endif -#ifdef LTC_ECC_PRIME239V2 - "PRIME239V2", -#endif -#ifdef LTC_ECC_PRIME239V3 - "PRIME239V3", -#endif -#ifdef LTC_ECC_SECP256R1 - "SECP256R1", "NISTP256", "PRIME256V1", "ECC-256", "P-256", -#endif -#ifdef LTC_ECC_SECP256K1 - "SECP256K1", -#endif -#ifdef LTC_ECC_BRAINPOOLP256R1 - "BRAINPOOLP256R1", -#endif -#ifdef LTC_ECC_BRAINPOOLP320R1 - "BRAINPOOLP320R1", -#endif -#ifdef LTC_ECC_SECP384R1 - "SECP384R1", "NISTP384", "ECC-384", "P-384", -#endif -#ifdef LTC_ECC_BRAINPOOLP384R1 - "BRAINPOOLP384R1", -#endif -#ifdef LTC_ECC_BRAINPOOLP512R1 - "BRAINPOOLP512R1", -#endif -#ifdef LTC_ECC_SECP521R1 - "SECP521R1", "NISTP521", "ECC-521", "P-521", -#endif - }; int i, recid, stat; const ltc_ecc_curve* dp; ecc_key key, privkey, pubkey, reckey; @@ -1611,8 +1538,8 @@ static int _ecc_test_recovery(void) ecc_free(&pubkey); #endif - for (i = 0; i < (int)(sizeof(names)/sizeof(names[0])); i++) { - DO(ecc_find_curve(names[i], &dp)); + for (i = 0; i < (int)(sizeof(curvenames)/sizeof(curvenames[0])); i++) { + DO(ecc_find_curve(curvenames[i], &dp)); /* generate new key */ DO(ecc_set_curve(dp, &key)); diff --git a/tests/misc_test.c b/tests/misc_test.c index c20418035..67648f973 100644 --- a/tests/misc_test.c +++ b/tests/misc_test.c @@ -33,6 +33,9 @@ int misc_test(void) #endif #ifdef LTC_CRC32 DO(crc32_test()); +#endif +#ifdef LTC_SSH + DO(ssh_test()); #endif return 0; } diff --git a/tests/ssh_test.c b/tests/ssh_test.c new file mode 100644 index 000000000..942a745de --- /dev/null +++ b/tests/ssh_test.c @@ -0,0 +1,310 @@ +/* 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_test.h" + +/** + @file ssh_test.c + Support for SSH data formats (RFC4251), Russ Williams +*/ + +#ifdef LTC_SSH + +#define BUFSIZE 64 + +/** + Test vectors from from RFC4251, section 5 + + uint32: "the value 699921578 (0x29b7f4aa) is stored as 29 b7 f4 aa" + + string: "the US-ASCII string "testing" is represented as 00 00 00 07 t e s t i n g" + + mpint: + value (hex) representation (hex) + ----------- -------------------- + 0 00 00 00 00 + 9a378f9b2e332a7 00 00 00 08 09 a3 78 f9 b2 e3 32 a7 + 80 00 00 00 02 00 80 + -1234 00 00 00 02 ed cc + -deadbeef 00 00 00 05 ff 21 52 41 11 + + name-list: + value representation (hex) + ----- -------------------- + (), the empty name-list 00 00 00 00 + ("zlib") 00 00 00 04 7a 6c 69 62 + ("zlib,none") 00 00 00 09 7a 6c 69 62 2c 6e 6f 6e 65 +*/ +static const unsigned char byte1[] = {0x01}; +static const unsigned char byte2[] = {0x71}; +static const unsigned char uint32[] = {0x29, 0xb7, 0xf4, 0xaa}; +static const unsigned char uint64[] = {0x09, 0xa3, 0x78, 0xf9, 0xb2, 0xe3, 0x32, 0xa7}; +static const unsigned char string[] = {0x00, 0x00, 0x00, 0x07, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67}; +static const unsigned char mpint1[] = {0x00, 0x00, 0x00, 0x00}; +static const unsigned char mpint2[] = {0x00, 0x00, 0x00, 0x08, 0x09, 0xa3, 0x78, 0xf9, 0xb2, 0xe3, 0x32, 0xa7}; +static const unsigned char mpint3[] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x80}; +static const unsigned char nlist1[] = {0x00, 0x00, 0x00, 0x00}; +static const unsigned char nlist2[] = {0x00, 0x00, 0x00, 0x04, 0x7a, 0x6c, 0x69, 0x62}; +static const unsigned char nlist3[] = {0x00, 0x00, 0x00, 0x09, 0x7a, 0x6c, 0x69, 0x62, 0x2c, 0x6e, 0x6f, 0x6e, 0x65}; + + +/** + LTC_SSH encoding test + @return CRYPT_OK if successful +*/ +static int _ssh_encoding_test(void) +{ + unsigned char buffer[BUFSIZE]; + unsigned long buflen; + void *v, *zero; + int err; + + /* Buffer too short */ + buflen = 3; + zeromem(buffer, BUFSIZE); + err = ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_UINT32, 0x29b7f4aa, + LTC_SSHDATA_EOL, NULL); + if (err != CRYPT_BUFFER_OVERFLOW) return CRYPT_FAIL_TESTVECTOR; + + + /* byte */ + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_BYTE, 0x01, + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, byte1, sizeof(byte1), "enc-byte", 1); + + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_BYTE, 0x71, + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, byte2, sizeof(byte2), "enc-byte", 2); + if (XMEMCMP(buffer, byte2, buflen) != 0) return CRYPT_FAIL_TESTVECTOR; + + /* boolean */ + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_BOOLEAN, 0x01, + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, byte1, sizeof(byte1), "enc-boolean", 1); + + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_BOOLEAN, 0x71, + LTC_SSHDATA_EOL, NULL)); + /* Should be written out as 0x01 */ + COMPARE_TESTVECTOR(buffer, buflen, byte1, sizeof(byte1), "enc-boolean", 2); + + /* uint32 */ + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_UINT32, 0x29b7f4aa, + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, uint32, sizeof(uint32), "enc-uint32", 1); + + /* uint64 */ + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_UINT64, CONST64(0x09a378f9b2e332a7), + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, uint64, sizeof(uint64), "enc-uint64", 1); + + + /* string */ + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_STRING, "testing", + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, string, sizeof(string), "enc-string", 1); + + + /* mpint */ + if ((err = mp_init_multi(&zero, &v, NULL)) != CRYPT_OK) { + return err; + } + + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(mp_set(zero, 0)); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_MPINT, zero, + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, mpint1, sizeof(mpint1), "enc-mpint", 1); + + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(mp_read_radix(v, "9a378f9b2e332a7", 16)); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_MPINT, v, + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, mpint2, sizeof(mpint2), "enc-mpint", 2); + + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(mp_set(v, 0x80)); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_MPINT, v, + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, mpint3, sizeof(mpint3), "enc-mpint", 3); + + mp_clear_multi(v, zero, NULL); + + + /* name-list */ + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_NAMELIST, "", + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, nlist1, sizeof(nlist1), "enc-nlist", 1); + + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_NAMELIST, "zlib", + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, nlist2, sizeof(nlist2), "enc-nlist", 2); + + buflen = BUFSIZE; + zeromem(buffer, BUFSIZE); + DO(ssh_encode_sequence_multi(buffer, &buflen, + LTC_SSHDATA_NAMELIST, "zlib,none", + LTC_SSHDATA_EOL, NULL)); + COMPARE_TESTVECTOR(buffer, buflen, nlist3, sizeof(nlist3), "enc-nlist", 3); + + return CRYPT_OK; +} + +/** + LTC_SSH decoding test + @return CRYPT_OK if successful +*/ +static int _ssh_decoding_test(void) +{ + char strbuf[BUFSIZE]; + void *u, *v; + ulong32 tmp32; + ulong64 tmp64; + unsigned char tmp8; + int err; + + /* byte */ + DO(ssh_decode_sequence_multi(byte1, sizeof(byte1), + LTC_SSHDATA_BYTE, &tmp8, + LTC_SSHDATA_EOL, NULL)); + if (tmp8 != 0x01) return CRYPT_FAIL_TESTVECTOR; + + DO(ssh_decode_sequence_multi(byte2, sizeof(byte2), + LTC_SSHDATA_BYTE, &tmp8, + LTC_SSHDATA_EOL, NULL)); + if (tmp8 != 0x71) return CRYPT_FAIL_TESTVECTOR; + + /* boolean */ + DO(ssh_decode_sequence_multi(byte1, sizeof(byte1), + LTC_SSHDATA_BOOLEAN, &tmp8, + LTC_SSHDATA_EOL, NULL)); + if (tmp8 != 0x01) return CRYPT_FAIL_TESTVECTOR; + + DO(ssh_decode_sequence_multi(byte2, sizeof(byte2), + LTC_SSHDATA_BOOLEAN, &tmp8, + LTC_SSHDATA_EOL, NULL)); + if (tmp8 != 0x01) return CRYPT_FAIL_TESTVECTOR; + + /* uint32 */ + DO(ssh_decode_sequence_multi(uint32, sizeof(uint32), + LTC_SSHDATA_UINT32, &tmp32, + LTC_SSHDATA_EOL, NULL)); + if (tmp32 != 0x29b7f4aa) return CRYPT_FAIL_TESTVECTOR; + + /* uint64 */ + DO(ssh_decode_sequence_multi(uint64, sizeof(uint64), + LTC_SSHDATA_UINT64, &tmp64, + LTC_SSHDATA_EOL, NULL)); + if (tmp64 != CONST64(0x09a378f9b2e332a7)) return CRYPT_FAIL_TESTVECTOR; + + /* string */ + zeromem(strbuf, BUFSIZE); + DO(ssh_decode_sequence_multi(string, sizeof(string), + LTC_SSHDATA_STRING, strbuf, BUFSIZE, + LTC_SSHDATA_EOL, NULL)); + if (XSTRCMP(strbuf, "testing") != 0) return CRYPT_FAIL_TESTVECTOR; + + /* mpint */ + if ((err = mp_init_multi(&u, &v, NULL)) != CRYPT_OK) { + return err; + } + + DO(ssh_decode_sequence_multi(mpint1, sizeof(mpint1), + LTC_SSHDATA_MPINT, v, + LTC_SSHDATA_EOL, NULL)); + if (mp_cmp_d(v, 0) != LTC_MP_EQ) return CRYPT_FAIL_TESTVECTOR; + + DO(mp_read_radix(u, "9a378f9b2e332a7", 16)); + DO(ssh_decode_sequence_multi(mpint2, sizeof(mpint2), + LTC_SSHDATA_MPINT, v, + LTC_SSHDATA_EOL, NULL)); + if (mp_cmp(u, v) != LTC_MP_EQ) return CRYPT_FAIL_TESTVECTOR; + + DO(ssh_decode_sequence_multi(mpint3, sizeof(mpint3), + LTC_SSHDATA_MPINT, v, + LTC_SSHDATA_EOL, NULL)); + if (mp_cmp_d(v, 0x80) != LTC_MP_EQ) return CRYPT_FAIL_TESTVECTOR; + + mp_clear_multi(v, u, NULL); + + /* name-list */ + zeromem(strbuf, BUFSIZE); + DO(ssh_decode_sequence_multi(nlist1, sizeof(nlist1), + LTC_SSHDATA_NAMELIST, strbuf, BUFSIZE, + LTC_SSHDATA_EOL, NULL)); + if (XSTRCMP(strbuf, "") != 0) return CRYPT_FAIL_TESTVECTOR; + + zeromem(strbuf, BUFSIZE); + DO(ssh_decode_sequence_multi(nlist2, sizeof(nlist2), + LTC_SSHDATA_NAMELIST, strbuf, BUFSIZE, + LTC_SSHDATA_EOL, NULL)); + if (XSTRCMP(strbuf, "zlib") != 0) return CRYPT_FAIL_TESTVECTOR; + + zeromem(strbuf, BUFSIZE); + DO(ssh_decode_sequence_multi(nlist3, sizeof(nlist3), + LTC_SSHDATA_NAMELIST, strbuf, BUFSIZE, + LTC_SSHDATA_EOL, NULL)); + if (XSTRCMP(strbuf, "zlib,none") != 0) return CRYPT_FAIL_TESTVECTOR; + + + return CRYPT_OK; +} + +/** + LTC_SSH self-test + @return CRYPT_OK if successful, CRYPT_NOP if tests have been disabled. +*/ +int ssh_test(void) +{ + DO(_ssh_encoding_test()); + DO(_ssh_decoding_test()); + + return CRYPT_OK; +} + + + +#endif + + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/tests/tomcrypt_test.h b/tests/tomcrypt_test.h index 22fbe0006..00304534d 100644 --- a/tests/tomcrypt_test.h +++ b/tests/tomcrypt_test.h @@ -45,6 +45,9 @@ int prng_test(void); int mpi_test(void); int padding_test(void); +#ifdef LTC_SSH +int ssh_test(void); +#endif #ifdef LTC_PKCS_1 struct ltc_prng_descriptor* no_prng_desc_get(void);