diff --git a/demos/timing.c b/demos/timing.c index 52dd11522..d356d0a97 100644 --- a/demos/timing.c +++ b/demos/timing.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" #if defined(_WIN32) @@ -872,7 +873,7 @@ static void time_ecc(void) unsigned char buf[2][256] = { 0 }; unsigned long i, w, x, y, z; int err, stat; - static unsigned long sizes[] = { + const unsigned long sizes[] = { #ifdef LTC_ECC_SECP112R1 112/8, #endif @@ -898,6 +899,11 @@ static void time_ecc(void) 521/8, #endif 100000}; + ltc_ecc_sig_opts sig_opts = { + .type = LTC_ECCSIG_RFC7518, + .prng = &yarrow_prng, + .wprng = find_prng ("yarrow") + }; if (ltc_mp.name == NULL) return; @@ -969,8 +975,7 @@ static void time_ecc(void) t_start(); t1 = t_read(); z = sizeof(buf[1]); - if ((err = ecc_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng, - find_prng("yarrow"), &key)) != CRYPT_OK) { + if ((err = ecc_sign_hash_v2(buf[0], 20, buf[1], &z, &sig_opts, &key)) != CRYPT_OK) { fprintf(stderr, "\n\necc_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } @@ -988,7 +993,7 @@ static void time_ecc(void) for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); - if ((err = ecc_verify_hash(buf[1], z, buf[0], 20, &stat, &key)) != CRYPT_OK) { + if ((err = ecc_verify_hash_v2(buf[1], z, buf[0], 20, &sig_opts, &stat, &key)) != CRYPT_OK) { fprintf(stderr, "\n\necc_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj index 72d7fb779..200dc670a 100644 --- a/libtomcrypt_VS2008.vcproj +++ b/libtomcrypt_VS2008.vcproj @@ -1387,6 +1387,10 @@ RelativePath="src\misc\crc32.c" > + + @@ -2277,6 +2281,14 @@ RelativePath="src\pk\asn1\x509\x509_encode_subject_public_key_info.c" > + + + + + + @@ -2558,6 +2574,10 @@ RelativePath="src\pk\ecc\ecc_verify_hash_rfc7518.c" > + + diff --git a/makefile b/makefile index 72437220c..5ba4de0d3 100644 --- a/makefile +++ b/makefile @@ -154,6 +154,7 @@ pre_gen/tomcrypt_amalgam.c: $(TAB_SOURCES) $(SOURCES) printf "#define LTC_SAFER_TAB_C\n" >> $@ printf "#define LTC_SOBER128TAB_C\n" >> $@ printf "#define LTC_WHIRLTAB_C\n\n" >> $@ + printf "#define LTC_DEPRECATED(x)\n\n" >> $@ printf "#include \"tomcrypt_private.h\"\n\n" >> $@ cat $^ >> $@ diff --git a/makefile.mingw b/makefile.mingw index 1c323f103..2dc38b9c5 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -109,8 +109,8 @@ src/misc/crypt/crypt_register_all_ciphers.o src/misc/crypt/crypt_register_all_ha src/misc/crypt/crypt_register_all_prngs.o src/misc/crypt/crypt_register_cipher.o \ src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ -src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \ -src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \ +src/misc/crypt/crypt_unregister_prng.o src/misc/deprecated.o src/misc/error_to_string.o \ +src/misc/hkdf/hkdf.o 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/password_free.o src/misc/pbes/pbes.o src/misc/pbes/pbes1.o \ src/misc/pbes/pbes2.o src/misc/pem/pem.o src/misc/pem/pem_pkcs.o src/misc/pem/pem_read.o \ src/misc/pem/pem_ssh.o src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o \ @@ -176,9 +176,10 @@ src/pk/asn1/oid/pk_get.o src/pk/asn1/oid/pk_oid_cmp.o src/pk/asn1/oid/pk_oid_str src/pk/asn1/pkcs8/pkcs8_decode_flexi.o src/pk/asn1/pkcs8/pkcs8_get.o \ src/pk/asn1/x509/x509_decode_public_key_from_certificate.o src/pk/asn1/x509/x509_decode_spki.o \ src/pk/asn1/x509/x509_decode_subject_public_key_info.o \ -src/pk/asn1/x509/x509_encode_subject_public_key_info.o src/pk/dh/dh.o src/pk/dh/dh_check_pubkey.o \ -src/pk/dh/dh_export.o src/pk/dh/dh_export_key.o src/pk/dh/dh_free.o src/pk/dh/dh_generate_key.o \ -src/pk/dh/dh_import.o src/pk/dh/dh_import_pkcs8.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o \ +src/pk/asn1/x509/x509_encode_subject_public_key_info.o src/pk/asn1/x509/x509_get_pka.o \ +src/pk/asn1/x509/x509_import_spki.o src/pk/dh/dh.o src/pk/dh/dh_check_pubkey.o src/pk/dh/dh_export.o \ +src/pk/dh/dh_export_key.o src/pk/dh/dh_free.o src/pk/dh/dh_generate_key.o src/pk/dh/dh_import.o \ +src/pk/dh/dh_import_pkcs8.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o \ src/pk/dh/dh_shared_secret.o src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o \ src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_generate_key.o \ src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_import_pkcs8.o \ @@ -194,18 +195,19 @@ src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_k src/pk/ecc/ecc_recover_key.o src/pk/ecc/ecc_rfc6979_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_sign_hash_eth27.o src/pk/ecc/ecc_sign_hash_internal.o \ -src/pk/ecc/ecc_sign_hash_rfc5656.o src/pk/ecc/ecc_sign_hash_rfc7518.o src/pk/ecc/ecc_sizes.o \ -src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ecc_verify_hash_eth27.o \ -src/pk/ecc/ecc_verify_hash_internal.o src/pk/ecc/ecc_verify_hash_rfc5656.o \ -src/pk/ecc/ecc_verify_hash_rfc7518.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/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \ -src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_raw.o \ -src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_sign.o \ -src/pk/ed25519/ed25519_verify.o src/pk/pka_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/ecc/ecc_sign_hash_rfc5656.o src/pk/ecc/ecc_sign_hash_rfc7518.o src/pk/ecc/ecc_sign_hash_x962.o \ +src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ecc_verify_hash_eth27.o src/pk/ecc/ecc_verify_hash_internal.o \ +src/pk/ecc/ecc_verify_hash_rfc5656.o src/pk/ecc/ecc_verify_hash_rfc7518.o \ +src/pk/ecc/ecc_verify_hash_x962.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/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o src/pk/ed25519/ed25519_import_pkcs8.o \ +src/pk/ed25519/ed25519_import_raw.o src/pk/ed25519/ed25519_import_x509.o \ +src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_sign.o src/pk/ed25519/ed25519_verify.o \ +src/pk/pka_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 \ @@ -233,13 +235,13 @@ src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o #List of test objects to compile TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/bcrypt_test.o \ -tests/cipher_hash_test.o tests/common.o tests/der_test.o tests/dh_test.o tests/dsa_test.o \ -tests/ecc_test.o tests/ed25519_test.o tests/file_test.o tests/mac_test.o tests/misc_test.o \ -tests/modes_test.o tests/mpi_test.o tests/multi_test.o tests/no_null_termination_check_test.o \ -tests/no_prng.o tests/padding_test.o tests/pem_test.o tests/pk_oid_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/ssh_test.o tests/store_test.o tests/test.o \ -tests/x25519_test.o +tests/cipher_hash_test.o tests/common.o tests/deprecated_test.o tests/der_test.o tests/dh_test.o \ +tests/dsa_test.o tests/ecc_test.o tests/ed25519_test.o tests/file_test.o tests/mac_test.o \ +tests/misc_test.o tests/modes_test.o tests/mpi_test.o tests/multi_test.o \ +tests/no_null_termination_check_test.o tests/no_prng.o tests/padding_test.o tests/pem_test.o \ +tests/pk_oid_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/ssh_test.o tests/store_test.o tests/test.o tests/x25519_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 91d17f9bd..6fdf20715 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -102,8 +102,8 @@ src/misc/crypt/crypt_register_all_ciphers.obj src/misc/crypt/crypt_register_all_ src/misc/crypt/crypt_register_all_prngs.obj src/misc/crypt/crypt_register_cipher.obj \ src/misc/crypt/crypt_register_hash.obj src/misc/crypt/crypt_register_prng.obj src/misc/crypt/crypt_sizes.obj \ src/misc/crypt/crypt_unregister_cipher.obj src/misc/crypt/crypt_unregister_hash.obj \ -src/misc/crypt/crypt_unregister_prng.obj src/misc/error_to_string.obj src/misc/hkdf/hkdf.obj \ -src/misc/hkdf/hkdf_test.obj src/misc/mem_neq.obj src/misc/padding/padding_depad.obj \ +src/misc/crypt/crypt_unregister_prng.obj src/misc/deprecated.obj src/misc/error_to_string.obj \ +src/misc/hkdf/hkdf.obj 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/password_free.obj src/misc/pbes/pbes.obj src/misc/pbes/pbes1.obj \ src/misc/pbes/pbes2.obj src/misc/pem/pem.obj src/misc/pem/pem_pkcs.obj src/misc/pem/pem_read.obj \ src/misc/pem/pem_ssh.obj src/misc/pkcs12/pkcs12_kdf.obj src/misc/pkcs12/pkcs12_utf8_to_utf16.obj \ @@ -169,9 +169,10 @@ src/pk/asn1/oid/pk_get.obj src/pk/asn1/oid/pk_oid_cmp.obj src/pk/asn1/oid/pk_oid src/pk/asn1/pkcs8/pkcs8_decode_flexi.obj src/pk/asn1/pkcs8/pkcs8_get.obj \ src/pk/asn1/x509/x509_decode_public_key_from_certificate.obj src/pk/asn1/x509/x509_decode_spki.obj \ src/pk/asn1/x509/x509_decode_subject_public_key_info.obj \ -src/pk/asn1/x509/x509_encode_subject_public_key_info.obj src/pk/dh/dh.obj src/pk/dh/dh_check_pubkey.obj \ -src/pk/dh/dh_export.obj src/pk/dh/dh_export_key.obj src/pk/dh/dh_free.obj src/pk/dh/dh_generate_key.obj \ -src/pk/dh/dh_import.obj src/pk/dh/dh_import_pkcs8.obj src/pk/dh/dh_set.obj src/pk/dh/dh_set_pg_dhparam.obj \ +src/pk/asn1/x509/x509_encode_subject_public_key_info.obj src/pk/asn1/x509/x509_get_pka.obj \ +src/pk/asn1/x509/x509_import_spki.obj src/pk/dh/dh.obj src/pk/dh/dh_check_pubkey.obj src/pk/dh/dh_export.obj \ +src/pk/dh/dh_export_key.obj src/pk/dh/dh_free.obj src/pk/dh/dh_generate_key.obj src/pk/dh/dh_import.obj \ +src/pk/dh/dh_import_pkcs8.obj src/pk/dh/dh_set.obj src/pk/dh/dh_set_pg_dhparam.obj \ src/pk/dh/dh_shared_secret.obj src/pk/dsa/dsa_decrypt_key.obj src/pk/dsa/dsa_encrypt_key.obj \ src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_generate_key.obj \ src/pk/dsa/dsa_generate_pqg.obj src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_import_pkcs8.obj \ @@ -187,18 +188,19 @@ src/pk/ecc/ecc_import_pkcs8.obj src/pk/ecc/ecc_import_x509.obj src/pk/ecc/ecc_ma src/pk/ecc/ecc_recover_key.obj src/pk/ecc/ecc_rfc6979_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_sign_hash_eth27.obj src/pk/ecc/ecc_sign_hash_internal.obj \ -src/pk/ecc/ecc_sign_hash_rfc5656.obj src/pk/ecc/ecc_sign_hash_rfc7518.obj src/pk/ecc/ecc_sizes.obj \ -src/pk/ecc/ecc_ssh_ecdsa_encode_name.obj src/pk/ecc/ecc_verify_hash.obj src/pk/ecc/ecc_verify_hash_eth27.obj \ -src/pk/ecc/ecc_verify_hash_internal.obj src/pk/ecc/ecc_verify_hash_rfc5656.obj \ -src/pk/ecc/ecc_verify_hash_rfc7518.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/ed25519/ed25519_export.obj src/pk/ed25519/ed25519_import.obj \ -src/pk/ed25519/ed25519_import_pkcs8.obj src/pk/ed25519/ed25519_import_raw.obj \ -src/pk/ed25519/ed25519_import_x509.obj src/pk/ed25519/ed25519_make_key.obj src/pk/ed25519/ed25519_sign.obj \ -src/pk/ed25519/ed25519_verify.obj src/pk/pka_key.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \ +src/pk/ecc/ecc_sign_hash_rfc5656.obj src/pk/ecc/ecc_sign_hash_rfc7518.obj src/pk/ecc/ecc_sign_hash_x962.obj \ +src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_ssh_ecdsa_encode_name.obj src/pk/ecc/ecc_verify_hash.obj \ +src/pk/ecc/ecc_verify_hash_eth27.obj src/pk/ecc/ecc_verify_hash_internal.obj \ +src/pk/ecc/ecc_verify_hash_rfc5656.obj src/pk/ecc/ecc_verify_hash_rfc7518.obj \ +src/pk/ecc/ecc_verify_hash_x962.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/ed25519/ed25519_export.obj src/pk/ed25519/ed25519_import.obj src/pk/ed25519/ed25519_import_pkcs8.obj \ +src/pk/ed25519/ed25519_import_raw.obj src/pk/ed25519/ed25519_import_x509.obj \ +src/pk/ed25519/ed25519_make_key.obj src/pk/ed25519/ed25519_sign.obj src/pk/ed25519/ed25519_verify.obj \ +src/pk/pka_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 \ @@ -226,13 +228,13 @@ src/stream/sosemanuk/sosemanuk_memory.obj src/stream/sosemanuk/sosemanuk_test.ob #List of test objects to compile TOBJECTS=tests/base16_test.obj tests/base32_test.obj tests/base64_test.obj tests/bcrypt_test.obj \ -tests/cipher_hash_test.obj tests/common.obj tests/der_test.obj tests/dh_test.obj tests/dsa_test.obj \ -tests/ecc_test.obj tests/ed25519_test.obj tests/file_test.obj tests/mac_test.obj tests/misc_test.obj \ -tests/modes_test.obj tests/mpi_test.obj tests/multi_test.obj tests/no_null_termination_check_test.obj \ -tests/no_prng.obj tests/padding_test.obj tests/pem_test.obj tests/pk_oid_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/ssh_test.obj tests/store_test.obj tests/test.obj \ -tests/x25519_test.obj +tests/cipher_hash_test.obj tests/common.obj tests/deprecated_test.obj tests/der_test.obj tests/dh_test.obj \ +tests/dsa_test.obj tests/ecc_test.obj tests/ed25519_test.obj tests/file_test.obj tests/mac_test.obj \ +tests/misc_test.obj tests/modes_test.obj tests/mpi_test.obj tests/multi_test.obj \ +tests/no_null_termination_check_test.obj tests/no_prng.obj tests/padding_test.obj tests/pem_test.obj \ +tests/pk_oid_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/ssh_test.obj tests/store_test.obj tests/test.obj tests/x25519_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 7db447417..d68a3850f 100644 --- a/makefile.unix +++ b/makefile.unix @@ -123,8 +123,8 @@ src/misc/crypt/crypt_register_all_ciphers.o src/misc/crypt/crypt_register_all_ha src/misc/crypt/crypt_register_all_prngs.o src/misc/crypt/crypt_register_cipher.o \ src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ -src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \ -src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \ +src/misc/crypt/crypt_unregister_prng.o src/misc/deprecated.o src/misc/error_to_string.o \ +src/misc/hkdf/hkdf.o 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/password_free.o src/misc/pbes/pbes.o src/misc/pbes/pbes1.o \ src/misc/pbes/pbes2.o src/misc/pem/pem.o src/misc/pem/pem_pkcs.o src/misc/pem/pem_read.o \ src/misc/pem/pem_ssh.o src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o \ @@ -190,9 +190,10 @@ src/pk/asn1/oid/pk_get.o src/pk/asn1/oid/pk_oid_cmp.o src/pk/asn1/oid/pk_oid_str src/pk/asn1/pkcs8/pkcs8_decode_flexi.o src/pk/asn1/pkcs8/pkcs8_get.o \ src/pk/asn1/x509/x509_decode_public_key_from_certificate.o src/pk/asn1/x509/x509_decode_spki.o \ src/pk/asn1/x509/x509_decode_subject_public_key_info.o \ -src/pk/asn1/x509/x509_encode_subject_public_key_info.o src/pk/dh/dh.o src/pk/dh/dh_check_pubkey.o \ -src/pk/dh/dh_export.o src/pk/dh/dh_export_key.o src/pk/dh/dh_free.o src/pk/dh/dh_generate_key.o \ -src/pk/dh/dh_import.o src/pk/dh/dh_import_pkcs8.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o \ +src/pk/asn1/x509/x509_encode_subject_public_key_info.o src/pk/asn1/x509/x509_get_pka.o \ +src/pk/asn1/x509/x509_import_spki.o src/pk/dh/dh.o src/pk/dh/dh_check_pubkey.o src/pk/dh/dh_export.o \ +src/pk/dh/dh_export_key.o src/pk/dh/dh_free.o src/pk/dh/dh_generate_key.o src/pk/dh/dh_import.o \ +src/pk/dh/dh_import_pkcs8.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o \ src/pk/dh/dh_shared_secret.o src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o \ src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_generate_key.o \ src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_import_pkcs8.o \ @@ -208,18 +209,19 @@ src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_k src/pk/ecc/ecc_recover_key.o src/pk/ecc/ecc_rfc6979_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_sign_hash_eth27.o src/pk/ecc/ecc_sign_hash_internal.o \ -src/pk/ecc/ecc_sign_hash_rfc5656.o src/pk/ecc/ecc_sign_hash_rfc7518.o src/pk/ecc/ecc_sizes.o \ -src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ecc_verify_hash_eth27.o \ -src/pk/ecc/ecc_verify_hash_internal.o src/pk/ecc/ecc_verify_hash_rfc5656.o \ -src/pk/ecc/ecc_verify_hash_rfc7518.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/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \ -src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_raw.o \ -src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_sign.o \ -src/pk/ed25519/ed25519_verify.o src/pk/pka_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/ecc/ecc_sign_hash_rfc5656.o src/pk/ecc/ecc_sign_hash_rfc7518.o src/pk/ecc/ecc_sign_hash_x962.o \ +src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ecc_verify_hash_eth27.o src/pk/ecc/ecc_verify_hash_internal.o \ +src/pk/ecc/ecc_verify_hash_rfc5656.o src/pk/ecc/ecc_verify_hash_rfc7518.o \ +src/pk/ecc/ecc_verify_hash_x962.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/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o src/pk/ed25519/ed25519_import_pkcs8.o \ +src/pk/ed25519/ed25519_import_raw.o src/pk/ed25519/ed25519_import_x509.o \ +src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_sign.o src/pk/ed25519/ed25519_verify.o \ +src/pk/pka_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 \ @@ -247,13 +249,13 @@ src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o #List of test objects to compile (all goes to libtomcrypt_prof.a) TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/bcrypt_test.o \ -tests/cipher_hash_test.o tests/common.o tests/der_test.o tests/dh_test.o tests/dsa_test.o \ -tests/ecc_test.o tests/ed25519_test.o tests/file_test.o tests/mac_test.o tests/misc_test.o \ -tests/modes_test.o tests/mpi_test.o tests/multi_test.o tests/no_null_termination_check_test.o \ -tests/no_prng.o tests/padding_test.o tests/pem_test.o tests/pk_oid_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/ssh_test.o tests/store_test.o tests/test.o \ -tests/x25519_test.o +tests/cipher_hash_test.o tests/common.o tests/deprecated_test.o tests/der_test.o tests/dh_test.o \ +tests/dsa_test.o tests/ecc_test.o tests/ed25519_test.o tests/file_test.o tests/mac_test.o \ +tests/misc_test.o tests/modes_test.o tests/mpi_test.o tests/multi_test.o \ +tests/no_null_termination_check_test.o tests/no_prng.o tests/padding_test.o tests/pem_test.o \ +tests/pk_oid_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/ssh_test.o tests/store_test.o tests/test.o tests/x25519_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 fcb6ed8a8..cc6f33e4e 100644 --- a/makefile_include.mk +++ b/makefile_include.mk @@ -294,8 +294,8 @@ src/misc/crypt/crypt_register_all_ciphers.o src/misc/crypt/crypt_register_all_ha src/misc/crypt/crypt_register_all_prngs.o src/misc/crypt/crypt_register_cipher.o \ src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ -src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \ -src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \ +src/misc/crypt/crypt_unregister_prng.o src/misc/deprecated.o src/misc/error_to_string.o \ +src/misc/hkdf/hkdf.o 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/password_free.o src/misc/pbes/pbes.o src/misc/pbes/pbes1.o \ src/misc/pbes/pbes2.o src/misc/pem/pem.o src/misc/pem/pem_pkcs.o src/misc/pem/pem_read.o \ src/misc/pem/pem_ssh.o src/misc/pkcs12/pkcs12_kdf.o src/misc/pkcs12/pkcs12_utf8_to_utf16.o \ @@ -361,9 +361,10 @@ src/pk/asn1/oid/pk_get.o src/pk/asn1/oid/pk_oid_cmp.o src/pk/asn1/oid/pk_oid_str src/pk/asn1/pkcs8/pkcs8_decode_flexi.o src/pk/asn1/pkcs8/pkcs8_get.o \ src/pk/asn1/x509/x509_decode_public_key_from_certificate.o src/pk/asn1/x509/x509_decode_spki.o \ src/pk/asn1/x509/x509_decode_subject_public_key_info.o \ -src/pk/asn1/x509/x509_encode_subject_public_key_info.o src/pk/dh/dh.o src/pk/dh/dh_check_pubkey.o \ -src/pk/dh/dh_export.o src/pk/dh/dh_export_key.o src/pk/dh/dh_free.o src/pk/dh/dh_generate_key.o \ -src/pk/dh/dh_import.o src/pk/dh/dh_import_pkcs8.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o \ +src/pk/asn1/x509/x509_encode_subject_public_key_info.o src/pk/asn1/x509/x509_get_pka.o \ +src/pk/asn1/x509/x509_import_spki.o src/pk/dh/dh.o src/pk/dh/dh_check_pubkey.o src/pk/dh/dh_export.o \ +src/pk/dh/dh_export_key.o src/pk/dh/dh_free.o src/pk/dh/dh_generate_key.o src/pk/dh/dh_import.o \ +src/pk/dh/dh_import_pkcs8.o src/pk/dh/dh_set.o src/pk/dh/dh_set_pg_dhparam.o \ src/pk/dh/dh_shared_secret.o src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o \ src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_generate_key.o \ src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_import_pkcs8.o \ @@ -379,18 +380,19 @@ src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_k src/pk/ecc/ecc_recover_key.o src/pk/ecc/ecc_rfc6979_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_sign_hash_eth27.o src/pk/ecc/ecc_sign_hash_internal.o \ -src/pk/ecc/ecc_sign_hash_rfc5656.o src/pk/ecc/ecc_sign_hash_rfc7518.o src/pk/ecc/ecc_sizes.o \ -src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ecc_verify_hash_eth27.o \ -src/pk/ecc/ecc_verify_hash_internal.o src/pk/ecc/ecc_verify_hash_rfc5656.o \ -src/pk/ecc/ecc_verify_hash_rfc7518.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/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \ -src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_raw.o \ -src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_sign.o \ -src/pk/ed25519/ed25519_verify.o src/pk/pka_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ +src/pk/ecc/ecc_sign_hash_rfc5656.o src/pk/ecc/ecc_sign_hash_rfc7518.o src/pk/ecc/ecc_sign_hash_x962.o \ +src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o \ +src/pk/ecc/ecc_verify_hash_eth27.o src/pk/ecc/ecc_verify_hash_internal.o \ +src/pk/ecc/ecc_verify_hash_rfc5656.o src/pk/ecc/ecc_verify_hash_rfc7518.o \ +src/pk/ecc/ecc_verify_hash_x962.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/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o src/pk/ed25519/ed25519_import_pkcs8.o \ +src/pk/ed25519/ed25519_import_raw.o src/pk/ed25519/ed25519_import_x509.o \ +src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_sign.o src/pk/ed25519/ed25519_verify.o \ +src/pk/pka_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 \ @@ -423,13 +425,13 @@ endif # List of test objects to compile (all goes to libtomcrypt_prof.a) TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/bcrypt_test.o \ -tests/cipher_hash_test.o tests/common.o tests/der_test.o tests/dh_test.o tests/dsa_test.o \ -tests/ecc_test.o tests/ed25519_test.o tests/file_test.o tests/mac_test.o tests/misc_test.o \ -tests/modes_test.o tests/mpi_test.o tests/multi_test.o tests/no_null_termination_check_test.o \ -tests/no_prng.o tests/padding_test.o tests/pem_test.o tests/pk_oid_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/ssh_test.o tests/store_test.o tests/test.o \ -tests/x25519_test.o +tests/cipher_hash_test.o tests/common.o tests/deprecated_test.o tests/der_test.o tests/dh_test.o \ +tests/dsa_test.o tests/ecc_test.o tests/ed25519_test.o tests/file_test.o tests/mac_test.o \ +tests/misc_test.o tests/modes_test.o tests/mpi_test.o tests/multi_test.o \ +tests/no_null_termination_check_test.o tests/no_prng.o tests/padding_test.o tests/pem_test.o \ +tests/pk_oid_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/ssh_test.o tests/store_test.o tests/test.o tests/x25519_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/sources.cmake b/sources.cmake index 45682cf68..85cc37fde 100644 --- a/sources.cmake +++ b/sources.cmake @@ -232,6 +232,7 @@ src/misc/crypt/crypt_sizes.c src/misc/crypt/crypt_unregister_cipher.c src/misc/crypt/crypt_unregister_hash.c src/misc/crypt/crypt_unregister_prng.c +src/misc/deprecated.c src/misc/error_to_string.c src/misc/hkdf/hkdf.c src/misc/hkdf/hkdf_test.c @@ -372,6 +373,8 @@ src/pk/asn1/x509/x509_decode_public_key_from_certificate.c src/pk/asn1/x509/x509_decode_spki.c src/pk/asn1/x509/x509_decode_subject_public_key_info.c src/pk/asn1/x509/x509_encode_subject_public_key_info.c +src/pk/asn1/x509/x509_get_pka.c +src/pk/asn1/x509/x509_import_spki.c src/pk/dh/dh.c src/pk/dh/dh_check_pubkey.c src/pk/dh/dh_export.c @@ -431,6 +434,7 @@ src/pk/ecc/ecc_sign_hash_eth27.c src/pk/ecc/ecc_sign_hash_internal.c src/pk/ecc/ecc_sign_hash_rfc5656.c src/pk/ecc/ecc_sign_hash_rfc7518.c +src/pk/ecc/ecc_sign_hash_x962.c src/pk/ecc/ecc_sizes.c src/pk/ecc/ecc_ssh_ecdsa_encode_name.c src/pk/ecc/ecc_verify_hash.c @@ -438,6 +442,7 @@ src/pk/ecc/ecc_verify_hash_eth27.c src/pk/ecc/ecc_verify_hash_internal.c src/pk/ecc/ecc_verify_hash_rfc5656.c src/pk/ecc/ecc_verify_hash_rfc7518.c +src/pk/ecc/ecc_verify_hash_x962.c src/pk/ecc/ltc_ecc_export_point.c src/pk/ecc/ltc_ecc_import_point.c src/pk/ecc/ltc_ecc_is_point.c diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 685a57bfb..4785d1496 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -604,6 +604,10 @@ /* Maximum recursion limit when processing nested ASN.1 types. */ #define LTC_DER_MAX_RECURSION 30 #endif + #ifndef LTC_DER_OID_DEFAULT_NODES + /* Default number of nodes when decoding an OID. */ + #define LTC_DER_OID_DEFAULT_NODES 12 + #endif #endif #if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_SSH) diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index 72e4f992c..4b31cf458 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -40,6 +40,7 @@ enum ltc_pka_id { LTC_PKA_X25519, LTC_PKA_ED25519, LTC_PKA_DH, + LTC_PKA_RSA_PSS, LTC_PKA_NUM }; @@ -62,7 +63,21 @@ int rand_prime(void *N, long len, prng_state *prng, int wprng); /* ---- RSA ---- */ #ifdef LTC_MRSA -/** RSA PKCS style key */ +typedef struct ltc_rsa_parameters { + /** PSS/OAEP or PKCS #1 v1.5 style + * 0 -> PKCS #1 v1.5, 1 -> PSS/OAEP */ + int pss_oaep; + /** saltLength is only defined for PSS + * If saltLength == 0 -> OAEP, else -> PSS */ + unsigned long saltlen; + /** lparam hash for OAEP + * resp. + * signature hash for PSS + * and MGF hash algorithms */ + const char *hash_alg, *mgf1_hash_alg; +} ltc_rsa_parameters; + +/** RSA key */ typedef struct Rsa_key { /** Type of key, PK_PRIVATE or PK_PUBLIC */ int type; @@ -82,6 +97,8 @@ typedef struct Rsa_key { void *dP; /** The d mod (q - 1) CRT param */ void *dQ; + /** Further parameters of the RSA key */ + ltc_rsa_parameters params; } rsa_key; int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); @@ -95,50 +112,148 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, void rsa_free(rsa_key *key); +typedef struct ltc_rsa_op_parameters { + /* pss_oaep flag is unused */ + ltc_rsa_parameters params; + /* The padding type */ + int padding; + /* The PRNG to use. + * Only required for signing and encryption. */ + int wprng; + prng_state *prng; + /* Operation-specific parameters */ + union { + struct { + const unsigned char *lparam; + unsigned long lparamlen; + } crypt; + /* let's make space for potential future extensions */ + ulong64 dummy[8]; + } u; +} ltc_rsa_op_parameters; + +int rsa_encrypt_key_v2(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_rsa_op_parameters *opts, + const rsa_key *key); + +int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_rsa_op_parameters *opts, + int *stat, + const rsa_key *key); + +int rsa_sign_hash_v2(const unsigned char *hash, unsigned long hashlen, + unsigned char *sig, unsigned long *siglen, + ltc_rsa_op_parameters *opts, + const rsa_key *key); + +int rsa_verify_hash_v2(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + ltc_rsa_op_parameters *opts, + int *stat, + const rsa_key *key); + +/* These use PKCS #1 v2.0 padding */ +#define ltc_rsa_encrypt_key(in, inlen, out, outlen, lp, lplen, prng_, prng_idx, hash_idx, key) \ + rsa_encrypt_key_v2(in, inlen, out, outlen, \ + &(ltc_rsa_op_parameters){ \ + .u.crypt.lparam = lp, \ + .u.crypt.lparamlen = lplen,\ + .prng = prng_, \ + .wprng = prng_idx, \ + .params.mgf1_hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \ + .params.hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \ + .padding = LTC_PKCS_1_OAEP, \ + }, key) + +#define ltc_rsa_decrypt_key(in, inlen, out, outlen, lp, lplen, hash_idx, stat, key) \ + rsa_decrypt_key_v2(in, inlen, out, outlen, \ + &(ltc_rsa_op_parameters){ \ + .u.crypt.lparam = lp, \ + .u.crypt.lparamlen = lplen,\ + .params.mgf1_hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \ + .params.hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \ + .padding = LTC_PKCS_1_OAEP, \ + }, stat, key) + +#define ltc_rsa_sign_hash(hash, hashlen, sig, siglen, prng_, prng_idx, hash_idx, saltlen_, key) \ + rsa_sign_hash_v2(hash, hashlen, sig, siglen, \ + &(ltc_rsa_op_parameters){ \ + .prng = prng_, \ + .wprng = prng_idx, \ + .params.mgf1_hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \ + .params.hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \ + .params.saltlen = saltlen_, \ + .padding = LTC_PKCS_1_PSS, \ + }, key) + +#define ltc_rsa_verify_hash(sig, siglen, hash, hashlen, hash_idx, saltlen_, stat, key) \ + rsa_verify_hash_v2(sig, siglen, hash, hashlen, \ + &(ltc_rsa_op_parameters){ \ + .params.mgf1_hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \ + .params.hash_alg = hash_is_valid(hash_idx) == CRYPT_OK ? hash_descriptor[hash_idx].name : NULL, \ + .params.saltlen = saltlen_, \ + .padding = LTC_PKCS_1_PSS, \ + }, stat, key) + +//#define LTC_NO_DEPRECATED_APIS +#ifdef LTC_NO_DEPRECATED_APIS + +#define rsa_encrypt_key ltc_rsa_encrypt_key +#define rsa_decrypt_key ltc_rsa_decrypt_key +#define rsa_sign_hash ltc_rsa_sign_hash +#define rsa_verify_hash ltc_rsa_verify_hash + +#else /* LTC_NO_DEPRECATED_APIS */ + /* These use PKCS #1 v2.0 padding */ #define rsa_encrypt_key(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, key) \ - rsa_encrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, -1, LTC_PKCS_1_OAEP, key) + rsa_encrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, LTC_PKCS_1_OAEP, key) #define rsa_decrypt_key(in, inlen, out, outlen, lparam, lparamlen, hash_idx, stat, key) \ - rsa_decrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, hash_idx, -1, LTC_PKCS_1_OAEP, stat, key) + rsa_decrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, hash_idx, LTC_PKCS_1_OAEP, stat, key) -#define rsa_sign_hash(in, inlen, out, outlen, prng, prng_idx, hash_idx, saltlen, key) \ - rsa_sign_hash_ex(in, inlen, out, outlen, LTC_PKCS_1_PSS, prng, prng_idx, hash_idx, saltlen, key) +#define rsa_sign_hash(hash, hashlen, sig, siglen, prng, prng_idx, hash_idx, saltlen, key) \ + rsa_sign_hash_ex(hash, hashlen, sig, siglen, LTC_PKCS_1_PSS, prng, prng_idx, hash_idx, saltlen, key) #define rsa_verify_hash(sig, siglen, hash, hashlen, hash_idx, saltlen, stat, key) \ rsa_verify_hash_ex(sig, siglen, hash, hashlen, LTC_PKCS_1_PSS, hash_idx, saltlen, stat, key) -#define rsa_sign_saltlen_get_max(hash_idx, key) \ - rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, hash_idx, key) - /* These can be switched between PKCS #1 v2.x and PKCS #1 v1.5 paddings */ +LTC_DEPRECATED(rsa_encrypt_key_v2) int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, - int mgf_hash, int lparam_hash, - int padding, + int hash_idx, int padding, const rsa_key *key); +LTC_DEPRECATED(rsa_decrypt_key_v2) int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, - int mgf_hash, int lparam_hash, - int padding, + int hash_idx, int padding, int *stat, const rsa_key *key); +LTC_DEPRECATED(rsa_sign_hash_v2) int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int padding, - prng_state *prng, int prng_idx, + prng_state *prng, int prng_idx, int hash_idx, unsigned long saltlen, const rsa_key *key); +LTC_DEPRECATED(rsa_verify_hash_v2) int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int padding, int hash_idx, unsigned long saltlen, int *stat, const rsa_key *key); +#endif /* LTC_NO_DEPRECATED_APIS */ + +#define rsa_sign_saltlen_get_max(hash_idx, key) \ + rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, hash_idx, key) int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, const rsa_key *key); @@ -281,20 +396,10 @@ typedef struct { /** The private key */ void *k; - - /** The hash algorithm to use when creating a signature. - * Setting this will enable RFC6979 compatible signature generation. - * The macro ECC_SET_RFC6979_HASH_ALG() is provided as a helper - * to set this.*/ - const char *rfc6979_hash_alg; } ecc_key; -#define ECC_SET_RFC6979_HASH_ALG(key, alg) do { \ - (key)->rfc6979_hash_alg = (alg); \ -} while(0) - /** Formats of ECC signatures */ -typedef enum ecc_signature_type_ { +typedef enum ecc_signature_type { /* ASN.1 encoded, ANSI X9.62 */ LTC_ECCSIG_ANSIX962 = 0x0, /* raw R, S values */ @@ -305,6 +410,28 @@ typedef enum ecc_signature_type_ { LTC_ECCSIG_RFC5656 = 0x3, } ecc_signature_type; +typedef struct ltc_ecc_sig_opts { + /** Signature type */ + ecc_signature_type type; + /** The PRNG to use. + * This must be set in case deterministic signature generation + * according to RFC6979 is not enabled. + */ + prng_state *prng; + int wprng; + + /** Enable generation of a recovery ID. + * This must be set in case one requires the recovery ID of a + * signature operation. + */ + int *recid; + + /** The hash algorithm to use when creating a signature. + * Setting this will enable RFC6979 compatible signature generation. + */ + const char *rfc6979_hash_alg; +} ltc_ecc_sig_opts; + /** the ECC params provided */ extern const ltc_ecc_curve ltc_ecc_curves[]; @@ -340,6 +467,21 @@ int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_k int ecc_shared_secret(const ecc_key *private_key, const ecc_key *public_key, unsigned char *out, unsigned long *outlen); +int ecc_sign_hash_v2(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + ltc_ecc_sig_opts *opts, + const ecc_key *key); + +int ecc_verify_hash_v2(const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + ltc_ecc_sig_opts *opts, + int *stat, + const ecc_key *key); + #if defined(LTC_DER) int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, @@ -349,7 +491,42 @@ int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const ecc_key *key); - +#endif /* LTC_DER */ + +#define ltc_ecc_sign_hash(i, il, o, ol, p, wp, k) \ + ecc_sign_hash_v2(i, il, o, ol, \ + &(ltc_ecc_sig_opts){ \ + .type = LTC_ECCSIG_ANSIX962, \ + .prng = p, \ + .wprng = wp, \ + }, k) +#define ltc_ecc_sign_hash_rfc7518(i, il, o, ol, p, wp, k) \ + ecc_sign_hash_v2(i, il, o, ol, \ + &(ltc_ecc_sig_opts){ \ + .type = LTC_ECCSIG_RFC7518, \ + .prng = p, \ + .wprng = wp, \ + }, k) + +#define ltc_ecc_verify_hash(s, sl, h, hl, st, k) \ + ecc_verify_hash_v2(s, sl, h, hl, \ + &(ltc_ecc_sig_opts){ \ + .type = LTC_ECCSIG_ANSIX962, \ + }, st, k) +#define ltc_ecc_verify_hash_rfc7518(s, sl, h, hl, st, k) \ + ecc_verify_hash_v2(s, sl, h, hl, \ + &(ltc_ecc_sig_opts){ \ + .type = LTC_ECCSIG_RFC7518, \ + }, st, k) + +#ifdef LTC_NO_DEPRECATED_APIS +#define ecc_sign_hash ltc_ecc_sign_hash +#define ecc_verify_hash ltc_ecc_verify_hash +#define ecc_sign_hash_rfc7518 ltc_ecc_sign_hash_rfc7518 +#define ecc_verify_hash_rfc7518 ltc_ecc_verify_hash_rfc7518 +#else /* LTC_NO_DEPRECATED_APIS */ +#if defined(LTC_DER) +LTC_DEPRECATED(ecc_sign_hash_v2) int ecc_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, @@ -358,14 +535,16 @@ int ecc_sign_hash(const unsigned char *in, int wprng, const ecc_key *key); +LTC_DEPRECATED(ecc_verify_hash_v2) int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, const ecc_key *key); -#endif +#endif /* LTC_DER */ +LTC_DEPRECATED(ecc_sign_hash_v2) int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, unsigned char *out, @@ -374,60 +553,20 @@ int ecc_sign_hash_rfc7518(const unsigned char *in, int wprng, const ecc_key *key); -int ecc_sign_hash_rfc7518_ex(const unsigned char *in, - unsigned long inlen, - unsigned char *out, - unsigned long *outlen, - prng_state *prng, - int wprng, - int *recid, - const ecc_key *key); - +LTC_DEPRECATED(ecc_verify_hash_v2) int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, const ecc_key *key); - -#if defined(LTC_SSH) -int ecc_sign_hash_rfc5656(const unsigned char *in, - unsigned long inlen, - unsigned char *out, - unsigned long *outlen, - prng_state *prng, - int wprng, - const ecc_key *key); - -int ecc_verify_hash_rfc5656(const unsigned char *sig, - unsigned long siglen, - const unsigned char *hash, - unsigned long hashlen, - int *stat, - const ecc_key *key); -#endif - -int ecc_sign_hash_eth27(const unsigned char *in, - unsigned long inlen, - unsigned char *out, - unsigned long *outlen, - prng_state *prng, - int wprng, - const ecc_key *key); - -int ecc_verify_hash_eth27(const unsigned char *sig, - unsigned long siglen, - const unsigned char *hash, - unsigned long hashlen, - int *stat, - const ecc_key *key); +#endif /* LTC_NO_DEPRECATED_APIS */ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, - int recid, - ecc_signature_type sigformat, + ltc_ecc_sig_opts *opts, ecc_key *key); #endif diff --git a/src/headers/tomcrypt_pkcs.h b/src/headers/tomcrypt_pkcs.h index cca013c07..5d1d4cf42 100644 --- a/src/headers/tomcrypt_pkcs.h +++ b/src/headers/tomcrypt_pkcs.h @@ -20,14 +20,18 @@ enum ltc_pkcs_1_paddings LTC_PKCS_1_V1_5_NA1 = 4 /* PKCS #1 v1.5 padding - No ASN.1 (\sa ltc_pkcs_1_v1_5_blocks) */ }; +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_mgf1( int hash_idx, const unsigned char *seed, unsigned long seedlen, unsigned char *mask, unsigned long masklen); +LTC_DEPRECATED(nothing. API will be removed) int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); +LTC_DEPRECATED(nothing. API will be removed) int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen); /* *** v1.5 padding */ +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_v1_5_encode(const unsigned char *msg, unsigned long msglen, int block_type, @@ -37,6 +41,7 @@ int pkcs_1_v1_5_encode(const unsigned char *msg, unsigned char *out, unsigned long *outlen); +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_v1_5_decode(const unsigned char *msg, unsigned long msglen, int block_type, @@ -46,26 +51,28 @@ int pkcs_1_v1_5_decode(const unsigned char *msg, int *is_valid); /* *** v2.1 padding */ +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, unsigned long modulus_bitlen, prng_state *prng, - int prng_idx, - int mgf_hash, int lparam_hash, + int prng_idx, int hash_idx, unsigned char *out, unsigned long *outlen); +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, - unsigned long modulus_bitlen, - int mgf_hash, int lparam_hash, + unsigned long modulus_bitlen, int hash_idx, unsigned char *out, unsigned long *outlen, int *res); +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, unsigned long saltlen, prng_state *prng, int prng_idx, int hash_idx, unsigned long modulus_bitlen, unsigned char *out, unsigned long *outlen); +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, const unsigned char *sig, unsigned long siglen, unsigned long saltlen, int hash_idx, diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index c0edbb912..dbb0f44bd 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -60,6 +60,9 @@ enum ltc_oid_id { LTC_OID_X25519, LTC_OID_ED25519, LTC_OID_DH, + LTC_OID_RSA_OAEP, + LTC_OID_RSA_MGF1, + LTC_OID_RSA_PSS, LTC_OID_NUM }; @@ -352,19 +355,40 @@ struct bufp { }; #define SET_BUFP(n, d, l) n.start = (char*)d, n.work = (char*)d, n.end = (char*)d + l + 1 +#define UPDATE_BUFP(n, d, w, l) n.start = (char*)d, n.work = (char*)d + w, n.end = (char*)d + l + 1 -struct get_char { +struct get_char; +struct get_char_api { int (*get)(struct get_char*); +}; + +struct get_char { + struct get_char_api api; union { #ifndef LTC_NO_FILE - FILE *f; + struct { + FILE *f; + } f; #endif /* LTC_NO_FILE */ struct bufp buf; } data; struct str unget_buf; char unget_buf_[LTC_PEM_DECODE_BUFSZ]; int prev_get; + unsigned long total_read; }; + +#define pem_get_char_init(b, l) { \ + .api = get_char_buffer_api, \ + SET_BUFP(.data.buf, (b), (l)), \ + .total_read = 0, \ +} + +#define pem_get_char_init_filehandle(fi) { \ + .api = get_char_filehandle_api, \ + .data.f.f = (fi), \ + .total_read = 0, \ +} #endif /* others */ @@ -387,10 +411,10 @@ int pem_decrypt(unsigned char *data, unsigned long *datalen, const struct blockcipher_info *info, enum padding_type padding); #ifndef LTC_NO_FILE -int pem_get_char_from_file(struct get_char *g); +extern const struct get_char_api get_char_filehandle_api; #endif /* LTC_NO_FILE */ -int pem_get_char_from_buf(struct get_char *g); -int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, struct get_char *g); +extern const struct get_char_api get_char_buffer_api; +int pem_read(void **dest, unsigned long *len, struct pem_headers *hdr, struct get_char *g); #endif /* tomcrypt_pk.h */ @@ -411,12 +435,58 @@ int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long /* ---- DH Routines ---- */ #ifdef LTC_MRSA +/* Receiving side, i.e. Decrypt or Verify */ +#define LTC_RSA_OP_RECV 0x00u +/* Sending side, i.e. Encrypt or Sign */ +#define LTC_RSA_OP_SEND 0x01u +/* En- or Decrypt */ +#define LTC_RSA_OP_CRYPT 0x00u +/* Sign or Verify */ +#define LTC_RSA_OP_SIGN 0x02u +/* All combinations of the above + * but only the PKCS#1 de-/encoding part */ +#define LTC_RSA_OP_PKCS1 0x04u + +typedef enum ltc_rsa_op { + LTC_RSA_DECRYPT = LTC_RSA_OP_CRYPT | LTC_RSA_OP_RECV, + LTC_RSA_ENCRYPT = LTC_RSA_OP_CRYPT | LTC_RSA_OP_SEND, + LTC_RSA_VERIFY = LTC_RSA_OP_SIGN | LTC_RSA_OP_RECV, + LTC_RSA_SIGN = LTC_RSA_OP_SIGN | LTC_RSA_OP_SEND, + LTC_PKCS1_ENCRYPT = LTC_RSA_OP_PKCS1 | LTC_RSA_ENCRYPT, + LTC_PKCS1_DECRYPT = LTC_RSA_OP_PKCS1 | LTC_RSA_DECRYPT, + LTC_PKCS1_SIGN = LTC_RSA_OP_PKCS1 | LTC_RSA_SIGN, + LTC_PKCS1_VERIFY = LTC_RSA_OP_PKCS1 | LTC_RSA_VERIFY, +} ltc_rsa_op; + +typedef struct ltc_rsa_op_check { + const rsa_key *key; + ltc_rsa_op_parameters *params; + int hash_alg, mgf1_hash_alg; +} ltc_rsa_op_checked; + +#define ltc_rsa_op_checked_init(k, p) { \ + .key = k, \ + .params = p, \ + .hash_alg = -1, \ + .mgf1_hash_alg = -1, \ +} + +#define ltc_pkcs1_op_checked_init(p) ltc_rsa_op_checked_init(NULL, p) + int rsa_init(rsa_key *key); void rsa_shrink_key(rsa_key *key); +int rsa_args_to_op_params(const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, + int padding, unsigned long saltlen, + ltc_rsa_op_parameters *params); +int rsa_key_valid_op(ltc_rsa_op op, ltc_rsa_op_checked *params); +int rsa_params_equal(const ltc_rsa_parameters *a, const ltc_rsa_parameters *b); int rsa_make_key_bn_e(prng_state *prng, int wprng, int size, void *e, rsa_key *key); /* used by op-tee */ int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key); int rsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, rsa_key *key); +int rsa_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key); +int rsa_decode_parameters(const ltc_asn1_list *parameters, ltc_rsa_parameters *rsa_params); #endif /* LTC_MRSA */ /* ---- DH Routines ---- */ @@ -441,15 +511,66 @@ int ecc_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, ecc_ke int ecc_import_with_curve(const unsigned char *in, unsigned long inlen, int type, ecc_key *key); int ecc_import_with_oid(const unsigned char *in, unsigned long inlen, unsigned long *oid, unsigned long oid_len, int type, ecc_key *key); +int ecc_sign_hash_rfc7518_internal(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + ltc_ecc_sig_opts *opts, + const ecc_key *key); + +int ecc_verify_hash_rfc7518_internal(const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + int *stat, + const ecc_key *key); + +#ifdef LTC_DER +int ecc_verify_hash_x962(const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + int *stat, + const ecc_key *key); +int ecc_sign_hash_x962(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + ltc_ecc_sig_opts *opts, + const ecc_key *key); +#endif + +#if defined(LTC_SSH) +int ecc_sign_hash_rfc5656(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + ltc_ecc_sig_opts *opts, + const ecc_key *key); + +int ecc_verify_hash_rfc5656(const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + int *stat, + const ecc_key *key); +#endif + +int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_ecc_sig_opts *opts, const ecc_key *key); + +int ecc_verify_hash_eth27(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, const ecc_key *key); int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, - void *r, void *s, prng_state *prng, int wprng, - int *recid, const ecc_key *key); + void *r, void *s, ltc_ecc_sig_opts *opts, const ecc_key *key); int ecc_verify_hash_internal(void *r, void *s, const unsigned char *hash, unsigned long hashlen, int *stat, const ecc_key *key); -int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, ecc_key *key); +int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, const char *rfc6979_hash_alg, ecc_key *key); #ifdef LTC_SSH int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key); @@ -525,8 +646,8 @@ int dsa_int_validate(const dsa_key *key, int *stat); int dsa_int_validate_xy(const dsa_key *key, int *stat); int dsa_int_validate_pqg(const dsa_key *key, int *stat); int dsa_int_validate_primes(const dsa_key *key, int *stat); -int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key); int dsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dsa_key *key); +int dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key); #endif /* LTC_MDSA */ @@ -600,17 +721,29 @@ int der_printable_value_decode(int v); unsigned long der_utf8_charsize(const wchar_t c); -typedef struct { +typedef int (*der_flexi_handler)(const ltc_asn1_list*, void*); + +typedef struct der_flexi_check { ltc_asn1_type t; + int optional; ltc_asn1_list **pp; + der_flexi_handler handler; + void *userdata; } der_flexi_check; -#define LTC_SET_DER_FLEXI_CHECK(list, index, Type, P) \ - do { \ - int LTC_SDFC_temp##__LINE__ = (index); \ - list[LTC_SDFC_temp##__LINE__].t = Type; \ - list[LTC_SDFC_temp##__LINE__].pp = P; \ +#define LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, P, Opt, Hndl, Udata) \ + do { \ + int LTC_SDFC_temp##__LINE__ = (index); \ + list[LTC_SDFC_temp##__LINE__].t = Type; \ + list[LTC_SDFC_temp##__LINE__].pp = P; \ + list[LTC_SDFC_temp##__LINE__].optional = Opt; \ + list[LTC_SDFC_temp##__LINE__].handler = (der_flexi_handler)Hndl; \ + list[LTC_SDFC_temp##__LINE__].userdata = Udata; \ } while (0) +#define LTC_SET_DER_FLEXI_CHECK(list, index, Type, P) LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, P, 0, NULL, NULL) +#define LTC_SET_DER_FLEXI_CHECK_OPT(list, index, Type, P) LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, P, 1, NULL, NULL) +#define LTC_SET_DER_FLEXI_HANDLER(list, index, Type, Hndl, Udata) LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, NULL, 0, Hndl, Udata) +#define LTC_SET_DER_FLEXI_HANDLER_OPT(list, index, Type, Hndl, Udata) LTC_PRIV_SET_DER_FLEXI_CHECK(list, index, Type, NULL, 1, Hndl, Udata) extern const ltc_asn1_type der_asn1_tag_to_type_map[]; @@ -629,13 +762,17 @@ int der_teletex_value_decode(int v); int der_utf8_valid_char(const wchar_t c); -typedef int (*public_key_decode_cb)(const unsigned char *in, unsigned long inlen, void *ctx); +typedef int (*public_key_decode_cb)(const unsigned char *in, unsigned long inlen, void *key); int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen, enum ltc_oid_id algorithm, ltc_asn1_type param_type, ltc_asn1_list* parameters, unsigned long *parameters_len, - public_key_decode_cb callback, void *ctx); -int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, ltc_asn1_list **spki); + public_key_decode_cb callback, void *key); +int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, const ltc_asn1_list **spki); +int x509_process_public_key_from_spki(const unsigned char *in, unsigned long inlen, + enum ltc_oid_id algorithm, ltc_asn1_type param_type, + ltc_asn1_list* parameters, unsigned long *parameters_len, + public_key_decode_cb callback, void *key); /* SUBJECT PUBLIC KEY INFO */ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, @@ -646,12 +783,37 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i enum ltc_oid_id algorithm, void *public_key, unsigned long *public_key_len, ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); +int x509_get_pka(const ltc_asn1_list *pub, enum ltc_pka_id *pka); +int x509_import_spki(const unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, ltc_asn1_list **root); + int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2); #endif /* LTC_DER */ /* tomcrypt_pkcs.h */ +#ifdef LTC_PKCS_1 + +int ltc_pkcs_1_pss_encode_mgf1(const unsigned char *msghash, unsigned long msghashlen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen); +int ltc_pkcs_1_pss_decode_mgf1(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, int *res); +int ltc_pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + unsigned long modulus_bitlen, + ltc_rsa_op_parameters *params, + unsigned char *out, unsigned long *outlen); +int ltc_pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + unsigned long modulus_bitlen, + ltc_rsa_op_parameters *params, + unsigned char *out, unsigned long *outlen, + int *res); + +#endif /* LTC_PKCS_1 */ + #ifdef LTC_PKCS_8 /* Public-Key Cryptography Standards (PKCS) #8: diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index 61b5cd050..62d2e2c82 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -455,6 +455,7 @@ const char *crypt_build_settings = #if defined(LTC_DER) " DER " " " NAME_VALUE(LTC_DER_MAX_RECURSION) " " + " " NAME_VALUE(LTC_DER_OID_DEFAULT_NODES) " " #endif #if defined(LTC_PKCS_1) " PKCS#1 " @@ -580,6 +581,9 @@ const char *crypt_build_settings = #endif #if defined(LTC_CLOCK_GETTIME) " LTC_CLOCK_GETTIME " +#endif +#if defined(LTC_NO_DEPRECATED_APIS) + " LTC_NO_DEPRECATED_APIS " #endif "\n" ; diff --git a/src/misc/deprecated.c b/src/misc/deprecated.c new file mode 100644 index 000000000..e7b116a12 --- /dev/null +++ b/src/misc/deprecated.c @@ -0,0 +1,341 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include "tomcrypt_private.h" + +#ifndef LTC_NO_DEPRECATED_APIS + +#ifdef LTC_MECC +/** + Sign a message digest (ANSI X9.62 format) + @param in The message digest to sign + @param inlen The length of the digest + @param out [out] The destination for the signature + @param outlen [in/out] The max size and resulting size of the signature + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param key A private ECC key + @return CRYPT_OK if successful +*/ +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, const ecc_key *key) +{ + return ltc_ecc_sign_hash(in, inlen, out, outlen, prng, wprng, key); +} + +/** + Verify an ECC signature (ANSI X9.62 format) + @param sig The signature to verify + @param siglen The length of the signature (octets) + @param hash The hash (message digest) that was signed + @param hashlen The length of the hash (octets) + @param stat [out] Result of signature, 1==valid, 0==invalid + @param key The corresponding public ECC key + @return CRYPT_OK if successful (even if the signature is not valid) +*/ +int ecc_verify_hash(const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + int *stat, + const ecc_key *key) +{ + return ltc_ecc_verify_hash(sig, siglen, hash, hashlen, stat, key); +} + +/** + Sign a message digest (RFC7518 format) + @param in The message digest to sign + @param inlen The length of the digest + @param out [out] The destination for the signature + @param outlen [in/out] The max size and resulting size of the signature + @param opts The signature options that shall be applied + @param key A private ECC key + @return CRYPT_OK if successful +*/ +int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, const ecc_key *key) +{ + return ltc_ecc_sign_hash_rfc7518(in, inlen, out, outlen, prng, wprng, key); +} + +/** + Verify an ECC signature (RFC7518 format) + @param sig The signature to verify + @param siglen The length of the signature (octets) + @param hash The hash (message digest) that was signed + @param hashlen The length of the hash (octets) + @param stat [out] Result of signature, 1==valid, 0==invalid + @param key The corresponding public ECC key + @return CRYPT_OK if successful (even if the signature is not valid) +*/ +int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, const ecc_key *key) +{ + return ltc_ecc_verify_hash_rfc7518(sig, siglen, hash, hashlen, stat, key); +} +#endif /* LTC_MECC */ + +#ifdef LTC_MRSA +/** + (PKCS #1 v2.0) OAEP pad then encrypt + @param in The plaintext + @param inlen The length of the plaintext (octets) + @param out [out] The ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param lparam The system "lparam" for the encryption + @param lparamlen The length of lparam (octets) + @param prng An active PRNG + @param prng_idx The index of the desired prng + @param hash_idx The index of the desired hash + @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) + @param key The RSA key to encrypt to + @return CRYPT_OK if successful +*/ +int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, + int hash_idx, int padding, + const rsa_key *key) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(lparam, lparamlen, + prng, prng_idx, + hash_idx, + padding, 0, + ¶ms)) != CRYPT_OK) { + return err; + } + return rsa_encrypt_key_v2(in, inlen, out, outlen, ¶ms, key); +} + +/** + PKCS #1 decrypt then v1.5 or OAEP depad + @param in The ciphertext + @param inlen The length of the ciphertext (octets) + @param out [out] The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext (octets) + @param lparam The system "lparam" value + @param lparamlen The length of the lparam value (octets) + @param hash_idx The hash algorithm used + @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) + @param stat [out] Result of the decryption, 1==valid, 0==invalid + @param key The corresponding private RSA key + @return CRYPT_OK if succcessul (even if invalid) +*/ +int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int padding, + int *stat, const rsa_key *key) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(lparam, lparamlen, + NULL, -1, + hash_idx, + padding, 0, + ¶ms)) != CRYPT_OK) { + return err; + } + return rsa_decrypt_key_v2(in, inlen, out, outlen, ¶ms, stat, key); +} + +/** + PKCS #1 pad then sign + @param in The hash to sign + @param inlen The length of the hash to sign (octets) + @param out [out] The signature + @param outlen [in/out] The max size and resulting size of the signature + @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) + @param prng An active PRNG state + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param saltlen The length of the salt desired (octets) + @param key The private RSA key to use + @return CRYPT_OK if successful +*/ +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + prng_state *prng, int prng_idx, + int hash_idx, unsigned long saltlen, + const rsa_key *key) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(NULL, 0, + prng, prng_idx, + hash_idx, + padding, saltlen, + ¶ms)) != CRYPT_OK) { + return err; + } + return rsa_sign_hash_v2(in, inlen, out, outlen, ¶ms, key); +} + +/** + PKCS #1 de-sign then v1.5 or PSS depad + @param sig The signature data + @param siglen The length of the signature data (octets) + @param hash The hash of the message that was signed + @param hashlen The length of the hash of the message that was signed (octets) + @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) + @param hash_idx The index of the desired hash + @param saltlen The length of the salt used during signature + @param stat [out] The result of the signature comparison, 1==valid, 0==invalid + @param key The public RSA key corresponding to the key that performed the signature + @return CRYPT_OK on success (even if the signature is invalid) +*/ +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + int hash_idx, unsigned long saltlen, + int *stat, const rsa_key *key) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(NULL, 0, + NULL, -1, + hash_idx, + padding, saltlen, + ¶ms)) != CRYPT_OK) { + return err; + } + return rsa_verify_hash_v2(sig, siglen, hash, hashlen, ¶ms, stat, key); +} +#endif /* LTC_MRSA */ + + +#ifdef LTC_PKCS_1 +/** + PKCS #1 v2.00 OAEP encode + @param msg The data to encode + @param msglen The length of the data to encode (octets) + @param lparam A session or system parameter (can be NULL) + @param lparamlen The length of the lparam data + @param modulus_bitlen The bit length of the RSA modulus + @param prng An active PRNG state + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param out [out] The destination for the encoded data + @param outlen [in/out] The max size and resulting size of the encoded data + @return CRYPT_OK if successful +*/ +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(lparam, lparamlen, + prng, prng_idx, + hash_idx, + LTC_PKCS_1_OAEP, 0, + ¶ms)) != CRYPT_OK) { + return err; + } + return ltc_pkcs_1_oaep_encode(msg, msglen, modulus_bitlen, ¶ms, out, outlen); +} + +/** + PKCS #1 v2.00 OAEP decode + @param msg The encoded data to decode + @param msglen The length of the encoded data (octets) + @param lparam The session or system data (can be NULL) + @param lparamlen The length of the lparam + @param modulus_bitlen The bit length of the RSA modulus + @param mgf_hash The hash algorithm used for the MGF + @param lparam_hash The hash algorithm used when hashing the lparam (can be -1) + @param out [out] Destination of decoding + @param outlen [in/out] The max size and resulting size of the decoding + @param res [out] Result of decoding, 1==valid, 0==invalid + @return CRYPT_OK if successful +*/ +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen, + int *res) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(lparam, lparamlen, + NULL, -1, + hash_idx, + LTC_PKCS_1_OAEP, 0, + ¶ms)) != CRYPT_OK) { + return err; + } + return ltc_pkcs_1_oaep_decode(msg, msglen, modulus_bitlen, ¶ms, out, outlen, res); +} + +/** + PKCS #1 v2.00 Signature Encoding using MGF1 and both hashes are the same + @param msghash The hash to encode + @param msghashlen The length of the hash (octets) + @param saltlen The length of the salt desired (octets) + @param prng An active PRNG context + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param out [out] The destination of the encoding + @param outlen [in/out] The max size and resulting size of the encoded data + @return CRYPT_OK if successful +*/ +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(NULL, 0, + prng, prng_idx, + hash_idx, + LTC_PKCS_1_PSS, saltlen, + ¶ms)) != CRYPT_OK) { + return err; + } + return ltc_pkcs_1_pss_encode_mgf1(msghash, msghashlen, ¶ms, modulus_bitlen, out, outlen); +} + +/** + PKCS #1 v2.00 PSS decode + @param msghash The hash to verify + @param msghashlen The length of the hash (octets) + @param sig The signature data (encoded data) + @param siglen The length of the signature data (octets) + @param saltlen The length of the salt used (octets) + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param res [out] The result of the comparison, 1==valid, 0==invalid + @return CRYPT_OK if successful (even if the comparison failed) +*/ +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(NULL, 0, + NULL, -1, + hash_idx, + LTC_PKCS_1_PSS, saltlen, + ¶ms)) != CRYPT_OK) { + return err; + } + return ltc_pkcs_1_pss_decode_mgf1(msghash, msghashlen, sig, siglen, ¶ms, modulus_bitlen, res); +} +#endif /* LTC_PKCS_1 */ + +#endif /* LTC_NO_DEPRECATED_APIS */ diff --git a/src/misc/pem/pem.c b/src/misc/pem/pem.c index 632515914..1e8cc0132 100644 --- a/src/misc/pem/pem.c +++ b/src/misc/pem/pem.c @@ -10,6 +10,13 @@ #ifdef LTC_PEM const struct pem_header_id pem_std_headers[] = { + { + /* X.509 Certificates */ + SET_CSTR(.start, "-----BEGIN CERTIFICATE-----"), + SET_CSTR(.end, "-----END CERTIFICATE-----"), + .has_more_headers = no, + .flags = pf_x509, + }, { /* PKCS#8 encrypted */ SET_CSTR(.start, "-----BEGIN ENCRYPTED PRIVATE KEY-----"), @@ -24,13 +31,6 @@ const struct pem_header_id pem_std_headers[] = { .has_more_headers = no, .flags = pf_pkcs8, }, - { - /* X.509 Certificates */ - SET_CSTR(.start, "-----BEGIN CERTIFICATE-----"), - SET_CSTR(.end, "-----END CERTIFICATE-----"), - .has_more_headers = no, - .flags = pf_x509, - }, { /* Regular (plain) public keys */ SET_CSTR(.start, "-----BEGIN PUBLIC KEY-----"), diff --git a/src/misc/pem/pem_pkcs.c b/src/misc/pem/pem_pkcs.c index e99f29ea0..17aa47705 100644 --- a/src/misc/pem/pem_pkcs.c +++ b/src/misc/pem/pem_pkcs.c @@ -41,120 +41,50 @@ static int s_decrypt_pem(unsigned char *asn1_cert, unsigned long *asn1_len, cons return err; } -static int s_get_pka(ltc_asn1_list *pub, enum ltc_pka_id *pka) -{ - der_flexi_check flexi_should[4]; - ltc_asn1_list *seqid, *id; - enum ltc_oid_id oid_id; - int err; - unsigned long n = 0; - LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &seqid); - LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_BIT_STRING, NULL); - LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); - if ((err = der_flexi_sequence_cmp(pub, flexi_should)) != CRYPT_OK) { - return err; - } - n = 0; - LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OBJECT_IDENTIFIER, &id); - LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); - err = der_flexi_sequence_cmp(seqid, flexi_should); - if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) { - return err; - } - if ((err = pk_get_oid_from_asn1(id, &oid_id)) != CRYPT_OK) { - return err; - } - return pk_get_pka_id(oid_id, pka); -} +typedef int (*pkcs8_import_fn)(ltc_asn1_list *, ltc_asn1_list *, void*); -typedef int (*import_fn)(const unsigned char *, unsigned long, void*); - -static const import_fn s_import_x509_fns[LTC_PKA_NUM] = { +static const struct { + enum ltc_pka_id id; + pkcs8_import_fn fn; +} s_import_pkcs8_map[LTC_OID_NUM] = { +#ifdef LTC_MDH + [LTC_OID_DH] = { LTC_PKA_DH, (pkcs8_import_fn)dh_import_pkcs8_asn1 }, +#endif +#ifdef LTC_MDSA + [LTC_OID_DSA] = { LTC_PKA_DSA, (pkcs8_import_fn)dsa_import_pkcs8_asn1 }, +#endif #ifdef LTC_MRSA - [LTC_PKA_RSA] = (import_fn)rsa_import_x509, + [LTC_OID_RSA] = { LTC_PKA_RSA, (pkcs8_import_fn)rsa_import_pkcs8_asn1 }, #endif #ifdef LTC_MECC - [LTC_PKA_EC] = (import_fn)ecc_import_x509, + [LTC_OID_EC] = { LTC_PKA_EC, (pkcs8_import_fn)ecc_import_pkcs8_asn1 }, #endif #ifdef LTC_CURVE25519 - [LTC_PKA_X25519] = (import_fn)x25519_import_x509, - [LTC_PKA_ED25519] = (import_fn)ed25519_import_x509, + [LTC_OID_X25519] = { LTC_PKA_X25519, (pkcs8_import_fn)x25519_import_pkcs8_asn1 }, + [LTC_OID_ED25519] = { LTC_PKA_ED25519, (pkcs8_import_fn)ed25519_import_pkcs8_asn1 }, #endif }; -static int s_import_x509(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k) -{ - enum ltc_pka_id pka = LTC_PKA_UNDEF; - ltc_asn1_list *d, *spki; - int err; - if ((err = x509_decode_spki(asn1_cert, asn1_len, &d, &spki)) != CRYPT_OK) { - return err; - } - err = s_get_pka(spki, &pka); - der_free_sequence_flexi(d); - if (err != CRYPT_OK) { - return err; - } - if (pka < 0 - || pka > LTC_ARRAY_SIZE(s_import_x509_fns) - || s_import_x509_fns[pka] == NULL) { - return CRYPT_PK_INVALID_TYPE; - } - if ((err = s_import_x509_fns[pka](asn1_cert, asn1_len, &k->u)) == CRYPT_OK) { - k->id = pka; - } - return err; -} - static int s_import_pkcs8(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, const password_ctx *pw_ctx) { int err; - enum ltc_oid_id pka; + enum ltc_oid_id oid_id; ltc_asn1_list *alg_id, *priv_key; ltc_asn1_list *p8_asn1 = NULL; if ((err = pkcs8_decode_flexi(asn1_cert, asn1_len, pw_ctx, &p8_asn1)) != CRYPT_OK) { goto cleanup; } - if ((err = pkcs8_get_children(p8_asn1, &pka, &alg_id, &priv_key)) != CRYPT_OK) { + if ((err = pkcs8_get_children(p8_asn1, &oid_id, &alg_id, &priv_key)) != CRYPT_OK) { goto cleanup; } - switch (pka) { -#ifdef LTC_MDH - case LTC_OID_DH: - err = dh_import_pkcs8_asn1(alg_id, priv_key, &k->u.dh); - k->id = LTC_PKA_DH; - break; -#endif -#ifdef LTC_MDSA - case LTC_OID_DSA: - err = dsa_import_pkcs8_asn1(alg_id, priv_key, &k->u.dsa); - k->id = LTC_PKA_DSA; - break; -#endif -#ifdef LTC_MRSA - case LTC_OID_RSA: - err = rsa_import_pkcs8_asn1(alg_id, priv_key, &k->u.rsa); - k->id = LTC_PKA_RSA; - break; -#endif -#ifdef LTC_MECC - case LTC_OID_EC: - err = ecc_import_pkcs8_asn1(alg_id, priv_key, &k->u.ecc); - k->id = LTC_PKA_EC; - break; -#endif -#ifdef LTC_CURVE25519 - case LTC_OID_X25519: - err = x25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.x25519); - k->id = LTC_PKA_X25519; - break; - case LTC_OID_ED25519: - err = ed25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.ed25519); - k->id = LTC_PKA_ED25519; - break; -#endif - default: - err = CRYPT_PK_INVALID_TYPE; + if (oid_id < 0 + || oid_id > LTC_ARRAY_SIZE(s_import_pkcs8_map) + || s_import_pkcs8_map[oid_id].fn == NULL) { + err = CRYPT_PK_INVALID_TYPE; + goto cleanup; + } + if ((err = s_import_pkcs8_map[oid_id].fn(alg_id, priv_key, &k->u)) == CRYPT_OK) { + k->id = s_import_pkcs8_map[oid_id].id; } cleanup: @@ -171,11 +101,13 @@ static int s_extract_pka(unsigned char *asn1_cert, unsigned long asn1_len, enum if ((err = der_decode_sequence_flexi(asn1_cert, &asn1_len, &pub)) != CRYPT_OK) { return err; } - err = s_get_pka(pub, pka); + err = x509_get_pka(pub, pka); der_sequence_free(pub); return err; } +typedef int (*import_fn)(const unsigned char *, unsigned long, void*); + static const import_fn s_import_openssl_fns[LTC_PKA_NUM] = { #ifdef LTC_MRSA [LTC_PKA_RSA] = (import_fn)rsa_import, @@ -195,21 +127,16 @@ static const import_fn s_import_openssl_fns[LTC_PKA_NUM] = { static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx) { unsigned char *asn1_cert = NULL; - unsigned long w, asn1_len, n; + unsigned long w = 0, asn1_len, n; int err = CRYPT_ERROR; struct pem_headers hdr = { 0 }; struct password pw = { 0 }; enum ltc_pka_id pka; XMEMSET(k, 0, sizeof(*k)); - w = LTC_PEM_READ_BUFSIZE * 2; -retry: - asn1_cert = XREALLOC(asn1_cert, w); for (n = 0; n < pem_std_headers_num; ++n) { hdr.id = &pem_std_headers[n]; - err = pem_read(asn1_cert, &w, &hdr, g); - if (err == CRYPT_BUFFER_OVERFLOW) { - goto retry; - } else if (err == CRYPT_OK) { + err = pem_read((void**)&asn1_cert, &w, &hdr, g); + if (err == CRYPT_OK) { break; } else if (err != CRYPT_UNKNOWN_PEM) { goto cleanup; @@ -224,7 +151,7 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c err = s_import_pkcs8(asn1_cert, asn1_len, k, pw_ctx); goto cleanup; } else if (hdr.id->flags == pf_x509) { - err = s_import_x509(asn1_cert, asn1_len, k); + err = x509_import_spki(asn1_cert, asn1_len, k, NULL); goto cleanup; } else if ((hdr.id->flags & pf_public) && hdr.id->pka == LTC_PKA_UNDEF) { if ((err = s_extract_pka(asn1_cert, asn1_len, &pka)) != CRYPT_OK) { @@ -272,7 +199,7 @@ int pem_decode_pkcs_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *pw_c LTC_ARGCHK(f != NULL); LTC_ARGCHK(k != NULL); { - struct get_char g = { .get = pem_get_char_from_file, .data.f = f }; + struct get_char g = pem_get_char_init_filehandle(f); return s_decode(&g, k, pw_ctx); } } @@ -284,7 +211,7 @@ int pem_decode_pkcs(const void *buf, unsigned long len, ltc_pka_key *k, const pa LTC_ARGCHK(len != 0); LTC_ARGCHK(k != NULL); { - struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.data.buf, buf, len) }; + struct get_char g = pem_get_char_init(buf, len); return s_decode(&g, k, pw_ctx); } } diff --git a/src/misc/pem/pem_read.c b/src/misc/pem/pem_read.c index abefff924..bbc61cb0d 100644 --- a/src/misc/pem/pem_read.c +++ b/src/misc/pem/pem_read.c @@ -17,14 +17,76 @@ extern const struct str pem_dek_info_start; extern const struct blockcipher_info pem_dek_infos[]; extern const unsigned long pem_dek_infos_num; +static LTC_INLINE unsigned long s_bufp_alloc_len(struct bufp *buf) +{ + if (buf->start == NULL || buf->end == NULL) + return 0; + return buf->end - buf->start - 1; +} + +static LTC_INLINE unsigned long s_bufp_used_len(struct bufp *buf) +{ + if (buf->start == NULL || buf->end == NULL) + return 0; + return buf->work - buf->start; +} + +static LTC_INLINE int s_bufp_grow(struct bufp *buf) +{ + int err = CRYPT_OK; + void *ret; + unsigned long alloc_len = s_bufp_alloc_len(buf), realloc_len; + unsigned long work_offset = s_bufp_used_len(buf); + if (alloc_len == 0) + realloc_len = LTC_PEM_READ_BUFSIZE; + else + realloc_len = alloc_len * 2; + if (realloc_len < alloc_len) + return CRYPT_OVERFLOW; + ret = XREALLOC(buf->start, realloc_len); + if (ret == NULL) { + err = CRYPT_MEM; + } else { + UPDATE_BUFP((*buf), ret, work_offset, realloc_len); + } + return err; +} + +static LTC_INLINE int s_bufp_fits(struct bufp *buf, unsigned long to_write) +{ + char *d = buf->work; + char *e = buf->end; + char *w = d + to_write; + if (d == NULL || w < d || w > e) + return 0; + return 1; +} + +static LTC_INLINE int s_bufp_add(struct bufp *buf, const void *src, unsigned long len) +{ + int err; + if (!s_bufp_fits(buf, len)) { + if ((err = s_bufp_grow(buf)) != CRYPT_OK) { + return err; + } + } + XMEMCPY(buf->work, src, len); + buf->work += len; + return CRYPT_OK; +} + #ifndef LTC_NO_FILE -int pem_get_char_from_file(struct get_char *g) +static int s_pem_get_char_from_file(struct get_char *g) { - return getc(g->data.f); + return getc(g->data.f.f); } + +const struct get_char_api get_char_filehandle_api = { + .get = s_pem_get_char_from_file, +}; #endif /* LTC_NO_FILE */ -int pem_get_char_from_buf(struct get_char *g) +static int s_pem_get_char_from_buf(struct get_char *g) { int ret; if (g->data.buf.work == g->data.buf.end) { @@ -35,6 +97,10 @@ int pem_get_char_from_buf(struct get_char *g) return ret; } +const struct get_char_api get_char_buffer_api = { + .get = s_pem_get_char_from_buf, +}; + static void s_unget_line(char *buf, unsigned long buflen, struct get_char *g) { if (buflen > sizeof(g->unget_buf_)) @@ -81,7 +147,7 @@ static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, while(blen < *buflen || search_for_start) { wr = blen < *buflen ? blen : *buflen - 1; c_ = g->prev_get; - g->prev_get = g->get(g); + g->prev_get = g->api.get(g); if (g->prev_get == '\n') { buf[wr] = '\0'; if (c_ == '\r') { @@ -89,6 +155,7 @@ static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, } s_tts(buf, &wr); *buflen = wr; + g->total_read++; return buf; } if (g->prev_get == -1 || g->prev_get == '\0') { @@ -99,30 +166,21 @@ static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, } buf[wr] = g->prev_get; blen++; + g->total_read++; } return NULL; } -LTC_INLINE static char* s_get_first_line(char *buf, unsigned long *buflen, struct get_char *g) +static LTC_INLINE char* s_get_first_line(char *buf, unsigned long *buflen, struct get_char *g) { return s_get_line_i(buf, buflen, g, 1); } -LTC_INLINE static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g) +static LTC_INLINE char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g) { return s_get_line_i(buf, buflen, g, 0); } -static LTC_INLINE int s_fits_buf(void *dest, unsigned long to_write, void *end) -{ - unsigned char *d = dest; - unsigned char *e = end; - unsigned char *w = d + to_write; - if (w < d || w > e) - return 0; - return 1; -} - static int s_pem_decode_headers(struct pem_headers *hdr, struct get_char *g) { char buf[LTC_PEM_DECODE_BUFSZ], *alg_start; @@ -190,31 +248,29 @@ static int s_pem_decode_headers(struct pem_headers *hdr, struct get_char *g) return CRYPT_OK; } -int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, struct get_char *g) +int pem_read(void **dest, unsigned long *len, struct pem_headers *hdr, struct get_char *g) { - char buf[LTC_PEM_DECODE_BUFSZ]; - char *wpem = asn1_cert; - char *end = wpem + *asn1_len; + char line[LTC_PEM_DECODE_BUFSZ]; + struct bufp b_ = {0}, *b = &b_; const char pem_start[] = "----"; - unsigned long slen, linelen; + unsigned long slen; int err, hdr_ok = 0; - int would_overflow = 0; unsigned char empty_lines = 0; g->prev_get = 0; do { - linelen = sizeof(buf); - if (s_get_first_line(buf, &linelen, g) == NULL) { + slen = sizeof(line); + if (s_get_first_line(line, &slen, g) == NULL) { if (g->prev_get == -1) return CRYPT_NOP; else return CRYPT_INVALID_PACKET; } - if (linelen < sizeof(pem_start) - 1) + if (slen < sizeof(pem_start) - 1) continue; - } while(XMEMCMP(buf, pem_start, sizeof(pem_start) - 1) != 0); - if (hdr->id->start.len != linelen || XMEMCMP(buf, hdr->id->start.p, hdr->id->start.len)) { - s_unget_line(buf, linelen, g); + } while(XMEMCMP(line, pem_start, sizeof(pem_start) - 1) != 0); + if (hdr->id->start.len != slen || XMEMCMP(line, hdr->id->start.p, hdr->id->start.len)) { + s_unget_line(line, slen, g); return CRYPT_UNKNOWN_PEM; } @@ -223,9 +279,9 @@ int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, return err; /* Read the base64 encoded part of the PEM */ - slen = sizeof(buf); - while (s_get_line(buf, &slen, g)) { - if (slen == hdr->id->end.len && !XMEMCMP(buf, hdr->id->end.p, slen)) { + slen = sizeof(line); + while (s_get_line(line, &slen, g)) { + if (slen == hdr->id->end.len && !XMEMCMP(line, hdr->id->end.p, slen)) { hdr_ok = 1; break; } @@ -234,34 +290,26 @@ int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, break; empty_lines++; } - if (!would_overflow && s_fits_buf(wpem, slen, end)) { - XMEMCPY(wpem, buf, slen); - } else { - would_overflow = 1; + if ((err = s_bufp_add(b, line, slen)) != CRYPT_OK) { + goto error_out; } - wpem += slen; - slen = sizeof(buf); + slen = sizeof(line); } - if (!hdr_ok) - return CRYPT_INVALID_PACKET; - - if (would_overflow || !s_fits_buf(wpem, 1, end)) { - /* NUL termination */ - wpem++; - /* prevent a wrap-around */ - if (wpem < (char*)asn1_cert) - return CRYPT_OVERFLOW; - *asn1_len = wpem - (char*)asn1_cert; - return CRYPT_BUFFER_OVERFLOW; + if (!hdr_ok) { + err = CRYPT_INVALID_PACKET; + } else { + slen = s_bufp_alloc_len(b); + err = base64_strict_decode(b->start, s_bufp_used_len(b), (void*)b->start, &slen); } + if (err == CRYPT_OK) { + *dest = b->start; + *len = slen; - *asn1_len = wpem - (char*)asn1_cert; - *wpem++ = '\0'; - - if ((err = base64_strict_decode(asn1_cert, *asn1_len, asn1_cert, asn1_len)) != CRYPT_OK) { - return err; + } else { +error_out: + XFREE(b->start); } - return CRYPT_OK; + return err; } #endif /* LTC_PEM */ diff --git a/src/misc/pem/pem_ssh.c b/src/misc/pem/pem_ssh.c index 77fa87be9..d4de0865a 100644 --- a/src/misc/pem/pem_ssh.c +++ b/src/misc/pem/pem_ssh.c @@ -712,20 +712,15 @@ static const unsigned long pem_openssh_num = LTC_ARRAY_SIZE(pem_openssh); static int s_decode_openssh(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx) { unsigned char *pem = NULL, *p, *privkey = NULL, *tag; - unsigned long n, w, l, privkey_len, taglen; + unsigned long n, w = 0, l, privkey_len, taglen; int err; struct pem_headers hdr; struct kdf_options opts = { 0 }; XMEMSET(k, 0, sizeof(*k)); - w = LTC_PEM_READ_BUFSIZE * 2; -retry: - pem = XREALLOC(pem, w); for (n = 0; n < pem_openssh_num; ++n) { hdr.id = &pem_openssh[n]; - err = pem_read(pem, &w, &hdr, g); - if (err == CRYPT_BUFFER_OVERFLOW) { - goto retry; - } else if (err == CRYPT_OK) { + err = pem_read((void**)&pem, &w, &hdr, g); + if (err == CRYPT_OK) { break; } else if (err != CRYPT_UNKNOWN_PEM) { goto cleanup; @@ -791,7 +786,9 @@ static int s_decode_openssh(struct get_char *g, ltc_pka_key *k, const password_c zeromem(privkey, privkey_len); XFREE(privkey); } - XFREE(pem); + if (pem) { + XFREE(pem); + } return err; } @@ -801,7 +798,7 @@ int pem_decode_openssh_filehandle(FILE *f, ltc_pka_key *k, const password_ctx *p LTC_ARGCHK(f != NULL); LTC_ARGCHK(k != NULL); { - struct get_char g = { .get = pem_get_char_from_file, .data.f = f }; + struct get_char g = pem_get_char_init_filehandle(f); return s_decode_openssh(&g, k, pw_ctx); } } @@ -841,7 +838,7 @@ int pem_decode_openssh(const void *buf, unsigned long len, ltc_pka_key *k, const LTC_ARGCHK(len != 0); LTC_ARGCHK(k != NULL); { - struct get_char g = { .get = pem_get_char_from_buf, SET_BUFP(.data.buf, buf, len) }; + struct get_char g = pem_get_char_init(buf, len); return s_decode_openssh(&g, k, pw_ctx); } } diff --git a/src/pk/asn1/der/sequence/der_flexi_sequence_cmp.c b/src/pk/asn1/der/sequence/der_flexi_sequence_cmp.c index 026eb504a..535483f59 100644 --- a/src/pk/asn1/der/sequence/der_flexi_sequence_cmp.c +++ b/src/pk/asn1/der/sequence/der_flexi_sequence_cmp.c @@ -24,11 +24,20 @@ int der_flexi_sequence_cmp(const ltc_asn1_list *flexi, der_flexi_check *check) return CRYPT_INVALID_PACKET; } cur = flexi->child; - while(check->t != LTC_ASN1_EOL) { + while(check->t != LTC_ASN1_EOL && cur) { if (!LTC_ASN1_IS_TYPE(cur, check->t)) { + if (check->optional) { + check++; + continue; + } return CRYPT_INVALID_PACKET; } if (check->pp != NULL) *check->pp = cur; + else if (check->handler) { + int err = check->handler(cur, check->userdata); + if (err != CRYPT_OK) + return err; + } cur = cur->next; check++; } diff --git a/src/pk/asn1/oid/pk_get.c b/src/pk/asn1/oid/pk_get.c index 1fd5872e2..81a1b2f3e 100644 --- a/src/pk/asn1/oid/pk_get.c +++ b/src/pk/asn1/oid/pk_get.c @@ -7,18 +7,22 @@ typedef struct { enum ltc_oid_id id; enum ltc_pka_id pka; - const char* oid; + const char *hash; + const char *oid; } oid_table_entry; static const oid_table_entry pka_oids[] = { - { LTC_OID_UNDEF, LTC_PKA_UNDEF, NULL }, - { LTC_OID_RSA, LTC_PKA_RSA, "1.2.840.113549.1.1.1" }, - { LTC_OID_DSA, LTC_PKA_DSA, "1.2.840.10040.4.1" }, - { LTC_OID_EC, LTC_PKA_EC, "1.2.840.10045.2.1" }, - { LTC_OID_EC_PRIMEF, LTC_PKA_EC, "1.2.840.10045.1.1" }, - { LTC_OID_X25519, LTC_PKA_X25519, "1.3.101.110" }, - { LTC_OID_ED25519, LTC_PKA_ED25519, "1.3.101.112" }, - { LTC_OID_DH, LTC_PKA_DH, "1.2.840.113549.1.3.1" }, + { LTC_OID_UNDEF, LTC_PKA_UNDEF, NULL, NULL }, + { LTC_OID_RSA, LTC_PKA_RSA, NULL, "1.2.840.113549.1.1.1" }, + { LTC_OID_DSA, LTC_PKA_DSA, NULL, "1.2.840.10040.4.1" }, + { LTC_OID_EC, LTC_PKA_EC, NULL, "1.2.840.10045.2.1" }, + { LTC_OID_EC_PRIMEF, LTC_PKA_EC, NULL, "1.2.840.10045.1.1" }, + { LTC_OID_X25519, LTC_PKA_X25519, NULL, "1.3.101.110" }, + { LTC_OID_ED25519, LTC_PKA_ED25519, NULL, "1.3.101.112" }, + { LTC_OID_DH, LTC_PKA_DH, NULL, "1.2.840.113549.1.3.1" }, + { LTC_OID_RSA_OAEP, LTC_PKA_RSA, NULL, "1.2.840.113549.1.1.7" }, + { LTC_OID_RSA_MGF1, LTC_PKA_RSA, NULL, "1.2.840.113549.1.1.8" }, + { LTC_OID_RSA_PSS, LTC_PKA_RSA_PSS, NULL, "1.2.840.113549.1.1.10" }, }; static LTC_INLINE const oid_table_entry* s_get_entry(enum ltc_oid_id id) @@ -43,21 +47,35 @@ int pk_get_oid(enum ltc_oid_id id, const char **st) return CRYPT_INVALID_ARG; } -/* - Returns the PKA ID requested. - @return CRYPT_OK if valid -*/ -int pk_get_pka_id(enum ltc_oid_id id, enum ltc_pka_id *pka) +static LTC_INLINE int s_get_values(enum ltc_oid_id id, enum ltc_pka_id *pka, const char **hash) { const oid_table_entry* e = s_get_entry(id); LTC_ARGCHK(pka != NULL); if (e != NULL) { *pka = e->pka; + if (hash) { + *hash = e->hash; + } else if (e->hash) { + /* If we don't want the hash result, but the entry has a hash, we're most likely + * confused and we prefer to stop processing then, instead of continuing with a + * maybe wrong assumption. + */ + return CRYPT_INVALID_ARG; + } return CRYPT_OK; } return CRYPT_INVALID_ARG; } +/* + Returns the PKA ID requested. + @return CRYPT_OK if valid +*/ +int pk_get_pka_id(enum ltc_oid_id id, enum ltc_pka_id *pka) +{ + return s_get_values(id, pka, NULL); +} + /* Returns the OID ID requested. @return CRYPT_OK if valid diff --git a/src/pk/asn1/x509/x509_decode_public_key_from_certificate.c b/src/pk/asn1/x509/x509_decode_public_key_from_certificate.c index 45a1c6f60..b96db4438 100644 --- a/src/pk/asn1/x509/x509_decode_public_key_from_certificate.c +++ b/src/pk/asn1/x509/x509_decode_public_key_from_certificate.c @@ -10,7 +10,7 @@ #ifdef LTC_DER /** - Try to decode the public key from a X.509 certificate + Process the public key from the SubjectPublicKeyInfo of a X.509 certificate @param in The input buffer @param inlen The length of the input buffer @param algorithm One out of the enum #public_key_algorithms @@ -19,53 +19,82 @@ @param parameters_len [in/out] The number of parameters to include @param callback The callback @param ctx The context passed to the callback - @return CRYPT_OK on success, - CRYPT_NOP if no SubjectPublicKeyInfo was found, - another error if decoding or memory allocation failed + @return CRYPT_OK on success */ -int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen, - enum ltc_oid_id algorithm, ltc_asn1_type param_type, - ltc_asn1_list* parameters, unsigned long *parameters_len, - public_key_decode_cb callback, void *ctx) +int x509_process_public_key_from_spki(const unsigned char *in, unsigned long inlen, + enum ltc_oid_id algorithm, ltc_asn1_type param_type, + ltc_asn1_list* parameters, unsigned long *parameters_len, + public_key_decode_cb callback, void *key) { int err; unsigned char *tmpbuf = NULL; unsigned long tmpbuf_len; - ltc_asn1_list *decoded_list = NULL, *spki; - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(inlen != 0); - LTC_ARGCHK(callback != NULL); - - if ((err = x509_decode_spki(in, inlen, &decoded_list, &spki)) != CRYPT_OK) { - return err; - } + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(callback != NULL); if (algorithm == LTC_OID_EC) { - err = callback(spki->data, spki->size, ctx); + err = callback(in, inlen, key); } else { tmpbuf_len = inlen; tmpbuf = XCALLOC(1, tmpbuf_len); if (tmpbuf == NULL) { - err = CRYPT_MEM; - goto LBL_OUT; + return CRYPT_MEM; } - err = x509_decode_subject_public_key_info(spki->data, spki->size, + err = x509_decode_subject_public_key_info(in, inlen, algorithm, tmpbuf, &tmpbuf_len, param_type, parameters, parameters_len); if (err == CRYPT_OK) { - err = callback(tmpbuf, tmpbuf_len, ctx); - goto LBL_OUT; + err = callback(tmpbuf, tmpbuf_len, key); } } -LBL_OUT: - if (decoded_list) der_free_sequence_flexi(decoded_list); if (tmpbuf != NULL) XFREE(tmpbuf); return err; } +/** + Try to decode the public key from a X.509 certificate + @param in The input buffer + @param inlen The length of the input buffer + @param algorithm One out of the enum #public_key_algorithms + @param param_type The parameters' type out of the enum ltc_asn1_type + @param parameters The parameters to include + @param parameters_len [in/out] The number of parameters to include + @param callback The callback + @param ctx The context passed to the callback + @return CRYPT_OK on success, + CRYPT_NOP if no SubjectPublicKeyInfo was found, + another error if decoding or memory allocation failed +*/ +int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen, + enum ltc_oid_id algorithm, ltc_asn1_type param_type, + ltc_asn1_list* parameters, unsigned long *parameters_len, + public_key_decode_cb callback, void *key) +{ + int err; + ltc_asn1_list *decoded_list; + const ltc_asn1_list *spki; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != 0); + LTC_ARGCHK(callback != NULL); + + if ((err = x509_decode_spki(in, inlen, &decoded_list, &spki)) != CRYPT_OK) { + return err; + } + + err = x509_process_public_key_from_spki(spki->data, spki->size, + algorithm, param_type, + parameters, parameters_len, + callback, key); + + if (decoded_list) der_free_sequence_flexi(decoded_list); + + return err; +} + #endif diff --git a/src/pk/asn1/x509/x509_decode_spki.c b/src/pk/asn1/x509/x509_decode_spki.c index 147aaf1c6..144441cd2 100644 --- a/src/pk/asn1/x509/x509_decode_spki.c +++ b/src/pk/asn1/x509/x509_decode_spki.c @@ -26,10 +26,10 @@ @param spki [out] A pointer to the SubjectPublicKeyInfo @return CRYPT_OK on success, CRYPT_NOP if no SubjectPublicKeyInfo was found, another error if decoding failed */ -int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, ltc_asn1_list **spki) +int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, const ltc_asn1_list **spki) { int err; - unsigned long tmp_inlen; + unsigned long tmp_inlen, n, element_is_spki; ltc_asn1_list *decoded_list = NULL, *l; LTC_ARGCHK(in != NULL); @@ -49,29 +49,49 @@ int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) { l = l->child; if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) { + /* TBSCertificate ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * serialNumber CertificateSerialNumber, + * signature AlgorithmIdentifier, + * issuer Name, + * validity Validity, + * subject Name, + * subjectPublicKeyInfo SubjectPublicKeyInfo, + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version MUST be v2 or v3 + * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version MUST be v2 or v3 + * extensions [3] EXPLICIT Extensions OPTIONAL + * -- If present, version MUST be v3 + * } + */ l = l->child; - /* Move forward in the tree until we find this combination - ... - SEQUENCE - SEQUENCE - OBJECT IDENTIFIER - NULL - BIT STRING + /* `l` points now either to 'version' or 'serialNumber', depending on + * whether 'version' is included or defaults to 'v1'. + * 'version' is represented as a LTC_ASN1_CUSTOM_TYPE + * 'serialNumber' is represented as an LTC_ASN1_INTEGER + * Decide now whether to move 5 or 6 elements forward until + * `l` should point to subjectPublicKeyInfo. */ - do { - /* The additional check for l->data is there to make sure - * we won't try to decode a list that has been 'shrunk' - */ - if ((l->type == LTC_ASN1_SEQUENCE) - && (l->data != NULL) - && LOOKS_LIKE_SPKI(l->child)) { - *out = decoded_list; - *spki = l; - return CRYPT_OK; - } + if (l->type == LTC_ASN1_CUSTOM_TYPE) + element_is_spki = 6; + else + element_is_spki = 5; + for (n = 0; n < element_is_spki && l; ++n) { l = l->next; - } while(l); + } + /* The additional check for l->data is there to make sure + * we won't try to decode a list that has been 'shrunk' + */ + if ((l != NULL) + && (l->type == LTC_ASN1_SEQUENCE) + && (l->data != NULL) + && LOOKS_LIKE_SPKI(l->child)) { + *out = decoded_list; + *spki = l; + return CRYPT_OK; + } } } } diff --git a/src/pk/asn1/x509/x509_get_pka.c b/src/pk/asn1/x509/x509_get_pka.c new file mode 100644 index 000000000..0236c761e --- /dev/null +++ b/src/pk/asn1/x509/x509_get_pka.c @@ -0,0 +1,38 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x509_get_pka.c + Extract the PKA from an X.509 cert, Steffen Jaeckel +*/ + +#ifdef LTC_DER + +int x509_get_pka(const ltc_asn1_list *pub, enum ltc_pka_id *pka) +{ + der_flexi_check flexi_should[4]; + ltc_asn1_list *seqid, *id = NULL; + enum ltc_oid_id oid_id; + int err; + unsigned long n = 0; + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &seqid); + LTC_SET_DER_FLEXI_CHECK_OPT(flexi_should, n++, LTC_ASN1_BIT_STRING, NULL); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); + if ((err = der_flexi_sequence_cmp(pub, flexi_should)) != CRYPT_OK) { + return err; + } + n = 0; + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OBJECT_IDENTIFIER, &id); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); + err = der_flexi_sequence_cmp(seqid, flexi_should); + if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) { + return err; + } + if ((err = pk_get_oid_from_asn1(id, &oid_id)) != CRYPT_OK) { + return err; + } + return pk_get_pka_id(oid_id, pka); +} + +#endif /* LTC_DER */ diff --git a/src/pk/asn1/x509/x509_import_spki.c b/src/pk/asn1/x509/x509_import_spki.c new file mode 100644 index 000000000..13057bd31 --- /dev/null +++ b/src/pk/asn1/x509/x509_import_spki.c @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x509_import_spki.c + Import the SubjectPublicKeyInfo of an X.509 cert, Steffen Jaeckel +*/ + +#ifdef LTC_DER + +typedef int (*import_fn)(const unsigned char *, unsigned long, void *); + +#ifdef LTC_CURVE25519 +static int s_x25519_import_pub(const unsigned char *in, unsigned long inlen, void *key) +{ + return x25519_import_raw(in, inlen, PK_PUBLIC, key); +} +static int s_x25519_import_spki(const unsigned char *in, unsigned long inlen, void *key) +{ + return x509_process_public_key_from_spki(in, inlen, + LTC_OID_X25519, + LTC_ASN1_EOL, NULL, NULL, + s_x25519_import_pub, key); +} + +static int s_ed25519_import_pub(const unsigned char *in, unsigned long inlen, void *key) +{ + return ed25519_import_raw(in, inlen, PK_PUBLIC, key); +} +static int s_ed25519_import_spki(const unsigned char *in, unsigned long inlen, void *key) +{ + return x509_process_public_key_from_spki(in, inlen, + LTC_OID_ED25519, + LTC_ASN1_EOL, NULL, NULL, + s_ed25519_import_pub, key); +} +#endif + +static const import_fn s_import_spki_fns[LTC_PKA_NUM] = { +#ifdef LTC_MRSA + [LTC_PKA_RSA] = (import_fn)rsa_import_spki, + [LTC_PKA_RSA_PSS] = (import_fn)rsa_import_spki, +#endif +#ifdef LTC_MDSA + [LTC_PKA_DSA] = (import_fn)dsa_import_spki, +#endif +#ifdef LTC_MECC + [LTC_PKA_EC] = (import_fn)ecc_import_subject_public_key_info, +#endif +#ifdef LTC_CURVE25519 + [LTC_PKA_X25519] = (import_fn)s_x25519_import_spki, + [LTC_PKA_ED25519] = (import_fn)s_ed25519_import_spki, +#endif +}; + +int x509_import_spki(const unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, ltc_asn1_list **root) +{ + enum ltc_pka_id pka = LTC_PKA_UNDEF; + ltc_asn1_list *d; + const ltc_asn1_list *spki; + int err; + if ((err = x509_decode_spki(asn1_cert, asn1_len, &d, &spki)) != CRYPT_OK) { + return err; + } + if ((err = x509_get_pka(spki, &pka)) != CRYPT_OK) { + goto err_out; + } + if (pka < 0 + || pka > LTC_ARRAY_SIZE(s_import_spki_fns) + || s_import_spki_fns[pka] == NULL) { + err = CRYPT_PK_INVALID_TYPE; + goto err_out; + } + if ((err = s_import_spki_fns[pka](spki->data, spki->size, &k->u)) == CRYPT_OK) { + k->id = pka; + } +err_out: + if (err == CRYPT_OK && root) { + *root = d; + d = NULL; + } + der_free_sequence_flexi(d); + return err; +} + +#endif /* LTC_DER */ diff --git a/src/pk/dsa/dsa_import.c b/src/pk/dsa/dsa_import.c index d2c2d49ec..91ddcc2be 100644 --- a/src/pk/dsa/dsa_import.c +++ b/src/pk/dsa/dsa_import.c @@ -9,7 +9,7 @@ #ifdef LTC_MDSA -int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key) +static int s_dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key) { int err; unsigned long zero = 0; @@ -28,6 +28,109 @@ int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key) return err; } +static int s_dsa_import_y(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + return der_decode_integer(in, inlen, key->y); +} + +static LTC_INLINE int s_dsa_set_params(dsa_key *key, ltc_asn1_list *params) +{ + LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL); + LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL); + LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL); + return 3; +} + +static LTC_INLINE int s_dsa_validate(dsa_key *key) +{ + int err, stat; + key->qord = ltc_mp_unsigned_bin_size(key->q); + + /* quick p, q, g validation, without primality testing + * + x, y validation */ + if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) { + return err; + } + + if (stat == 0) { + return CRYPT_INVALID_PACKET; + } + + return CRYPT_OK; +} + +static int s_dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + int err; + unsigned char* tmpbuf = NULL; + ltc_asn1_list params[3]; + unsigned long tmpbuf_len = inlen, len; + + len = s_dsa_set_params(key, params); + + tmpbuf = XCALLOC(1, tmpbuf_len); + if (tmpbuf == NULL) { + return CRYPT_MEM; + } + + err = x509_decode_subject_public_key_info(in, inlen, + LTC_OID_DSA, tmpbuf, &tmpbuf_len, + LTC_ASN1_SEQUENCE, params, &len); + if (err != CRYPT_OK) { + goto LBL_ERR; + } + + if ((err = s_dsa_import_y(tmpbuf, tmpbuf_len, key)) != CRYPT_OK) { + goto LBL_ERR; + } + + key->type = PK_PUBLIC; +LBL_ERR: + XFREE(tmpbuf); + return err; +} + +int dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + int err; + + LTC_ARGCHK(in != NULL); + + /* init key */ + if ((err = dsa_int_init(key)) != CRYPT_OK) return err; + + if ((err = s_dsa_import_spki(in, inlen, key)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = s_dsa_validate(key)) != CRYPT_OK) { + goto LBL_ERR; + } + + return CRYPT_OK; +LBL_ERR: + dsa_free(key); + return err; +} + +static int s_dsa_import_x509(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + int err; + ltc_asn1_list params[3]; + unsigned long len; + + len = s_dsa_set_params(key, params); + + if ((err = x509_decode_public_key_from_certificate(in, inlen, + LTC_OID_DSA, + LTC_ASN1_SEQUENCE, params, &len, + (public_key_decode_cb)s_dsa_import_y, key)) == CRYPT_OK) { + key->type = PK_PUBLIC; + return CRYPT_OK; + } + + return err; +} + /** Import a DSA key @param in The binary packet to import from @@ -37,8 +140,7 @@ int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key) */ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) { - int err, stat; - unsigned char* tmpbuf = NULL; + int err; unsigned char flags[1]; LTC_ARGCHK(in != NULL); @@ -86,47 +188,18 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) } } - if (dsa_import_pkcs1(in, inlen, key) != CRYPT_OK) { - ltc_asn1_list params[3]; - unsigned long tmpbuf_len = inlen, len; - - LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL); - LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL); - LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL); - len = 3; - - tmpbuf = XCALLOC(1, tmpbuf_len); - if (tmpbuf == NULL) { - return CRYPT_MEM; - } - - err = x509_decode_subject_public_key_info(in, inlen, - LTC_OID_DSA, tmpbuf, &tmpbuf_len, - LTC_ASN1_SEQUENCE, params, &len); - if (err != CRYPT_OK) { - XFREE(tmpbuf); - goto LBL_ERR; - } - - if ((err = der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) { - XFREE(tmpbuf); - goto LBL_ERR; - } - - key->type = PK_PUBLIC; - XFREE(tmpbuf); + if (s_dsa_import_pkcs1(in, inlen, key) == CRYPT_OK) { + goto LBL_OK; } - -LBL_OK: - key->qord = ltc_mp_unsigned_bin_size(key->q); - - /* quick p, q, g validation, without primality testing - * + x, y validation */ - if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) { + if (s_dsa_import_spki(in, inlen, key) == CRYPT_OK) { + goto LBL_OK; + } + if ((err = s_dsa_import_x509(in, inlen, key)) != CRYPT_OK) { goto LBL_ERR; } - if (stat == 0) { - err = CRYPT_INVALID_PACKET; + +LBL_OK: + if ((err = s_dsa_validate(key)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/pk/ecc/ecc_make_key.c b/src/pk/ecc/ecc_make_key.c index c8239cf1d..1b047417b 100644 --- a/src/pk/ecc/ecc_make_key.c +++ b/src/pk/ecc/ecc_make_key.c @@ -59,7 +59,6 @@ int ecc_generate_key(prng_state *prng, int wprng, ecc_key *key) goto error; } key->type = PK_PRIVATE; - key->rfc6979_hash_alg = NULL; /* success */ err = CRYPT_OK; diff --git a/src/pk/ecc/ecc_recover_key.c b/src/pk/ecc/ecc_recover_key.c index 3b6332b54..ebd1a410d 100644 --- a/src/pk/ecc/ecc_recover_key.c +++ b/src/pk/ecc/ecc_recover_key.c @@ -23,20 +23,21 @@ */ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, - int recid, ecc_signature_type sigformat, ecc_key *key) + ltc_ecc_sig_opts *opts, ecc_key *key) { ecc_point *mG = NULL, *mQ = NULL, *mR = NULL; void *p, *m, *a, *b; void *r, *s, *v, *w, *t1, *t2, *u1, *u2, *v1, *v2, *e, *x, *y, *a_plus3; void *mu = NULL, *ma = NULL; void *mp = NULL; - int err; + int err, recid; unsigned long pbits, pbytes, i, shift_right; unsigned char ch, buf[MAXBLOCKSIZE]; LTC_ARGCHK(sig != NULL); LTC_ARGCHK(hash != NULL); LTC_ARGCHK(key != NULL); + LTC_ARGCHK(opts != NULL); /* BEWARE: requires sqrtmod_prime */ if (ltc_mp.sqrtmod_prime == NULL) { @@ -64,8 +65,9 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, err = CRYPT_MEM; goto error; } + recid = (opts->recid != NULL) ? *(opts->recid) : -1; - if (sigformat == LTC_ECCSIG_RFC7518) { + if (opts->type == LTC_ECCSIG_RFC7518) { /* RFC7518 format - raw (r,s) */ i = ltc_mp_unsigned_bin_size(key->dp.order); if (siglen != (2*i)) { @@ -75,7 +77,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, if ((err = ltc_mp_read_unsigned_bin(r, sig, i)) != CRYPT_OK) { goto error; } if ((err = ltc_mp_read_unsigned_bin(s, sig+i, i)) != CRYPT_OK) { goto error; } } - else if (sigformat == LTC_ECCSIG_ETH27) { + else if (opts->type == LTC_ECCSIG_ETH27) { /* Ethereum (v,r,s) format */ 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 */ @@ -97,7 +99,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, if ((err = ltc_mp_read_unsigned_bin(s, sig+32, 32)) != CRYPT_OK) { goto error; } } #ifdef LTC_DER - else if (sigformat == LTC_ECCSIG_ANSIX962) { + else if (opts->type == LTC_ECCSIG_ANSIX962) { /* ANSI X9.62 format - ASN.1 encoded SEQUENCE{ INTEGER(r), INTEGER(s) } */ if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT, LTC_ASN1_INTEGER, 1UL, r, @@ -106,7 +108,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, } #endif #ifdef LTC_SSH - else if (sigformat == LTC_ECCSIG_RFC5656) { + else if (opts->type == LTC_ECCSIG_RFC5656) { char name[64], name2[64]; unsigned long namelen = sizeof(name); unsigned long name2len = sizeof(name2); diff --git a/src/pk/ecc/ecc_rfc6979_key.c b/src/pk/ecc/ecc_rfc6979_key.c index f2bf9db71..1f313bd34 100644 --- a/src/pk/ecc/ecc_rfc6979_key.c +++ b/src/pk/ecc/ecc_rfc6979_key.c @@ -19,7 +19,7 @@ @param key [out] Newly created deterministic key @return CRYPT_OK if successful, upon error all allocated memory will be freed */ -int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, ecc_key *key) +int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long inlen, const char *rfc6979_hash_alg, ecc_key *key) { int err, hash = -1; unsigned char v[MAXBLOCKSIZE], k[MAXBLOCKSIZE]; @@ -32,10 +32,10 @@ int ecc_rfc6979_key(const ecc_key *priv, const unsigned char *in, unsigned long LTC_ARGCHK(key != NULL); LTC_ARGCHK(key->dp.size > 0); - if (priv->rfc6979_hash_alg == NULL) { + if (rfc6979_hash_alg == NULL) { return CRYPT_INVALID_ARG; } - hash = find_hash(priv->rfc6979_hash_alg); + hash = find_hash(rfc6979_hash_alg); if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } diff --git a/src/pk/ecc/ecc_set_curve.c b/src/pk/ecc/ecc_set_curve.c index ce9055a85..7947c6ebb 100644 --- a/src/pk/ecc/ecc_set_curve.c +++ b/src/pk/ecc/ecc_set_curve.c @@ -19,8 +19,6 @@ int ecc_set_curve(const ltc_ecc_curve *cu, ecc_key *key) return err; } - key->rfc6979_hash_alg = NULL; - /* A, B, order, prime, Gx, Gy */ if ((err = ltc_mp_read_radix(key->dp.prime, cu->prime, 16)) != CRYPT_OK) { goto error; } if ((err = ltc_mp_read_radix(key->dp.order, cu->order, 16)) != CRYPT_OK) { goto error; } diff --git a/src/pk/ecc/ecc_set_key.c b/src/pk/ecc/ecc_set_key.c index b7204b841..df8e7b137 100644 --- a/src/pk/ecc/ecc_set_key.c +++ b/src/pk/ecc/ecc_set_key.c @@ -46,7 +46,6 @@ int ecc_set_key(const unsigned char *in, unsigned long inlen, int type, ecc_key } key->type = type; - key->rfc6979_hash_alg = NULL; return CRYPT_OK; error: diff --git a/src/pk/ecc/ecc_sign_hash.c b/src/pk/ecc/ecc_sign_hash.c index c9c278b31..97023ac80 100644 --- a/src/pk/ecc/ecc_sign_hash.c +++ b/src/pk/ecc/ecc_sign_hash.c @@ -3,7 +3,25 @@ #include "tomcrypt_private.h" -#if defined(LTC_MECC) && defined(LTC_DER) +#if defined(LTC_MECC) + +typedef int (*ecc_sign_fn)(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + ltc_ecc_sig_opts *opts, + const ecc_key *key); + +static const ecc_sign_fn s_ecc_sign_hash[] = { +#ifdef LTC_DER + [LTC_ECCSIG_ANSIX962] = ecc_sign_hash_x962, +#endif + [LTC_ECCSIG_RFC7518] = ecc_sign_hash_rfc7518_internal, + [LTC_ECCSIG_ETH27] = ecc_sign_hash_eth27, +#ifdef LTC_SSH + [LTC_ECCSIG_RFC5656] = ecc_sign_hash_rfc5656, +#endif +}; /** Sign a message digest (ANSI X9.62 format) @@ -11,32 +29,22 @@ @param inlen The length of the digest @param out [out] The destination for the signature @param outlen [in/out] The max size and resulting size of the signature - @param prng An active PRNG state - @param wprng The index of the PRNG you wish to use + @param opts The signature options that shall be applied @param key A private ECC key @return CRYPT_OK if successful */ -int ecc_sign_hash(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, const ecc_key *key) +int ecc_sign_hash_v2(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + ltc_ecc_sig_opts *opts, + const ecc_key *key) { - int err; - void *r, *s; - - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - if ((err = ltc_mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) return err; - if ((err = ecc_sign_hash_internal(in, inlen, r, s, prng, wprng, NULL, key)) != CRYPT_OK) goto error; - - /* store as ASN.1 SEQUENCE { r, s -- integer } */ - err = der_encode_sequence_multi(out, outlen, - LTC_ASN1_INTEGER, 1UL, r, - LTC_ASN1_INTEGER, 1UL, s, - LTC_ASN1_EOL, 0UL, NULL); -error: - ltc_mp_deinit_multi(r, s, LTC_NULL); - return err; + if (opts->type < 0 || opts->type >= LTC_ARRAY_SIZE(s_ecc_sign_hash)) + return CRYPT_PK_INVALID_TYPE; + if (s_ecc_sign_hash[opts->type] == NULL) + return CRYPT_PK_INVALID_TYPE; + return s_ecc_sign_hash[opts->type](in, inlen, out, outlen, opts, key); } #endif diff --git a/src/pk/ecc/ecc_sign_hash_eth27.c b/src/pk/ecc/ecc_sign_hash_eth27.c index dd06d14cb..4944d4527 100644 --- a/src/pk/ecc/ecc_sign_hash_eth27.c +++ b/src/pk/ecc/ecc_sign_hash_eth27.c @@ -11,14 +11,13 @@ @param inlen The length of the digest @param out [out] The destination for the signature @param outlen [in/out] The max size and resulting size of the signature - @param prng An active PRNG state - @param wprng The index of the PRNG you wish to use + @param opts The signature options that shall be applied @param key A private ECC key @return CRYPT_OK if successful */ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, const ecc_key *key) + ltc_ecc_sig_opts *opts, const ecc_key *key) { int err, recid; void *r, *s; @@ -26,6 +25,7 @@ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(opts != NULL); LTC_ARGCHK(key != NULL); /* Only valid for secp256k1 - OID 1.3.132.0.10 */ @@ -38,7 +38,9 @@ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, } if ((err = ltc_mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) return err; - if ((err = ecc_sign_hash_internal(in, inlen, r, s, prng, wprng, &recid, key)) != CRYPT_OK) goto error; + if (opts->recid == NULL) + opts->recid = &recid; + if ((err = ecc_sign_hash_internal(in, inlen, r, s, opts, key)) != CRYPT_OK) goto error; zeromem(out, 65); *outlen = 65; @@ -46,10 +48,12 @@ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, if ((err = ltc_mp_to_unsigned_bin(r, out + 32 - i)) != CRYPT_OK) goto error; i = ltc_mp_unsigned_bin_size(s); if ((err = ltc_mp_to_unsigned_bin(s, out + 64 - i)) != CRYPT_OK) goto error; - out[64] = (unsigned char)(recid + 27); /* Recovery ID is 27/28 for Ethereum */ + out[64] = (unsigned char)(*(opts->recid) + 27); /* Recovery ID is 27/28 for Ethereum */ err = CRYPT_OK; error: + if (opts->recid == &recid) + opts->recid = NULL; ltc_mp_deinit_multi(r, s, LTC_NULL); return err; } diff --git a/src/pk/ecc/ecc_sign_hash_internal.c b/src/pk/ecc/ecc_sign_hash_internal.c index 5321ddefb..9e2db46bc 100644 --- a/src/pk/ecc/ecc_sign_hash_internal.c +++ b/src/pk/ecc/ecc_sign_hash_internal.c @@ -6,8 +6,7 @@ #ifdef LTC_MECC int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, - void *r, void *s, prng_state *prng, int wprng, - int *recid, const ecc_key *key) + void *r, void *s, ltc_ecc_sig_opts *opts, const ecc_key *key) { ecc_key pubkey; void *e, *p, *b; @@ -19,6 +18,7 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, LTC_ARGCHK(r != NULL); LTC_ARGCHK(s != NULL); LTC_ARGCHK(in != NULL); + LTC_ARGCHK(opts != NULL); LTC_ARGCHK(key != NULL); /* is this a private key? */ @@ -58,16 +58,16 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, /* make up a key and export the public copy */ do { if ((err = ecc_copy_curve(key, &pubkey)) != CRYPT_OK) { goto errnokey; } - if (key->rfc6979_hash_alg != NULL) { - if ((err = ecc_rfc6979_key(key, in, inlen, &pubkey)) != CRYPT_OK) { goto errnokey; } + if (opts->rfc6979_hash_alg != NULL) { + if ((err = ecc_rfc6979_key(key, in, inlen, opts->rfc6979_hash_alg, &pubkey)) != CRYPT_OK) { goto errnokey; } } else { - if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { goto errnokey; } + if ((err = ecc_generate_key(opts->prng, opts->wprng, &pubkey)) != CRYPT_OK) { goto errnokey; } } /* find r = x1 mod n */ if ((err = ltc_mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } - if (recid) { + if (opts->recid) { /* find recovery ID (if needed) */ v = 0; if (ltc_mp_copy(pubkey.pubkey.x, s) != CRYPT_OK) { goto error; } @@ -82,7 +82,7 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, if (ltc_mp_iszero(r) == LTC_MP_YES) { ecc_free(&pubkey); } else { - if ((err = rand_bn_upto(b, p, prng, wprng)) != CRYPT_OK) { goto error; } /* b = blinding value */ + if ((err = rand_bn_upto(b, p, opts->prng, opts->wprng)) != CRYPT_OK) { goto error; } /* b = blinding value */ /* find s = (e + xr)/k */ if ((err = ltc_mp_mulmod(pubkey.k, b, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = kb */ if ((err = ltc_mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/kb */ @@ -102,7 +102,7 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, goto errnokey; } - if (recid) *recid = v; + if (opts->recid) *opts->recid = v; goto errnokey; error: diff --git a/src/pk/ecc/ecc_sign_hash_rfc5656.c b/src/pk/ecc/ecc_sign_hash_rfc5656.c index fd9f10e24..1330004ca 100644 --- a/src/pk/ecc/ecc_sign_hash_rfc5656.c +++ b/src/pk/ecc/ecc_sign_hash_rfc5656.c @@ -11,14 +11,13 @@ @param inlen The length of the digest @param out [out] The destination for the signature @param outlen [in/out] The max size and resulting size of the signature - @param prng An active PRNG state - @param wprng The index of the PRNG you wish to use + @param opts The signature options that shall be applied @param key A private ECC key @return CRYPT_OK if successful */ int ecc_sign_hash_rfc5656(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, const ecc_key *key) + ltc_ecc_sig_opts *opts, const ecc_key *key) { int err; void *r, *s; @@ -32,7 +31,7 @@ int ecc_sign_hash_rfc5656(const unsigned char *in, unsigned long inlen, if ((err = ecc_ssh_ecdsa_encode_name(name, &namelen, key)) != CRYPT_OK) return err; if ((err = ltc_mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) return err; - if ((err = ecc_sign_hash_internal(in, inlen, r, s, prng, wprng, NULL, key)) != CRYPT_OK) goto error; + if ((err = ecc_sign_hash_internal(in, inlen, r, s, opts, key)) != CRYPT_OK) goto error; /* Store as SSH data sequence, per RFC4251 */ err = ssh_encode_sequence_multi(out, outlen, diff --git a/src/pk/ecc/ecc_sign_hash_rfc7518.c b/src/pk/ecc/ecc_sign_hash_rfc7518.c index 1faefca15..a28f0c36c 100644 --- a/src/pk/ecc/ecc_sign_hash_rfc7518.c +++ b/src/pk/ecc/ecc_sign_hash_rfc7518.c @@ -11,16 +11,13 @@ @param inlen The length of the digest @param out [out] The destination for the signature @param outlen [in/out] The max size and resulting size of the signature - @param prng An active PRNG state - @param wprng The index of the PRNG you wish to use - @param recid [out] Recovery ID + @param opts The signature options that shall be applied @param key A private ECC key @return CRYPT_OK if successful */ -int ecc_sign_hash_rfc7518_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, - int *recid, const ecc_key *key) +int ecc_sign_hash_rfc7518_internal(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_ecc_sig_opts *opts, const ecc_key *key) { int err; void *r, *s; @@ -38,7 +35,7 @@ int ecc_sign_hash_rfc7518_ex(const unsigned char *in, unsigned long inlen, } if ((err = ltc_mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) return err; - if ((err = ecc_sign_hash_internal(in, inlen, r, s, prng, wprng, recid, key)) != CRYPT_OK) goto error; + if ((err = ecc_sign_hash_internal(in, inlen, r, s, opts, key)) != CRYPT_OK) goto error; zeromem(out, 2 * pbytes); *outlen = 2 * pbytes; @@ -52,22 +49,4 @@ int ecc_sign_hash_rfc7518_ex(const unsigned char *in, unsigned long inlen, return err; } -/** - Sign a message digest (RFC7518 format) - @param in The message digest to sign - @param inlen The length of the digest - @param out [out] The destination for the signature - @param outlen [in/out] The max size and resulting size of the signature - @param prng An active PRNG state - @param wprng The index of the PRNG you wish to use - @param key A private ECC key - @return CRYPT_OK if successful -*/ -int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, const ecc_key *key) -{ - return ecc_sign_hash_rfc7518_ex(in, inlen, out, outlen, prng, wprng, NULL, key); -} - #endif diff --git a/src/pk/ecc/ecc_sign_hash_x962.c b/src/pk/ecc/ecc_sign_hash_x962.c new file mode 100644 index 000000000..8bf20fad6 --- /dev/null +++ b/src/pk/ecc/ecc_sign_hash_x962.c @@ -0,0 +1,44 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include "tomcrypt_private.h" + +#if defined(LTC_MECC) && defined(LTC_DER) + +/** + Sign a message digest (ANSI X9.62 format) + @param in The message digest to sign + @param inlen The length of the digest + @param out [out] The destination for the signature + @param outlen [in/out] The max size and resulting size of the signature + @param opts The signature options that shall be applied + @param key A private ECC key + @return CRYPT_OK if successful +*/ +int ecc_sign_hash_x962(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + ltc_ecc_sig_opts *opts, + const ecc_key *key) +{ + int err; + void *r, *s; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if ((err = ltc_mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) return err; + if ((err = ecc_sign_hash_internal(in, inlen, r, s, opts, key)) != CRYPT_OK) goto error; + + /* store as ASN.1 SEQUENCE { r, s -- integer } */ + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL); +error: + ltc_mp_deinit_multi(r, s, LTC_NULL); + return err; +} + +#endif diff --git a/src/pk/ecc/ecc_verify_hash.c b/src/pk/ecc/ecc_verify_hash.c index 494c474e2..14ca74535 100644 --- a/src/pk/ecc/ecc_verify_hash.c +++ b/src/pk/ecc/ecc_verify_hash.c @@ -10,8 +10,26 @@ ECC Crypto, Tom St Denis */ +typedef int (*ecc_verify_fn)(const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + int *stat, + const ecc_key *key); + +static const ecc_verify_fn s_ecc_verify_hash[] = { +#ifdef LTC_DER + [LTC_ECCSIG_ANSIX962] = ecc_verify_hash_x962, +#endif + [LTC_ECCSIG_RFC7518] = ecc_verify_hash_rfc7518_internal, + [LTC_ECCSIG_ETH27] = ecc_verify_hash_eth27, +#ifdef LTC_SSH + [LTC_ECCSIG_RFC5656] = ecc_verify_hash_rfc5656, +#endif +}; + /** - Verify an ECC signature (ANSI X9.62 format) + Verify an ECC signature @param sig The signature to verify @param siglen The length of the signature (octets) @param hash The hash (message digest) that was signed @@ -20,28 +38,19 @@ @param key The corresponding public ECC key @return CRYPT_OK if successful (even if the signature is not valid) */ -int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, const ecc_key *key) +int ecc_verify_hash_v2(const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + ltc_ecc_sig_opts *opts, + int *stat, + const ecc_key *key) { - void *r, *s; - int err; - - LTC_ARGCHK(sig != NULL); - - if ((err = ltc_mp_init_multi(&r, &s, NULL)) != CRYPT_OK) return err; - - /* ANSI X9.62 format - ASN.1 encoded SEQUENCE{ INTEGER(r), INTEGER(s) } */ - if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT, - LTC_ASN1_INTEGER, 1UL, r, - LTC_ASN1_INTEGER, 1UL, s, - LTC_ASN1_EOL, 0UL, LTC_NULL)) != CRYPT_OK) { goto error; } - - err = ecc_verify_hash_internal(r, s, hash, hashlen, stat, key); - -error: - ltc_mp_deinit_multi(r, s, LTC_NULL); - return err; + if (opts->type < 0 || opts->type >= LTC_ARRAY_SIZE(s_ecc_verify_hash)) + return CRYPT_PK_INVALID_TYPE; + if (s_ecc_verify_hash[opts->type] == NULL) + return CRYPT_PK_INVALID_TYPE; + return s_ecc_verify_hash[opts->type](sig, siglen, hash, hashlen, stat, key); } #endif diff --git a/src/pk/ecc/ecc_verify_hash_eth27.c b/src/pk/ecc/ecc_verify_hash_eth27.c index 587ecd2da..4f6394f7f 100644 --- a/src/pk/ecc/ecc_verify_hash_eth27.c +++ b/src/pk/ecc/ecc_verify_hash_eth27.c @@ -6,7 +6,7 @@ #ifdef LTC_MECC /** - @file ecc_verify_hash.c + @file ecc_verify_hash_eth27.c ECC Crypto, Tom St Denis */ diff --git a/src/pk/ecc/ecc_verify_hash_rfc7518.c b/src/pk/ecc/ecc_verify_hash_rfc7518.c index b048bdc20..ce2aa673f 100644 --- a/src/pk/ecc/ecc_verify_hash_rfc7518.c +++ b/src/pk/ecc/ecc_verify_hash_rfc7518.c @@ -6,21 +6,11 @@ #ifdef LTC_MECC /** - @file ecc_verify_hash.c + @file ecc_verify_hash_rfc7518.c ECC Crypto, Tom St Denis */ -/** - Verify an ECC signature (RFC7518 format) - @param sig The signature to verify - @param siglen The length of the signature (octets) - @param hash The hash (message digest) that was signed - @param hashlen The length of the hash (octets) - @param stat [out] Result of signature, 1==valid, 0==invalid - @param key The corresponding public ECC key - @return CRYPT_OK if successful (even if the signature is not valid) -*/ -int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, +int ecc_verify_hash_rfc7518_internal(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, const ecc_key *key) { diff --git a/src/pk/ecc/ecc_verify_hash_x962.c b/src/pk/ecc/ecc_verify_hash_x962.c new file mode 100644 index 000000000..d82b16347 --- /dev/null +++ b/src/pk/ecc/ecc_verify_hash_x962.c @@ -0,0 +1,37 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include "tomcrypt_private.h" + +#if defined(LTC_MECC) && defined(LTC_DER) + +/** + @file ecc_verify_hash_x962.c + ECC Crypto, Tom St Denis +*/ + +int ecc_verify_hash_x962(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, const ecc_key *key) +{ + void *r, *s; + int err; + + LTC_ARGCHK(sig != NULL); + + if ((err = ltc_mp_init_multi(&r, &s, NULL)) != CRYPT_OK) return err; + + /* ANSI X9.62 format - ASN.1 encoded SEQUENCE{ INTEGER(r), INTEGER(s) } */ + if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, LTC_NULL)) != CRYPT_OK) { goto error; } + + err = ecc_verify_hash_internal(r, s, hash, hashlen, stat, key); + +error: + ltc_mp_deinit_multi(r, s, LTC_NULL); + return err; +} + +#endif diff --git a/src/pk/pka_key.c b/src/pk/pka_key.c index d88ee3d30..c682cfcbf 100644 --- a/src/pk/pka_key.c +++ b/src/pk/pka_key.c @@ -30,6 +30,7 @@ void pka_key_free(ltc_pka_key *key) #endif break; case LTC_PKA_RSA: + case LTC_PKA_RSA_PSS: #if defined(LTC_MRSA) rsa_free(&key->u.rsa); #endif diff --git a/src/pk/pkcs1/pkcs_1_oaep_decode.c b/src/pk/pkcs1/pkcs_1_oaep_decode.c index 14519c1ea..a877b6232 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_decode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_decode.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" /** @@ -8,7 +9,6 @@ */ #ifdef LTC_PKCS_1 - /** PKCS #1 v2.00 OAEP decode @param msg The encoded data to decode @@ -23,38 +23,30 @@ @param res [out] Result of decoding, 1==valid, 0==invalid @return CRYPT_OK if successful */ -int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, - const unsigned char *lparam, unsigned long lparamlen, - unsigned long modulus_bitlen, - int mgf_hash, int lparam_hash, - unsigned char *out, unsigned long *outlen, - int *res) +int ltc_pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + unsigned long modulus_bitlen, + ltc_rsa_op_parameters *params, + unsigned char *out, unsigned long *outlen, + int *res) { unsigned char *DB, *seed, *mask; unsigned long hLen, x, y, modulus_len; - int err, ret, lparam_hash_used; + int err, ret; + ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); LTC_ARGCHK(msg != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(res != NULL); + if ((err = rsa_key_valid_op(LTC_PKCS1_DECRYPT, &op_checked)) != CRYPT_OK) { + return err; + } + /* default to invalid packet */ *res = 0; - /* test valid hash */ - if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) { - return err; - } - if (lparam_hash != -1) { - if ((err = hash_is_valid(lparam_hash)) != CRYPT_OK) { - return err; - } - lparam_hash_used = lparam_hash; - } else { - lparam_hash_used = mgf_hash; - } - hLen = hash_descriptor[lparam_hash_used].hashsize; + hLen = hash_descriptor[op_checked.hash_alg].hashsize; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); /* test hash/message size */ @@ -104,7 +96,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, x += modulus_len - hLen - 1; /* compute MGF1 of maskedDB (hLen) */ - if ((err = pkcs_1_mgf1(mgf_hash, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { + if ((err = pkcs_1_mgf1(op_checked.mgf1_hash_alg, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { goto LBL_ERR; } @@ -114,7 +106,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, } /* compute MGF1 of seed (k - hlen - 1) */ - if ((err = pkcs_1_mgf1(mgf_hash, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + if ((err = pkcs_1_mgf1(op_checked.mgf1_hash_alg, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } @@ -127,13 +119,13 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, /* compute lhash and store it in seed [reuse temps!] */ x = modulus_len; - if (lparam != NULL) { - if ((err = hash_memory(lparam_hash_used, lparam, lparamlen, seed, &x)) != CRYPT_OK) { + if (op_checked.params->u.crypt.lparam != NULL) { + if ((err = hash_memory(op_checked.hash_alg, op_checked.params->u.crypt.lparam, op_checked.params->u.crypt.lparamlen, seed, &x)) != CRYPT_OK) { goto LBL_ERR; } } else { /* can't pass hash_memory a NULL so use DB with zero length */ - if ((err = hash_memory(lparam_hash_used, DB, 0, seed, &x)) != CRYPT_OK) { + if ((err = hash_memory(op_checked.hash_alg, DB, 0, seed, &x)) != CRYPT_OK) { goto LBL_ERR; } } diff --git a/src/pk/pkcs1/pkcs_1_oaep_encode.c b/src/pk/pkcs1/pkcs_1_oaep_encode.c index 45aa5ce5c..f5ee5010b 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_encode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_encode.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" /** @@ -8,55 +9,35 @@ */ #ifdef LTC_PKCS_1 - /** PKCS #1 v2.00 OAEP encode @param msg The data to encode @param msglen The length of the data to encode (octets) - @param lparam A session or system parameter (can be NULL) - @param lparamlen The length of the lparam data @param modulus_bitlen The bit length of the RSA modulus - @param prng An active PRNG state - @param prng_idx The index of the PRNG desired - @param hash_idx The index of the hash desired + @param params The PKCS#1 operation's parameters @param out [out] The destination for the encoded data @param outlen [in/out] The max size and resulting size of the encoded data @return CRYPT_OK if successful */ -int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, - const unsigned char *lparam, unsigned long lparamlen, - unsigned long modulus_bitlen, prng_state *prng, - int prng_idx, - int mgf_hash, int lparam_hash, - unsigned char *out, unsigned long *outlen) +int ltc_pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + unsigned long modulus_bitlen, + ltc_rsa_op_parameters *params, + unsigned char *out, unsigned long *outlen) { unsigned char *DB, *seed, *mask; unsigned long hLen, x, y, modulus_len; - int err, lparam_hash_used; + int err; + ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); LTC_ARGCHK((msglen == 0) || (msg != NULL)); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - /* test valid hash */ - if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) { - return err; - } - if (lparam_hash != -1) { - if ((err = hash_is_valid(lparam_hash)) != CRYPT_OK) { - return err; - } - lparam_hash_used = lparam_hash; - } else { - lparam_hash_used = mgf_hash; - } - - /* valid prng */ - if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + if ((err = rsa_key_valid_op(LTC_PKCS1_ENCRYPT, &op_checked)) != CRYPT_OK) { return err; } - hLen = hash_descriptor[lparam_hash_used].hashsize; + hLen = hash_descriptor[op_checked.hash_alg].hashsize; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); /* test message size */ @@ -84,13 +65,13 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, /* get lhash */ /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ x = modulus_len; - if (lparam != NULL) { - if ((err = hash_memory(lparam_hash_used, lparam, lparamlen, DB, &x)) != CRYPT_OK) { + if (op_checked.params->u.crypt.lparam != NULL) { + if ((err = hash_memory(op_checked.hash_alg, op_checked.params->u.crypt.lparam, op_checked.params->u.crypt.lparamlen, DB, &x)) != CRYPT_OK) { goto LBL_ERR; } } else { /* can't pass hash_memory a NULL so use `out` with zero length */ - if ((err = hash_memory(lparam_hash_used, out, 0, DB, &x)) != CRYPT_OK) { + if ((err = hash_memory(op_checked.hash_alg, out, 0, DB, &x)) != CRYPT_OK) { goto LBL_ERR; } } @@ -111,13 +92,13 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, } /* now choose a random seed */ - if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) { + if (prng_descriptor[op_checked.params->wprng].read(seed, hLen, op_checked.params->prng) != hLen) { err = CRYPT_ERROR_READPRNG; goto LBL_ERR; } /* compute MGF1 of seed (k - hlen - 1) */ - if ((err = pkcs_1_mgf1(mgf_hash, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + if ((err = pkcs_1_mgf1(op_checked.mgf1_hash_alg, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } @@ -127,7 +108,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, } /* compute MGF1 of maskedDB (hLen) */ - if ((err = pkcs_1_mgf1(mgf_hash, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { + if ((err = pkcs_1_mgf1(op_checked.mgf1_hash_alg, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/pk/pkcs1/pkcs_1_pss_decode.c b/src/pk/pkcs1/pkcs_1_pss_decode.c index fad401d1b..69c45dc8e 100644 --- a/src/pk/pkcs1/pkcs_1_pss_decode.c +++ b/src/pk/pkcs1/pkcs_1_pss_decode.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" /** @@ -10,39 +11,41 @@ #ifdef LTC_PKCS_1 /** - PKCS #1 v2.00 PSS decode + PKCS #1 v2.00 Signature Verification @param msghash The hash to verify @param msghashlen The length of the hash (octets) @param sig The signature data (encoded data) @param siglen The length of the signature data (octets) - @param saltlen The length of the salt used (octets) - @param hash_idx The index of the hash desired + @param params The PKCS#1 operation's parameters @param modulus_bitlen The bit length of the RSA modulus @param res [out] The result of the comparison, 1==valid, 0==invalid @return CRYPT_OK if successful (even if the comparison failed) */ -int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, - const unsigned char *sig, unsigned long siglen, - unsigned long saltlen, int hash_idx, - unsigned long modulus_bitlen, int *res) +int ltc_pkcs_1_pss_decode_mgf1(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, int *res) { unsigned char *DB, *mask, *salt, *hash; - unsigned long x, y, hLen, modulus_len; + unsigned long x, y, hLen, modulus_len, saltlen; int err; hash_state md; + ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(params != NULL); LTC_ARGCHK(res != NULL); /* default to invalid */ *res = 0; - /* ensure hash is valid */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + if ((err = rsa_key_valid_op(LTC_PKCS1_VERIFY, &op_checked)) != CRYPT_OK) { return err; } - hLen = hash_descriptor[hash_idx].hashsize; + hLen = hash_descriptor[op_checked.hash_alg].hashsize; + saltlen = params->params.saltlen; modulus_bitlen--; modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); @@ -95,7 +98,7 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, } /* generate mask of length modulus_len - hLen - 1 from hash */ - if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + if ((err = pkcs_1_mgf1(op_checked.mgf1_hash_alg, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } @@ -124,20 +127,20 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, } /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ - if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].init(&md)) != CRYPT_OK) { goto LBL_ERR; } zeromem(mask, 8); - if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, mask, 8)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, msghash, msghashlen)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, DB+x, saltlen)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].done(&md, mask)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/pk/pkcs1/pkcs_1_pss_encode.c b/src/pk/pkcs1/pkcs_1_pss_encode.c index 2a4e3728a..95c8fe410 100644 --- a/src/pk/pkcs1/pkcs_1_pss_encode.c +++ b/src/pk/pkcs1/pkcs_1_pss_encode.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" /** @@ -13,39 +14,34 @@ PKCS #1 v2.00 Signature Encoding @param msghash The hash to encode @param msghashlen The length of the hash (octets) - @param saltlen The length of the salt desired (octets) - @param prng An active PRNG context - @param prng_idx The index of the PRNG desired - @param hash_idx The index of the hash desired + @param params The PKCS#1 operation's parameters @param modulus_bitlen The bit length of the RSA modulus @param out [out] The destination of the encoding @param outlen [in/out] The max size and resulting size of the encoded data @return CRYPT_OK if successful */ -int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, - unsigned long saltlen, prng_state *prng, - int prng_idx, int hash_idx, - unsigned long modulus_bitlen, - unsigned char *out, unsigned long *outlen) +int ltc_pkcs_1_pss_encode_mgf1(const unsigned char *msghash, unsigned long msghashlen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen) { unsigned char *DB, *mask, *salt, *hash; - unsigned long x, y, hLen, modulus_len; + unsigned long x, y, hLen, modulus_len, saltlen; int err; hash_state md; + ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(params != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - /* ensure hash and PRNG are valid */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + if ((err = rsa_key_valid_op(LTC_PKCS1_SIGN, &op_checked)) != CRYPT_OK) { return err; } - hLen = hash_descriptor[hash_idx].hashsize; + hLen = hash_descriptor[op_checked.hash_alg].hashsize; + saltlen = params->params.saltlen; modulus_bitlen--; modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); @@ -78,27 +74,27 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, /* generate random salt */ if (saltlen > 0) { - if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) { + if (prng_descriptor[params->wprng].read(salt, saltlen, params->prng) != saltlen) { err = CRYPT_ERROR_READPRNG; goto LBL_ERR; } } /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ - if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].init(&md)) != CRYPT_OK) { goto LBL_ERR; } zeromem(DB, 8); - if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, DB, 8)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, msghash, msghashlen)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].process(&md, salt, saltlen)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, salt, saltlen)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].done(&md, hash)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].done(&md, hash)) != CRYPT_OK) { goto LBL_ERR; } @@ -111,7 +107,7 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, /* x += saltlen; */ /* generate mask of length modulus_len - hLen - 1 from hash */ - if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + if ((err = pkcs_1_mgf1(op_checked.mgf1_hash_alg, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/pk/rsa/rsa_decrypt_key.c b/src/pk/rsa/rsa_decrypt_key.c index d8e7a546f..d61f25b65 100644 --- a/src/pk/rsa/rsa_decrypt_key.c +++ b/src/pk/rsa/rsa_decrypt_key.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" /** @@ -8,53 +9,38 @@ */ #ifdef LTC_MRSA - /** - PKCS #1 decrypt then v1.5 or OAEP depad + Decrypt then (PKCS #1 v2.0) OAEP or (PKCS #1 v1.5) EME depad @param in The ciphertext @param inlen The length of the ciphertext (octets) @param out [out] The plaintext @param outlen [in/out] The max size and resulting size of the plaintext (octets) - @param lparam The system "lparam" value - @param lparamlen The length of the lparam value (octets) - @param mgf_hash The hash algorithm used for the MGF - @param lparam_hash The hash algorithm used when hashing the lparam (can be -1) - @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) + @param params The RSA operation's parameters @param stat [out] Result of the decryption, 1==valid, 0==invalid @param key The corresponding private RSA key @return CRYPT_OK if succcessul (even if invalid) */ -int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, +int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - int mgf_hash, int lparam_hash, - int padding, + ltc_rsa_op_parameters *params, int *stat, const rsa_key *key) { - unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmp; + unsigned long modulus_bitlen, modulus_bytelen, x; + ltc_rsa_op_checked op_checked = ltc_rsa_op_checked_init(key, params); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); LTC_ARGCHK(stat != NULL); /* default to invalid */ *stat = 0; /* valid padding? */ - if ((padding != LTC_PKCS_1_V1_5) && - (padding != LTC_PKCS_1_OAEP)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding == LTC_PKCS_1_OAEP) { - /* valid hash ? */ - if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) { - return err; - } + if ((err = rsa_key_valid_op(LTC_RSA_DECRYPT, &op_checked)) != CRYPT_OK) { + return err; } /* get modulus len in bits */ @@ -72,17 +58,16 @@ int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen return CRYPT_MEM; } - /* rsa decode the packet */ + /* rsa exptmod the packet */ x = inlen; if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { XFREE(tmp); return err; } - if (padding == LTC_PKCS_1_OAEP) { - /* now OAEP decode the packet */ - err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, mgf_hash, - lparam_hash, out, outlen, stat); + if (params->padding == LTC_PKCS_1_OAEP) { + /* now OAEP depad the packet */ + err = ltc_pkcs_1_oaep_decode(tmp, x, modulus_bitlen, params, out, outlen, stat); } else { /* now PKCS #1 v1.5 depad the packet */ err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat); diff --git a/src/pk/rsa/rsa_encrypt_key.c b/src/pk/rsa/rsa_encrypt_key.c index 17dd1af5d..ad0bd7ac0 100644 --- a/src/pk/rsa/rsa_encrypt_key.c +++ b/src/pk/rsa/rsa_encrypt_key.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" /** @@ -8,54 +9,31 @@ */ #ifdef LTC_MRSA - /** - (PKCS #1 v2.0) OAEP pad then encrypt - @param in The plaintext - @param inlen The length of the plaintext (octets) - @param out [out] The ciphertext - @param outlen [in/out] The max size and resulting size of the ciphertext - @param lparam The system "lparam" for the encryption - @param lparamlen The length of lparam (octets) - @param prng An active PRNG - @param prng_idx The index of the desired prng - @param hash_idx The index of the desired hash - @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) - @param key The RSA key to encrypt to - @return CRYPT_OK if successful + (PKCS #1 v2.0) OAEP or (PKCS #1 v1.5) EME pad then encrypt + @param in The plaintext + @param inlen The length of the plaintext (octets) + @param out [out] The ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param params The RSA operation's parameters + @param key The RSA key to encrypt to + @return CRYPT_OK if successful */ -int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - prng_state *prng, int prng_idx, - int mgf_hash, int lparam_hash, - int padding, - const rsa_key *key) +int rsa_encrypt_key_v2(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_rsa_op_parameters *params, + const rsa_key *key) { - unsigned long modulus_bitlen, modulus_bytelen, x; int err; + unsigned long modulus_bitlen, modulus_bytelen, x; + ltc_rsa_op_checked op_checked = ltc_rsa_op_checked_init(key, params); LTC_ARGCHK((inlen == 0) || (in != NULL)); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); - - /* valid padding? */ - if ((padding != LTC_PKCS_1_V1_5) && - (padding != LTC_PKCS_1_OAEP)) { - return CRYPT_PK_INVALID_PADDING; - } - /* valid prng? */ - if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { - return err; - } - - if (padding == LTC_PKCS_1_OAEP) { - /* valid hash? */ - if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) { - return err; - } + if ((err = rsa_key_valid_op(LTC_RSA_ENCRYPT, &op_checked)) != CRYPT_OK) { + return err; } /* get modulus len in bits */ @@ -68,19 +46,17 @@ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, return CRYPT_BUFFER_OVERFLOW; } - if (padding == LTC_PKCS_1_OAEP) { + if (params->padding == LTC_PKCS_1_OAEP) { /* OAEP pad the key */ x = *outlen; - if ((err = pkcs_1_oaep_encode(in, inlen, lparam, - lparamlen, modulus_bitlen, prng, prng_idx, mgf_hash, - lparam_hash, out, &x)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_oaep_encode(in, inlen, modulus_bitlen, params, out, &x)) != CRYPT_OK) { return err; } } else { /* PKCS #1 v1.5 pad the key */ x = *outlen; if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_PKCS_1_EME, - modulus_bitlen, prng, prng_idx, + modulus_bitlen, params->prng, params->wprng, out, &x)) != CRYPT_OK) { return err; } diff --git a/src/pk/rsa/rsa_import.c b/src/pk/rsa/rsa_import.c index 1240a77e7..bc201ad97 100644 --- a/src/pk/rsa/rsa_import.c +++ b/src/pk/rsa/rsa_import.c @@ -9,6 +9,18 @@ #ifdef LTC_MRSA +#ifndef S_RSA_DECODE +#define S_RSA_DECODE +static int s_rsa_decode(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + /* now it should be SEQUENCE { INTEGER, INTEGER } */ + return der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL); +} +#endif + /** Import an RSAPublicKey or RSAPrivateKey as defined in PKCS #1 v2.1 [two-prime only] @@ -33,10 +45,7 @@ int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key) /* the version would fit into an LTC_ASN1_SHORT_INTEGER * so we try to decode as a public key */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) { + if ((err = s_rsa_decode(in, inlen, key)) == CRYPT_OK) { key->type = PK_PUBLIC; } goto LBL_OUT; @@ -85,57 +94,25 @@ int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key) int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) { int err; - unsigned char *tmpbuf=NULL; - unsigned long tmpbuf_len, len; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); + /* SubjectPublicKeyInfo or X.509 certificate format */ + if (rsa_import_x509(in, inlen, key) == CRYPT_OK) { + return CRYPT_OK; + } + /* init key */ if ((err = rsa_init(key)) != CRYPT_OK) { return err; } - - /* see if the OpenSSL DER format RSA public key will work */ - tmpbuf_len = inlen; - tmpbuf = XCALLOC(1, tmpbuf_len); - if (tmpbuf == NULL) { - err = CRYPT_MEM; - goto LBL_ERR; - } - - len = 0; - err = x509_decode_subject_public_key_info(in, inlen, - LTC_OID_RSA, tmpbuf, &tmpbuf_len, - LTC_ASN1_NULL, NULL, &len); - - if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ - - /* now it should be SEQUENCE { INTEGER, INTEGER } */ - if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto LBL_ERR; - } - key->type = PK_PUBLIC; - err = CRYPT_OK; - goto LBL_FREE; + /* Try to match against PKCS #1 standards */ + if ((err = rsa_import_pkcs1(in, inlen, key)) != CRYPT_OK) { + rsa_free(key); } - /* not SSL public key, try to match against PKCS #1 standards */ - if ((err = rsa_import_pkcs1(in, inlen, key)) == CRYPT_OK) { - goto LBL_FREE; - } - -LBL_ERR: - rsa_free(key); - -LBL_FREE: - if (tmpbuf != NULL) { - XFREE(tmpbuf); - } return err; } diff --git a/src/pk/rsa/rsa_import_x509.c b/src/pk/rsa/rsa_import_x509.c index 4d157ead4..6ebe55669 100644 --- a/src/pk/rsa/rsa_import_x509.c +++ b/src/pk/rsa/rsa_import_x509.c @@ -9,6 +9,8 @@ #ifdef LTC_MRSA +#ifndef S_RSA_DECODE +#define S_RSA_DECODE static int s_rsa_decode(const unsigned char *in, unsigned long inlen, rsa_key *key) { /* now it should be SEQUENCE { INTEGER, INTEGER } */ @@ -17,6 +19,201 @@ static int s_rsa_decode(const unsigned char *in, unsigned long inlen, rsa_key *k LTC_ASN1_INTEGER, 1UL, key->e, LTC_ASN1_EOL, 0UL, NULL); } +#endif + +typedef struct rsa_pss_parameters_data { + ltc_asn1_list params[4], inner[4], hash_alg[2], mgf[2], mgf_hash_alg[2]; + unsigned long hash_alg_oid[LTC_DER_OID_DEFAULT_NODES]; + unsigned long mgf_alg_oid[LTC_DER_OID_DEFAULT_NODES]; + unsigned long mgf1_hash_alg_oid[LTC_DER_OID_DEFAULT_NODES]; + unsigned long salt_length, trailer_field; +} rsa_pss_parameters_data; + +static LTC_INLINE void s_rsa_pss_parameters_data_setup(rsa_pss_parameters_data *d) +{ + unsigned long n; + /* RSASSA-PSS + * + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm DEFAULT sha1, + * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, + * saltLength [2] INTEGER DEFAULT 20, + * trailerField [3] TrailerField DEFAULT trailerFieldBC + * } + */ + + /* HashAlgorithm ::= AlgorithmIdentifier { + * {OAEP-PSSDigestAlgorithms} + * } + */ + LTC_SET_ASN1(d->hash_alg, 0, LTC_ASN1_OBJECT_IDENTIFIER, d->hash_alg_oid, LTC_ARRAY_SIZE(d->hash_alg_oid)); + LTC_SET_ASN1(d->hash_alg, 1, LTC_ASN1_NULL, NULL, 0); + d->hash_alg[1].optional = 1; + + /* MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} } */ + LTC_SET_ASN1(d->mgf_hash_alg, 0, LTC_ASN1_OBJECT_IDENTIFIER, d->mgf1_hash_alg_oid, LTC_ARRAY_SIZE(d->mgf1_hash_alg_oid)); + LTC_SET_ASN1(d->mgf_hash_alg, 1, LTC_ASN1_NULL, NULL, 0); + d->mgf_hash_alg[1].optional = 1; + + /* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= { + * { OID id-mgf1 PARAMETERS HashAlgorithm }, + * ... -- Allows for future expansion -- + * } + */ + LTC_SET_ASN1(d->mgf, 0, LTC_ASN1_OBJECT_IDENTIFIER, d->mgf_alg_oid, LTC_ARRAY_SIZE(d->mgf_alg_oid)); + LTC_SET_ASN1(d->mgf, 1, LTC_ASN1_SEQUENCE, d->mgf_hash_alg, LTC_ARRAY_SIZE(d->mgf_hash_alg)); + + LTC_SET_ASN1(d->inner, 0, LTC_ASN1_SEQUENCE, d->hash_alg, LTC_ARRAY_SIZE(d->hash_alg)); + LTC_SET_ASN1(d->inner, 1, LTC_ASN1_SEQUENCE, d->mgf, LTC_ARRAY_SIZE(d->mgf)); + LTC_SET_ASN1(d->inner, 2, LTC_ASN1_SHORT_INTEGER, &d->salt_length, 1UL); + LTC_SET_ASN1(d->inner, 3, LTC_ASN1_SHORT_INTEGER, &d->trailer_field, 1UL); + + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(d->params, 0, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, d->inner); /* context specific 0 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(d->params, 1, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, d->inner + 1); /* context specific 1 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(d->params, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 2, d->inner + 2); /* context specific 2 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(d->params, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 3, d->inner + 3); /* context specific 3 */ + for (n = 0; n < 4; ++n) { + d->params[n].optional = 1; + } +} + +static int s_rsa_decode_parameters(const rsa_pss_parameters_data *d, ltc_rsa_parameters *rsa_params) +{ + unsigned long n; + enum ltc_oid_id oid_id; + int err, idx; + + rsa_params->saltlen = 20; + rsa_params->hash_alg = rsa_params->mgf1_hash_alg = "sha1"; + + for (n = 0; n < 4; ++n) { + if (d->params[n].used == 0) + continue; + switch (n) { + case 0: + idx = find_hash_oid(d->hash_alg->data, d->hash_alg->size); + if (idx == -1) { + return CRYPT_INVALID_HASH; + } + rsa_params->hash_alg = hash_descriptor[idx].name; + break; + case 1: + if ((err = pk_get_oid_from_asn1(&d->mgf[0], &oid_id)) != CRYPT_OK) { + return err; + } + if (oid_id != LTC_OID_RSA_MGF1) { + return CRYPT_PK_ASN1_ERROR; + } + idx = find_hash_oid(d->mgf_hash_alg->data, d->mgf_hash_alg->size); + if (idx == -1) { + return CRYPT_INVALID_HASH; + } + rsa_params->mgf1_hash_alg = hash_descriptor[idx].name; + break; + case 2: + rsa_params->saltlen = d->salt_length; + break; + case 3: + if (d->trailer_field != 1) { + return CRYPT_PK_ASN1_ERROR; + } + break; + default: + return CRYPT_PK_ASN1_ERROR; + } + } + + rsa_params->pss_oaep = 1; + + return CRYPT_OK; +} + +int rsa_decode_parameters(const ltc_asn1_list *parameters, ltc_rsa_parameters *rsa_params) +{ + int err; + rsa_pss_parameters_data d; + + s_rsa_pss_parameters_data_setup(&d); + + if ((err = der_decode_sequence(parameters->data, parameters->size, d.params, 4)) != CRYPT_OK) { + return err; + } + + return s_rsa_decode_parameters(&d, rsa_params); +} + +static LTC_INLINE int s_rsa_1_5_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + return x509_process_public_key_from_spki(in, inlen, + LTC_OID_RSA, + LTC_ASN1_NULL, NULL, NULL, + (public_key_decode_cb)s_rsa_decode, key); +} + +static LTC_INLINE int s_rsa_pss_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + rsa_pss_parameters_data d; + unsigned long n_params = LTC_ARRAY_SIZE(d.params); + + if (x509_process_public_key_from_spki(in, inlen, + LTC_OID_RSA_PSS, + LTC_ASN1_NULL, NULL, NULL, + (public_key_decode_cb)s_rsa_decode, key) == CRYPT_OK) { + return CRYPT_OK; + } + s_rsa_pss_parameters_data_setup(&d); + if ((err = x509_process_public_key_from_spki(in, inlen, + LTC_OID_RSA_PSS, + LTC_ASN1_SEQUENCE, d.params, &n_params, + (public_key_decode_cb)s_rsa_decode, key)) != CRYPT_OK) { + return err; + } + return s_rsa_decode_parameters(&d, &key->params); +} + +static LTC_INLINE int s_rsa_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + if (s_rsa_1_5_import_spki(in, inlen, key) == CRYPT_OK) { + return CRYPT_OK; + } + + if ((err = s_rsa_pss_import_spki(in, inlen, key)) == CRYPT_OK) { + return CRYPT_OK; + } + return err; +} + +/** + Import an RSA key from SubjectPublicKeyInfo + @param in The packet to import from + @param inlen It's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ +int rsa_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if ((err = rsa_init(key)) != CRYPT_OK) { + return err; + } + + if ((err = s_rsa_import_spki(in, inlen, key)) == CRYPT_OK) { + key->type = PK_PUBLIC; + return CRYPT_OK; + } + + rsa_free(key); + + return err; +} /** Import an RSA key from a X.509 certificate @@ -27,6 +224,8 @@ static int s_rsa_decode(const unsigned char *in, unsigned long inlen, rsa_key *k */ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) { + ltc_asn1_list *decoded_list; + const ltc_asn1_list *spki; int err; LTC_ARGCHK(in != NULL); @@ -38,16 +237,26 @@ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) return err; } - if ((err = x509_decode_public_key_from_certificate(in, inlen, - LTC_OID_RSA, - LTC_ASN1_NULL, NULL, NULL, - (public_key_decode_cb)s_rsa_decode, key)) != CRYPT_OK) { - rsa_free(key); - } else { + /* First try to decode as SubjectPublicKeyInfo */ + if (s_rsa_import_spki(in, inlen, key) == CRYPT_OK) { key->type = PK_PUBLIC; + return CRYPT_OK; } - return err; + /* Now try to extract the SubjectPublicKeyInfo from the Certificate */ + if ((err = x509_decode_spki(in, inlen, &decoded_list, &spki)) != CRYPT_OK) { + rsa_free(key); + return err; + } + err = s_rsa_import_spki(spki->data, spki->size, key); + + der_free_sequence_flexi(decoded_list); + if (err != CRYPT_OK) { + rsa_free(key); + return err; + } + key->type = PK_PUBLIC; + return CRYPT_OK; } #endif /* LTC_MRSA */ diff --git a/src/pk/rsa/rsa_key.c b/src/pk/rsa/rsa_key.c index 7eb21b843..1366d1667 100644 --- a/src/pk/rsa/rsa_key.c +++ b/src/pk/rsa/rsa_key.c @@ -85,6 +85,7 @@ void rsa_shrink_key(rsa_key *key) int rsa_init(rsa_key *key) { LTC_ARGCHK(key != NULL); + XMEMSET(&key->params, 0, sizeof(key->params)); return ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, LTC_NULL); } @@ -96,6 +97,180 @@ void rsa_free(rsa_key *key) { LTC_ARGCHKVD(key != NULL); ltc_mp_cleanup_multi(&key->q, &key->p, &key->qP, &key->dP, &key->dQ, &key->N, &key->d, &key->e, LTC_NULL); + XMEMSET(&key->params, 0, sizeof(key->params)); +} + +static LTC_INLINE int s_rsa_key_valid_rsa_params(ltc_rsa_op_checked *check) +{ + const ltc_rsa_parameters *key_params; + int padding = check->params->padding; + if (check->key == NULL) { + return CRYPT_OK; + } + key_params = &check->key->params; + if (!key_params->pss_oaep + && (!check->params->params.pss_oaep + || padding == LTC_PKCS_1_V1_5 + || padding == LTC_PKCS_1_V1_5_NA1)) { + return CRYPT_OK; + } + if (padding != LTC_PKCS_1_PSS + && padding != LTC_PKCS_1_OAEP) { + return CRYPT_PK_TYPE_MISMATCH; + } + if (key_params->hash_alg == NULL || find_hash(key_params->hash_alg) != check->hash_alg) { + return CRYPT_INVALID_HASH; + } + if (key_params->mgf1_hash_alg == NULL) { + return CRYPT_INVALID_HASH; + } + if ((check->mgf1_hash_alg = find_hash(key_params->mgf1_hash_alg)) == -1) { + return CRYPT_INVALID_HASH; + } + return hash_is_valid(check->mgf1_hash_alg); +} + +static LTC_INLINE int s_rsa_key_set_hash_algs(ltc_rsa_op_checked *check) +{ + ltc_rsa_op_parameters *params = check->params; + if (params->params.hash_alg == NULL || + (check->hash_alg = find_hash(params->params.hash_alg)) == -1) { + return CRYPT_INVALID_HASH; + } + if (params->params.mgf1_hash_alg == NULL || + (check->mgf1_hash_alg = find_hash(params->params.mgf1_hash_alg)) == -1) { + return CRYPT_INVALID_HASH; + } + return CRYPT_OK; +} + +static LTC_INLINE int s_rsa_key_valid_sign(ltc_rsa_op_checked *check) +{ + ltc_rsa_op_parameters *params = check->params; + if ((params->padding != LTC_PKCS_1_V1_5) + && (params->padding != LTC_PKCS_1_PSS) + && (params->padding != LTC_PKCS_1_V1_5_NA1)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (params->padding != LTC_PKCS_1_V1_5_NA1) { + int err = s_rsa_key_set_hash_algs(check); + if (err != CRYPT_OK) { + return err; + } + } + if (params->padding == LTC_PKCS_1_V1_5) { + /* not all hashes have OIDs... so sad */ + if (check->hash_alg == -1 + || hash_descriptor[check->hash_alg].OIDlen == 0) { + return CRYPT_INVALID_ARG; + } + } + return s_rsa_key_valid_rsa_params(check); +} + +static LTC_INLINE int s_rsa_key_valid_crypt(ltc_rsa_op_checked *check) +{ + ltc_rsa_op_parameters *params = check->params; + if ((params->padding != LTC_PKCS_1_V1_5) && + (params->padding != LTC_PKCS_1_OAEP)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (params->padding == LTC_PKCS_1_OAEP) { + int err = s_rsa_key_set_hash_algs(check); + if (err != CRYPT_OK) { + return err; + } + } + return s_rsa_key_valid_rsa_params(check); +} + +static LTC_INLINE int s_rsa_check_prng(ltc_rsa_op_parameters *params) +{ + if (params->padding != LTC_PKCS_1_PSS) + return CRYPT_OK; + if (params->prng == NULL) + return CRYPT_INVALID_PRNG; + /* valid prng ? */ + return prng_is_valid(params->wprng); +} + +int rsa_key_valid_op(ltc_rsa_op op, ltc_rsa_op_checked *check) +{ + int err; + check->hash_alg = check->mgf1_hash_alg = -1; + LTC_ARGCHK(check->params != NULL); + if ((op & LTC_RSA_OP_PKCS1) != LTC_RSA_OP_PKCS1) { + /* PKCS#1 ops don't need an RSA key */ + LTC_ARGCHK(check->key != NULL); + } + if ((op & LTC_RSA_OP_SEND) == LTC_RSA_OP_SEND) { + if ((err = s_rsa_check_prng(check->params)) != CRYPT_OK) { + return err; + } + } + switch (op) { + case LTC_RSA_ENCRYPT: + case LTC_RSA_DECRYPT: + case LTC_PKCS1_ENCRYPT: + case LTC_PKCS1_DECRYPT: + return s_rsa_key_valid_crypt(check); + case LTC_RSA_SIGN: + case LTC_RSA_VERIFY: + case LTC_PKCS1_SIGN: + case LTC_PKCS1_VERIFY: + return s_rsa_key_valid_sign(check); + } + return CRYPT_ERROR; +} + +int rsa_params_equal(const ltc_rsa_parameters *a, const ltc_rsa_parameters *b) +{ + if (!a->pss_oaep) + return 0; + if (a->pss_oaep != b->pss_oaep) + return 0; + if (a->saltlen != b->saltlen) + return 0; + if (!a->hash_alg || !b->hash_alg) + return 0; + if (XSTRCMP(a->hash_alg, b->hash_alg)) + return 0; + if (!a->mgf1_hash_alg || !b->mgf1_hash_alg) + return 0; + if (XSTRCMP(a->mgf1_hash_alg, b->mgf1_hash_alg)) + return 0; + return 1; +} + +int rsa_args_to_op_params(const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, + int padding, unsigned long saltlen, + ltc_rsa_op_parameters *params) +{ + int err; + ltc_rsa_op_parameters p = { + .u.crypt.lparam = lparam, + .u.crypt.lparamlen = lparamlen, + .prng = prng, + .wprng = prng_idx, + .padding = padding, + .params.saltlen = saltlen, + }; + if ((err = hash_is_valid(hash_idx)) == CRYPT_OK) { + if (hash_descriptor[hash_idx].name == NULL) { + return CRYPT_INVALID_HASH; + } + p.params.hash_alg = hash_descriptor[hash_idx].name; + p.params.mgf1_hash_alg = p.params.hash_alg; + *params = p; + } else if (padding == LTC_PKCS_1_V1_5 || padding == LTC_PKCS_1_V1_5_NA1) { + /* PKCS#1 1.5 does not necessarily require a hash */ + err = CRYPT_OK; + *params = p; + } + return err; } #endif diff --git a/src/pk/rsa/rsa_sign_hash.c b/src/pk/rsa/rsa_sign_hash.c index bc5e0a89f..325b72542 100644 --- a/src/pk/rsa/rsa_sign_hash.c +++ b/src/pk/rsa/rsa_sign_hash.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" /** @@ -8,72 +9,48 @@ */ #ifdef LTC_MRSA - /** PKCS #1 pad then sign - @param in The hash to sign - @param inlen The length of the hash to sign (octets) - @param out [out] The signature - @param outlen [in/out] The max size and resulting size of the signature - @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) - @param prng An active PRNG state - @param prng_idx The index of the PRNG desired - @param hash_idx The index of the hash desired - @param saltlen The length of the salt desired (octets) + @param hash The hash to sign + @param hashlen The length of the hash to sign (octets) + @param sig [out] The signature + @param siglen [in/out] The max size and resulting size of the signature + @param params The RSA operation parameters @param key The private RSA key to use @return CRYPT_OK if successful */ -int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - int padding, - prng_state *prng, int prng_idx, - int hash_idx, unsigned long saltlen, - const rsa_key *key) +int rsa_sign_hash_v2(const unsigned char *hash, unsigned long hashlen, + unsigned char *sig, unsigned long *siglen, + ltc_rsa_op_parameters *params, + const rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x, y; int err; + ltc_rsa_op_checked op_check = ltc_rsa_op_checked_init(key, params); - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(siglen != NULL); LTC_ARGCHK(key != NULL); - /* valid padding? */ - if ((padding != LTC_PKCS_1_V1_5) && - (padding != LTC_PKCS_1_PSS) && - (padding != LTC_PKCS_1_V1_5_NA1)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding == LTC_PKCS_1_PSS) { - /* valid prng ? */ - if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { - return err; - } - } - - if (padding != LTC_PKCS_1_V1_5_NA1) { - /* valid hash ? */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } + if ((err = rsa_key_valid_op(LTC_RSA_SIGN, &op_check)) != CRYPT_OK) { + return err; } /* get modulus len in bits */ modulus_bitlen = ltc_mp_count_bits((key->N)); - /* outlen must be at least the size of the modulus */ + /* siglen must be at least the size of the modulus */ modulus_bytelen = ltc_mp_unsigned_bin_size((key->N)); - if (modulus_bytelen > *outlen) { - *outlen = modulus_bytelen; + if (modulus_bytelen > *siglen) { + *siglen = modulus_bytelen; return CRYPT_BUFFER_OVERFLOW; } - if (padding == LTC_PKCS_1_PSS) { + if (params->padding == LTC_PKCS_1_PSS) { /* PSS pad the key */ - x = *outlen; - if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx, - hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { + x = *siglen; + if ((err = ltc_pkcs_1_pss_encode_mgf1(hash, hashlen, params, modulus_bitlen, sig, &x)) != CRYPT_OK) { return err; } } else { @@ -81,12 +58,8 @@ int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, unsigned char *tmpin = NULL; const unsigned char *tmpin_ro; - if (padding == LTC_PKCS_1_V1_5) { + if (params->padding == LTC_PKCS_1_V1_5) { ltc_asn1_list digestinfo[2], siginfo[2]; - /* not all hashes have OIDs... so sad */ - if (hash_descriptor[hash_idx].OIDlen == 0) { - return CRYPT_INVALID_ARG; - } /* construct the SEQUENCE SEQUENCE { @@ -96,10 +69,10 @@ int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, hash OCTET STRING } */ - LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[op_check.hash_alg].OID, hash_descriptor[op_check.hash_alg].OIDlen); LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); - LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, hash, hashlen); /* allocate memory for the encoding */ y = ltc_mp_unsigned_bin_size(key->N); @@ -115,14 +88,14 @@ int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, tmpin_ro = tmpin; } else { /* set the pointer and data-length to the input values */ - tmpin_ro = in; - y = inlen; + tmpin_ro = hash; + y = hashlen; } - x = *outlen; - err = pkcs_1_v1_5_encode(tmpin_ro, y, LTC_PKCS_1_EMSA, modulus_bitlen, NULL, 0, out, &x); + x = *siglen; + err = pkcs_1_v1_5_encode(tmpin_ro, y, LTC_PKCS_1_EMSA, modulus_bitlen, NULL, 0, sig, &x); - if (padding == LTC_PKCS_1_V1_5) { + if (params->padding == LTC_PKCS_1_V1_5) { XFREE(tmpin); } @@ -132,7 +105,7 @@ int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, } /* RSA encode it */ - return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key); + return ltc_mp.rsa_me(sig, x, sig, siglen, PK_PRIVATE, key); } #endif /* LTC_MRSA */ diff --git a/src/pk/rsa/rsa_verify_hash.c b/src/pk/rsa/rsa_verify_hash.c index 9ca1641a6..a50f7975a 100644 --- a/src/pk/rsa/rsa_verify_hash.c +++ b/src/pk/rsa/rsa_verify_hash.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" /** @@ -8,29 +9,27 @@ */ #ifdef LTC_MRSA - /** PKCS #1 de-sign then v1.5 or PSS depad @param sig The signature data @param siglen The length of the signature data (octets) @param hash The hash of the message that was signed @param hashlen The length of the hash of the message that was signed (octets) - @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) - @param hash_idx The index of the desired hash - @param saltlen The length of the salt used during signature + @param params The RSA operation parameters @param stat [out] The result of the signature comparison, 1==valid, 0==invalid @param key The public RSA key corresponding to the key that performed the signature @return CRYPT_OK on success (even if the signature is invalid) */ -int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int padding, - int hash_idx, unsigned long saltlen, - int *stat, const rsa_key *key) +int rsa_verify_hash_v2(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + ltc_rsa_op_parameters *params, + int *stat, + const rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmpbuf; + ltc_rsa_op_checked op_check = ltc_rsa_op_checked_init(key, params); LTC_ARGCHK(hash != NULL); LTC_ARGCHK(sig != NULL); @@ -40,19 +39,8 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle /* default to invalid */ *stat = 0; - /* valid padding? */ - - if ((padding != LTC_PKCS_1_V1_5) && - (padding != LTC_PKCS_1_PSS) && - (padding != LTC_PKCS_1_V1_5_NA1)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding != LTC_PKCS_1_V1_5_NA1) { - /* valid hash ? */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } + if ((err = rsa_key_valid_op(LTC_RSA_VERIFY, &op_check)) != CRYPT_OK) { + return err; } /* get modulus len in bits */ @@ -83,14 +71,14 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle return CRYPT_INVALID_PACKET; } - if (padding == LTC_PKCS_1_PSS) { + if (params->padding == LTC_PKCS_1_PSS) { /* PSS decode and verify it */ if(modulus_bitlen%8 == 1){ - err = pkcs_1_pss_decode(hash, hashlen, tmpbuf+1, x-1, saltlen, hash_idx, modulus_bitlen, stat); + err = ltc_pkcs_1_pss_decode_mgf1(hash, hashlen, tmpbuf+1, x-1, params, modulus_bitlen, stat); } else{ - err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); + err = ltc_pkcs_1_pss_decode_mgf1(hash, hashlen, tmpbuf, x, params, modulus_bitlen, stat); } } else { @@ -112,16 +100,10 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle goto bail_2; } - if (padding == LTC_PKCS_1_V1_5) { + if (params->padding == LTC_PKCS_1_V1_5) { unsigned long loid[16], reallen; ltc_asn1_list digestinfo[2], siginfo[2]; - /* not all hashes have OIDs... so sad */ - if (hash_descriptor[hash_idx].OIDlen == 0) { - err = CRYPT_INVALID_ARG; - goto bail_2; - } - /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ /* construct the SEQUENCE SEQUENCE { @@ -133,16 +115,13 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle */ LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, LTC_ARRAY_SIZE(loid)); LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + digestinfo[1].optional = 1; LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); if (der_decode_sequence_strict(out, outlen, siginfo, 2) != CRYPT_OK) { - /* fallback to Legacy:missing NULL */ - LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 1); - if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) { - XFREE(out); - goto bail_2; - } + XFREE(out); + goto bail_2; } if ((err = der_length_sequence(siginfo, 2, &reallen)) != CRYPT_OK) { @@ -152,8 +131,8 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle /* test OID */ if ((reallen == outlen) && - (digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && - (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && + (digestinfo[0].size == hash_descriptor[op_check.hash_alg].OIDlen) && + (XMEMCMP(digestinfo[0].data, hash_descriptor[op_check.hash_alg].OID, sizeof(unsigned long) * hash_descriptor[op_check.hash_alg].OIDlen) == 0) && (siginfo[1].size == hashlen) && (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { *stat = 1; diff --git a/tests/deprecated_test.c b/tests/deprecated_test.c new file mode 100644 index 000000000..a7f7f8a81 --- /dev/null +++ b/tests/deprecated_test.c @@ -0,0 +1,88 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#define LTC_DEPRECATED(x) +#include + +#ifdef LTC_MECC +static void s_ecc_test(void) +{ + const ltc_ecc_curve* dp; + unsigned char buf[128]; + unsigned long len; + ecc_key key; + int stat; + unsigned char data16[16] = { 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1 }; + + /* We need an MPI provider for ECC */ + if (ltc_mp.name == NULL) return; + + ENSURE(ltc_ecc_curves[0].OID != NULL); + + DO(ecc_find_curve(ltc_ecc_curves[0].OID, &dp)); + DO(ecc_make_key_ex(&yarrow_prng, find_prng ("yarrow"), &key, dp)); + + len = sizeof(buf); + DO(ecc_sign_hash(data16, 16, buf, &len, &yarrow_prng, find_prng ("yarrow"), &key)); + stat = 0; + DO(ecc_verify_hash(buf, len, data16, 16, &stat, &key)); + + SHOULD_FAIL(ecc_verify_hash_rfc7518(buf, len, data16, 16, &stat, &key)); + + len = sizeof(buf); + DO(ecc_sign_hash_rfc7518(data16, 16, buf, &len, &yarrow_prng, find_prng ("yarrow"), &key)); + stat = 0; + DO(ecc_verify_hash_rfc7518(buf, len, data16, 16, &stat, &key)); + + SHOULD_FAIL(ecc_verify_hash(buf, len, data16, 16, &stat, &key)); + + ecc_free(&key); +} +#endif + +#ifdef LTC_MRSA +extern const unsigned char ltc_rsa_private_test_key[]; +extern const unsigned long ltc_rsa_private_test_key_sz; +extern const unsigned char ltc_openssl_public_rsa[]; +extern const unsigned long ltc_openssl_public_rsa_sz; +static void s_rsa_test(void) +{ + rsa_key key, pubkey; + int stat; + const unsigned char tv[] = "test"; + unsigned char buf0[1024], buf1[1024]; + unsigned long buf0len, buf1len; + + /* We need an MPI provider for RSA */ + if (ltc_mp.name == NULL) return; + + DO(rsa_import(ltc_rsa_private_test_key, ltc_rsa_private_test_key_sz, &key)); + DO(rsa_import(ltc_openssl_public_rsa, ltc_openssl_public_rsa_sz, &pubkey)); + + buf0len = sizeof(buf0); + DO(rsa_sign_hash_ex(tv, 4, buf0, &buf0len, LTC_PKCS_1_PSS, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), 8, &key)); + buf1len = sizeof(buf1); + DO(rsa_verify_hash_ex(buf0, buf0len, tv, 4, LTC_PKCS_1_PSS, find_hash("sha1"), 8, &stat, &pubkey)); + ENSURE(stat == 1); + + buf0len = sizeof(buf0); + DO(rsa_encrypt_key_ex(tv, 4, buf0, &buf0len, NULL, 0, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), LTC_PKCS_1_OAEP, &pubkey)); + buf1len = sizeof(buf1); + DO(rsa_decrypt_key_ex(buf0, buf0len, buf1, &buf1len, NULL, 0, find_hash("sha1"), LTC_PKCS_1_OAEP, &stat, &key)); + ENSURE(stat == 1); + COMPARE_TESTVECTOR(buf1, buf1len, tv, 4, "s_rsa_test", 0); + + rsa_free(&pubkey); + rsa_free(&key); +} +#endif + +int deprecated_test(void) +{ +#ifdef LTC_MECC + s_ecc_test(); +#endif +#ifdef LTC_MRSA + s_rsa_test(); +#endif + return 0; +} diff --git a/tests/ecc_test.c b/tests/ecc_test.c index b70666590..0d3cdf368 100644 --- a/tests/ecc_test.c +++ b/tests/ecc_test.c @@ -316,7 +316,7 @@ static int s_ecc_issue443_447(void) DO(ecc_find_curve("secp256r1", &cu)); DO(ecc_set_curve(cu, &key)); DO(ecc_set_key(pub1, sizeof(pub1), PK_PUBLIC, &key)); - err = ecc_verify_hash_rfc7518(sig1, sizeof(sig1), hash, hashlen, &stat, &key); /* should fail */ + err = ecc_verify_hash_rfc7518_internal(sig1, sizeof(sig1), hash, hashlen, &stat, &key); /* should fail */ ecc_free(&key); if (err != CRYPT_INVALID_PACKET) return CRYPT_FAIL_TESTVECTOR; @@ -325,7 +325,7 @@ static int s_ecc_issue443_447(void) DO(ecc_find_curve("secp521r1", &cu)); DO(ecc_set_curve(cu, &key)); DO(ecc_set_key(pub2, sizeof(pub2), PK_PUBLIC, &key)); - err = ecc_verify_hash_rfc7518(sig2, sizeof(sig2), hash, hashlen, &stat, &key); /* should fail */ + err = ecc_verify_hash_rfc7518_internal(sig2, sizeof(sig2), hash, hashlen, &stat, &key); /* should fail */ ecc_free(&key); if (err != CRYPT_INVALID_PACKET) return CRYPT_FAIL_TESTVECTOR; @@ -401,6 +401,10 @@ static int s_ecc_old_api(void) unsigned long x, y, z, s; int stat, stat2; ecc_key usera, userb, pubKey, privKey; + ltc_ecc_sig_opts sig_opts = { + .prng = &yarrow_prng, + .wprng = find_prng ("yarrow") + }; int low, high; ecc_sizes(&low, &high); @@ -500,10 +504,10 @@ static int s_ecc_old_api(void) buf[0][ch] = ch; } x = sizeof (buf[1]); - DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey)); - DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey)); + DO(ecc_sign_hash_v2(buf[0], 16, buf[1], &x, &sig_opts, &privKey)); + DO(ecc_verify_hash_v2(buf[1], x, buf[0], 16, &sig_opts, &stat, &pubKey)); buf[0][0] ^= 1; - DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey)); + DO(ecc_verify_hash_v2(buf[1], x, buf[0], 16, &sig_opts, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "ecc_verify_hash failed %d, %d, ", stat, stat2); return 1; @@ -513,10 +517,10 @@ static int s_ecc_old_api(void) buf[0][ch] = ch; } x = sizeof (buf[1]); - DO(ecc_sign_hash_rfc7518(buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey)); - DO(ecc_verify_hash_rfc7518(buf[1], x, buf[0], 16, &stat, &pubKey)); + DO(ecc_sign_hash_v2(buf[0], 16, buf[1], &x, &sig_opts, &privKey)); + DO(ecc_verify_hash_v2(buf[1], x, buf[0], 16, &sig_opts, &stat, &pubKey)); buf[0][0] ^= 1; - DO(ecc_verify_hash_rfc7518(buf[1], x, buf[0], 16, &stat2, &privKey)); + DO(ecc_verify_hash_v2(buf[1], x, buf[0], 16, &sig_opts, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "ecc_verify_hash_rfc7518 failed %d, %d, ", stat, stat2); return 1; @@ -549,13 +553,29 @@ int ecc_key_cmp(const int should_type, const ecc_key *should, const ecc_key *is) static int s_ecc_new_api(void) { - int i, j, stat; + int i, stat; const ltc_ecc_curve* dp; ecc_key key, privkey, pubkey; unsigned char buf[1000]; - unsigned long len; - unsigned char data16[16] = { 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1 }; + unsigned long len, j; + unsigned char data16[MAXBLOCKSIZE]; unsigned long len16; + const ecc_signature_type sig_algs[] = { +#ifdef LTC_DER + LTC_ECCSIG_ANSIX962, +#endif + LTC_ECCSIG_RFC7518, + LTC_ECCSIG_ETH27, +#ifdef LTC_SSH + LTC_ECCSIG_RFC5656, +#endif + }; + ltc_ecc_sig_opts sig_opts = { + .type = LTC_ECCSIG_ANSIX962, + .prng = &yarrow_prng, + .wprng = find_prng ("yarrow") + }; + XMEMSET(data16, 0xd1, sizeof(data16)); for (i = 0; i < (int)LTC_ARRAY_SIZE(curvenames); i++) { DO(ecc_find_curve(curvenames[i], &dp)); @@ -606,50 +626,50 @@ static int s_ecc_new_api(void) DO(ecc_set_curve(dp, &pubkey)); DO(ecc_set_key(buf, len, PK_PUBLIC, &pubkey)); - /* test signature */ - len = sizeof(buf); - DO(ecc_sign_hash(data16, 16, buf, &len, &yarrow_prng, find_prng ("yarrow"), &privkey)); - stat = 0; - 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_rfc5656(data16, 16, buf, &len, &yarrow_prng, find_prng ("yarrow"), &privkey)); - stat = 0; - DO(ecc_verify_hash_rfc5656(buf, len, data16, 16, &stat, &pubkey)); - if (stat != 1) return CRYPT_FAIL_TESTVECTOR; -#endif + for (j = 0; j < LTC_ARRAY_SIZE(sig_algs); ++j) { + /* test signature */ + if (sig_algs[j] == LTC_ECCSIG_ETH27 && XSTRCMP(dp->OID, "1.3.132.0.10")) + continue; + len = sizeof(buf); + sig_opts.type = sig_algs[j]; + DO(ecc_sign_hash_v2(data16, privkey.dp.size, buf, &len, &sig_opts, &privkey)); + stat = 0; + DO(ecc_verify_hash_v2(buf, len, data16, privkey.dp.size, &sig_opts, &stat, &pubkey)); + if (stat != 1) return CRYPT_FAIL_TESTVECTOR; #ifdef LTC_ECC_SHAMIR - if (strcmp(ltc_mp.name, "TomsFastMath") != 0) { - /* XXX-FIXME: TFM does not support sqrtmod_prime */ - int found = 0; - ecc_key reckey; - /* test recovery */ - len = sizeof(buf); - DO(ecc_sign_hash(data16, 16, buf, &len, &yarrow_prng, find_prng ("yarrow"), &privkey)); - DO(ecc_set_curve(dp, &reckey)); - for (j = 0; j < 2*(1+(int)privkey.dp.cofactor); j++) { - stat = ecc_recover_key(buf, len, data16, 16, j, LTC_ECCSIG_ANSIX962, &reckey); - if (stat != CRYPT_OK) continue; /* last two will almost always fail, only possible if x<(prime mod order) */ - stat = ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey); - if (stat == CRYPT_OK) found++; + if (strcmp(ltc_mp.name, "TomsFastMath") != 0) { + /* XXX-FIXME: TFM does not support sqrtmod_prime */ + int found = 0, recid; + ecc_key reckey; + /* test recovery */ + sig_opts.recid = &recid; + len = sizeof(buf); + DO(ecc_sign_hash_v2(data16, privkey.dp.size, buf, &len, &sig_opts, &privkey)); + DO(ecc_set_curve(dp, &reckey)); + for (j = 0; j < 2*(1+privkey.dp.cofactor); j++) { + recid = j; + stat = ecc_recover_key(buf, len, data16, privkey.dp.size, &sig_opts, &reckey); + if (stat != CRYPT_OK) continue; /* last two will almost always fail, only possible if x<(prime mod order) */ + stat = ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey); + if (stat == CRYPT_OK) found++; + } + sig_opts.recid = NULL; + if (found != 1) return CRYPT_FAIL_TESTVECTOR; /* unique match */ + ecc_free(&reckey); } - if (found != 1) return CRYPT_FAIL_TESTVECTOR; /* unique match */ - ecc_free(&reckey); - } #endif + } + /* test encryption */ len = sizeof(buf); DO(ecc_encrypt_key(data16, 16, buf, &len, &yarrow_prng, find_prng("yarrow"), find_hash("sha256"), &pubkey)); zeromem(data16, 16); len16 = 16; DO(ecc_decrypt_key(buf, len, data16, &len16, &privkey)); - if (len16 != 16) return CRYPT_FAIL_TESTVECTOR; - for (j = 0; j < 16; j++) if (data16[j] != 0xd1) return CRYPT_FAIL_TESTVECTOR; + if ((int)len16 != 16) return CRYPT_FAIL_TESTVECTOR; + for (j = 0; (int)j < 16; j++) if (data16[j] != 0xd1) return CRYPT_FAIL_TESTVECTOR; /* cleanup */ ecc_free(&privkey); @@ -993,6 +1013,11 @@ static int s_ecc_rfc6979(void) char name[128], tmp[MAXBLOCKSIZE]; unsigned int t, s, i, h; unsigned long pklen, hashlen, curvelen, inputlen, siglen, shouldlen, shouldlen2; + ltc_ecc_sig_opts sig_opts = { + .type = LTC_ECCSIG_RFC7518, + .prng = &yarrow_prng, + .wprng = find_prng ("yarrow") + }; for (t = 0; tests[t].curve; ++t) { curvelen = XSTRLEN(tests[t].curve); XMEMCPY(name, tests[t].curve, curvelen); @@ -1020,9 +1045,9 @@ static int s_ecc_rfc6979(void) XMEMCPY(&name[curvelen + inputlen], hashes[h], 7); hashlen = sizeof(hash); DOX(hash_memory(find_hash(hashes[h]), inputs[i], XSTRLEN(inputs[i]), hash, &hashlen), name); - ECC_SET_RFC6979_HASH_ALG(&key, hashes[h]); + sig_opts.rfc6979_hash_alg = hashes[h]; siglen = sizeof(sig); - DOX(ecc_sign_hash_rfc7518(hash, hashlen, sig, &siglen, &yarrow_prng, find_prng ("yarrow"), &key), name); + DOX(ecc_sign_hash_v2(hash, hashlen, sig, &siglen, &sig_opts, &key), name); XMEMSET(should, 0, sizeof(should)); shouldlen = sizeof(should); DOX(base16_decode(tests[t].signatures[s].r, XSTRLEN(tests[t].signatures[s].r), should, &shouldlen), name); @@ -1907,6 +1932,11 @@ static int s_ecc_test_ethereum(void) unsigned char buf[128]; unsigned long len; unsigned char data16[16] = { 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1 }; + ltc_ecc_sig_opts sig_opts = { + .type = LTC_ECCSIG_ETH27, + .prng = &yarrow_prng, + .wprng = find_prng ("yarrow"), + }; DO(ecc_find_curve("SECP256K1", &dp)); @@ -1914,15 +1944,15 @@ static int s_ecc_test_ethereum(void) /* test Ethereum signature */ len = sizeof(buf); - DO(ecc_sign_hash_eth27(data16, 16, buf, &len, &yarrow_prng, find_prng ("yarrow"), &key)); + DO(ecc_sign_hash_v2(data16, 16, buf, &len, &sig_opts, &key)); stat = 0; - DO(ecc_verify_hash_eth27(buf, len, data16, 16, &stat, &key)); + DO(ecc_verify_hash_v2(buf, len, data16, 16, &sig_opts, &stat, &key)); if (stat != 1) return CRYPT_FAIL_TESTVECTOR; /* XXX-FIXME: TFM does not support sqrtmod_prime */ if (strcmp(ltc_mp.name, "TomsFastMath") != 0) { DO(ecc_set_curve(dp, &reckey)); - DO(ecc_recover_key(buf, len, data16, 16, -1, LTC_ECCSIG_ETH27, &reckey)); + DO(ecc_recover_key(buf, len, data16, 16, &sig_opts, &reckey)); DO(ecc_key_cmp(PK_PUBLIC, &key, &reckey)); /* cleanup */ @@ -1962,6 +1992,11 @@ static int s_ecc_test_recovery(void) 0xb7, 0x3c, 0x97, 0x55, 0xfa, 0x69, 0xf8, 0xef, 0xe9, 0xcf, 0x12, 0xaf, 0x48, 0x25, 0xe3, 0xe0, 0x1b }; + ltc_ecc_sig_opts sig_opts = { + .prng = &yarrow_prng, + .wprng = find_prng ("yarrow"), + .recid = &recid + }; /* XXX-FIXME: TFM does not support sqrtmod_prime */ if (strcmp(ltc_mp.name, "TomsFastMath") == 0) return CRYPT_NOP; @@ -1973,18 +2008,23 @@ static int s_ecc_test_recovery(void) DO(ecc_set_key(eth_pubkey, sizeof(eth_pubkey), PK_PUBLIC, &pubkey)); DO(ecc_set_curve(dp, &reckey)); - DO(ecc_recover_key(eth_sig, sizeof(eth_sig)-1, eth_hash, sizeof(eth_hash), 0, LTC_ECCSIG_RFC7518, &reckey)); + recid = 0; + sig_opts.type = LTC_ECCSIG_RFC7518; + DO(ecc_recover_key(eth_sig, sizeof(eth_sig)-1, eth_hash, sizeof(eth_hash), &sig_opts, &reckey)); DO(ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey)); ecc_free(&reckey); DO(ecc_set_curve(dp, &reckey)); - DO(ecc_recover_key(eth_sig, sizeof(eth_sig), eth_hash, sizeof(eth_hash), -1, LTC_ECCSIG_ETH27, &reckey)); + recid = -1; + sig_opts.type = LTC_ECCSIG_ETH27; + DO(ecc_recover_key(eth_sig, sizeof(eth_sig), eth_hash, sizeof(eth_hash), &sig_opts, &reckey)); DO(ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey)); ecc_free(&reckey); ecc_free(&pubkey); #endif + sig_opts.type = LTC_ECCSIG_RFC7518; for (i = 0; i < (int)LTC_ARRAY_SIZE(curvenames); i++) { DO(ecc_find_curve(curvenames[i], &dp)); @@ -2013,16 +2053,16 @@ static int s_ecc_test_recovery(void) /* test signature */ len = sizeof(buf); recid = 0; - DO(ecc_sign_hash_rfc7518_ex(data16, 16, buf, &len, &yarrow_prng, find_prng ("yarrow"), &recid, &privkey)); + DO(ecc_sign_hash_v2(data16, 16, buf, &len, &sig_opts, &privkey)); /* test verification */ stat = 0; - DO(ecc_verify_hash_rfc7518(buf, len, data16, 16, &stat, &pubkey)); + DO(ecc_verify_hash_v2(buf, len, data16, 16, &sig_opts, &stat, &pubkey)); if (stat != 1) return CRYPT_FAIL_TESTVECTOR; /* test recovery */ DO(ecc_set_curve(dp, &reckey)); - stat = ecc_recover_key(buf, len, data16, 16, recid, LTC_ECCSIG_RFC7518, &reckey); + stat = ecc_recover_key(buf, len, data16, 16, &sig_opts, &reckey); if (stat != CRYPT_OK) return CRYPT_FAIL_TESTVECTOR; DO(ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey)); diff --git a/tests/pkcs_1_eme_test.c b/tests/pkcs_1_eme_test.c index ca540360b..1578fab18 100644 --- a/tests/pkcs_1_eme_test.c +++ b/tests/pkcs_1_eme_test.c @@ -24,8 +24,7 @@ int pkcs_1_eme_test(void) for (i = 0; i < LTC_ARRAY_SIZE(testcases_eme); ++i) { testcase_t* t = &testcases_eme[i]; rsa_key k, *key = &k; - DOX(ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL), t->name); + DOX(rsa_init(key), t->name); DOX(ltc_mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name); DOX(ltc_mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name); @@ -43,9 +42,9 @@ int pkcs_1_eme_test(void) unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf); int stat; prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (void*)no_prng_desc); - DOX(rsa_encrypt_key_ex(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (void*)no_prng_desc, prng_idx, -1, -1, LTC_PKCS_1_V1_5, key), s->name); + DOX(rsa_encrypt_key_ex(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (void*)no_prng_desc, prng_idx, -1, LTC_PKCS_1_V1_5, key), s->name); COMPARE_TESTVECTOR(obuf, obuflen, s->o3, s->o3_l,s->name, j); - DOX(rsa_decrypt_key_ex(obuf, obuflen, buf, &buflen, NULL, 0, -1, -1, LTC_PKCS_1_V1_5, &stat, key), s->name); + DOX(rsa_decrypt_key_ex(obuf, obuflen, buf, &buflen, NULL, 0, -1, LTC_PKCS_1_V1_5, &stat, key), s->name); DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name); } /* for */ diff --git a/tests/pkcs_1_emsa_test.c b/tests/pkcs_1_emsa_test.c index ba66f079a..43fb112ae 100644 --- a/tests/pkcs_1_emsa_test.c +++ b/tests/pkcs_1_emsa_test.c @@ -21,8 +21,7 @@ int pkcs_1_emsa_test(void) for (i = 0; i < LTC_ARRAY_SIZE(testcases_emsa); ++i) { testcase_t* t = &testcases_emsa[i]; rsa_key k, *key = &k; - DOX(ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL), t->name); + DOX(rsa_init(key), t->name); DOX(ltc_mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name); DOX(ltc_mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name); diff --git a/tests/pkcs_1_oaep_test.c b/tests/pkcs_1_oaep_test.c index 1cb6ca128..76157c2c0 100644 --- a/tests/pkcs_1_oaep_test.c +++ b/tests/pkcs_1_oaep_test.c @@ -24,8 +24,7 @@ int pkcs_1_oaep_test(void) for (i = 0; i < LTC_ARRAY_SIZE(testcases_oaep); ++i) { testcase_t* t = &testcases_oaep[i]; rsa_key k, *key = &k; - DOX(ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL), t->name); + DOX(rsa_init(key), t->name); DOX(ltc_mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name); DOX(ltc_mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name); diff --git a/tests/pkcs_1_pss_test.c b/tests/pkcs_1_pss_test.c index a62e53ff0..a86e473ac 100644 --- a/tests/pkcs_1_pss_test.c +++ b/tests/pkcs_1_pss_test.c @@ -24,8 +24,7 @@ int pkcs_1_pss_test(void) for (i = 0; i < LTC_ARRAY_SIZE(testcases_pss); ++i) { testcase_t* t = &testcases_pss[i]; rsa_key k, *key = &k; - DOX(ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL), t->name); + DOX(rsa_init(key), t->name); DOX(ltc_mp_read_unsigned_bin(key->e, t->rsa.e, t->rsa.e_l), t->name); DOX(ltc_mp_read_unsigned_bin(key->d, t->rsa.d, t->rsa.d_l), t->name); diff --git a/tests/pkcs_1_test.c b/tests/pkcs_1_test.c index de0f7d307..00d90bfed 100644 --- a/tests/pkcs_1_test.c +++ b/tests/pkcs_1_test.c @@ -46,11 +46,11 @@ int pkcs_1_test(void) /* encode it */ l1 = sizeof(buf[1]); - DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, -1, buf[1], &l1)); + DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, buf[1], &l1)); /* decode it */ l2 = sizeof(buf[2]); - DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, -1, buf[2], &l2, &res1)); + DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1)); if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) { fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen); diff --git a/tests/rsa_test.c b/tests/rsa_test.c index c1cfbb2b0..d27bd90f9 100644 --- a/tests/rsa_test.c +++ b/tests/rsa_test.c @@ -134,7 +134,7 @@ static const char *hex_key[] = { "DCCC27C8E4DC6248D59BAFF5AB60F621FD53E2B75D09C91AA104A9FC612C5D04583A5A39F14A215667FDCC20A38F78185A793D2E8E7E860AE6A833C104174A9F" }; /*** openssl public RSA key in DER format */ -static const unsigned char openssl_public_rsa[] = { +const unsigned char ltc_openssl_public_rsa[] = { 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, @@ -146,6 +146,7 @@ static const unsigned char openssl_public_rsa[] = { 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, }; +const unsigned long ltc_openssl_public_rsa_sz = sizeof(ltc_openssl_public_rsa); /* same key but with extra headers stripped */ static const unsigned char openssl_public_rsa_stripped[] = { @@ -184,22 +185,24 @@ static int rsa_compat_test(void) int stat, i; unsigned char buf[1024], key_parts[8][128]; unsigned long len, key_lens[8]; + ltc_rsa_op_parameters rsa_params = {0}; /* try reading the key */ DO(rsa_import(ltc_rsa_private_test_key, sizeof(ltc_rsa_private_test_key), &key)); - DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &pubkey)); + DO(rsa_import(ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), &pubkey)); /* sign-verify a message with PKCS #1 v1.5 no ASN.1 */ len = sizeof(buf); - DO(rsa_sign_hash_ex((unsigned char*)"test", 4, buf, &len, LTC_PKCS_1_V1_5_NA1, NULL, 0, 0, 0, &key)); + rsa_params.padding = LTC_PKCS_1_V1_5_NA1; + DO(rsa_sign_hash_v2((unsigned char*)"test", 4, buf, &len, &rsa_params, &key)); if (len != sizeof(openssl_rsautl_pkcs) || memcmp(buf, openssl_rsautl_pkcs, len)) { - fprintf(stderr, "RSA rsa_sign_hash_ex + LTC_PKCS_1_V1_5_NA1 failed\n"); + fprintf(stderr, "RSA rsa_sign_hash_v2 + LTC_PKCS_1_V1_5_NA1 failed\n"); return 1; } stat = 0; - DO(rsa_verify_hash_ex(openssl_rsautl_pkcs, sizeof(openssl_rsautl_pkcs), (unsigned char*)"test", 4, LTC_PKCS_1_V1_5_NA1, 0, 0, &stat, &pubkey)); + DO(rsa_verify_hash_v2(openssl_rsautl_pkcs, sizeof(openssl_rsautl_pkcs), (unsigned char*)"test", 4, &rsa_params, &stat, &pubkey)); if (stat != 1) { - fprintf(stderr, "RSA rsa_verify_hash_ex + LTC_PKCS_1_V1_5_NA1 failed\n"); + fprintf(stderr, "RSA rsa_verify_hash_v2 + LTC_PKCS_1_V1_5_NA1 failed\n"); return 1; } rsa_free(&pubkey); @@ -222,7 +225,7 @@ static int rsa_compat_test(void) rsa_free(&key); /* try reading the public key */ - DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key)); + DO(rsa_import(ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), &key)); len = sizeof(buf); DO(rsa_export(buf, &len, PK_PUBLIC, &key)); COMPARE_TESTVECTOR(buf, len, openssl_public_rsa_stripped, sizeof(openssl_public_rsa_stripped), "RSA public export (from OpenSSL)", 0); @@ -257,10 +260,10 @@ static int rsa_compat_test(void) rsa_free(&key); /* try export in SubjectPublicKeyInfo format of the public key */ - DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key)); + DO(rsa_import(ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), &key)); len = sizeof(buf); DO(rsa_export(buf, &len, PK_PUBLIC | PK_STD, &key)); - COMPARE_TESTVECTOR(buf, len, openssl_public_rsa, sizeof(openssl_public_rsa), "RSA public export (X.509)", 0); + COMPARE_TESTVECTOR(buf, len, ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), "RSA public export (X.509)", 0); rsa_free(&key); return 0; @@ -319,6 +322,7 @@ static int s_rsa_cryptx_issue_69(void) unsigned char buf0[512], buf1[512]; unsigned long l0, l1; int stat; + ltc_rsa_op_parameters rsa_params = {0}; l0 = sizeof(buf0); l1 = sizeof(buf1); @@ -331,9 +335,10 @@ static int s_rsa_cryptx_issue_69(void) l1 = sizeof(buf1); DO(radix_to_bin(sig1, 16, buf0, &l0)); DO(radix_to_bin(hash, 16, buf1, &l1)); - SHOULD_FAIL(rsa_verify_hash_ex(buf0, l0, buf1, l1, LTC_PKCS_1_V1_5, 0, 0, &stat, &key)); + rsa_params.padding = LTC_PKCS_1_V1_5; + SHOULD_FAIL(rsa_verify_hash_v2(buf0, l0, buf1, l1, &rsa_params, &stat, &key)); DO(radix_to_bin(sig2, 16, buf0, &l0)); - SHOULD_FAIL(rsa_verify_hash_ex(buf0, l0, buf1, l1, LTC_PKCS_1_V1_5, 0, 0, &stat, &key)); + SHOULD_FAIL(rsa_verify_hash_v2(buf0, l0, buf1, l1, &rsa_params, &stat, &key)); rsa_free(&key); return CRYPT_OK; } @@ -448,17 +453,48 @@ static int s_rsa_import_pkcs8(const void *in, unsigned long inlen, void *key) #endif #endif +static int s_rsa_macros_test(void) +{ + rsa_key key, pubkey; + int stat; + const unsigned char tv[] = "test"; + unsigned char buf0[1024], buf1[1024]; + unsigned long buf0len, buf1len; + + DO(rsa_import(ltc_rsa_private_test_key, sizeof(ltc_rsa_private_test_key), &key)); + DO(rsa_import(ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), &pubkey)); + + buf0len = sizeof(buf0); + DO(ltc_rsa_sign_hash(tv, 4, buf0, &buf0len, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), 8, &key)); + buf1len = sizeof(buf1); + DO(ltc_rsa_verify_hash(buf0, buf0len, tv, 4, find_hash("sha1"), 8, &stat, &key)); + ENSURE(stat == 1); + + buf0len = sizeof(buf0); + DO(ltc_rsa_encrypt_key(tv, 4, buf0, &buf0len, NULL, 0, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &pubkey)); + buf1len = sizeof(buf1); + DO(ltc_rsa_decrypt_key(buf0, buf0len, buf1, &buf1len, NULL, 0, find_hash("sha1"), &stat, &key)); + ENSURE(stat == 1); + COMPARE_TESTVECTOR(buf1, buf1len, tv, 4, "s_rsa_macros_test", 0); + + rsa_free(&pubkey); + rsa_free(&key); + + return CRYPT_OK; +} + int rsa_test(void) { unsigned char in[1024], out[1024], tmp[3072]; rsa_key key, privKey, pubKey; - int hash_idx, prng_idx, stat, stat2, i, mgf_hash, label_hash; - unsigned long rsa_msgsize, len, len2, len3, cnt, cnt2, max_msgsize; + int prng_idx, stat, stat2, i, mgf_hash; + unsigned long rsa_msgsize, len, len2, len3, cnt, cnt2, max_msgsize, label_hash; static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; void* dP; unsigned char* p; unsigned char* p2; unsigned char* p3; + ltc_rsa_op_parameters rsa_params = {0}; if (ltc_mp.name == NULL) return CRYPT_NOP; @@ -466,12 +502,15 @@ int rsa_test(void) return 1; } - hash_idx = find_hash("sha1"); - prng_idx = find_prng("yarrow"); - if (hash_idx == -1 || prng_idx == -1) { + rsa_params.params.hash_alg = "sha1"; + rsa_params.wprng = find_prng("yarrow"); + mgf_hash = find_hash(rsa_params.params.hash_alg); + if (mgf_hash == -1 || rsa_params.wprng == -1) { fprintf(stderr, "rsa_test requires LTC_SHA1 and yarrow"); return 1; } + rsa_params.prng = &yarrow_prng; + prng_idx = rsa_params.wprng; #ifdef LTC_TEST_READDIR DO(test_process_dir("tests/rsa", &key, s_rsa_import_x509, NULL, (dir_cleanup_cb)rsa_free, "rsa_test")); @@ -481,6 +520,7 @@ int rsa_test(void) DO(test_process_dir("tests/rsa-pkcs8", &key, s_rsa_import_pkcs8, NULL, (dir_cleanup_cb)rsa_free, "rsa_pkcs8_test")); #endif + DO(s_rsa_macros_test()); DO(s_rsa_cryptx_issue_69()); DO(s_rsa_issue_301(prng_idx)); DO(s_rsa_public_ubin_e(prng_idx)); @@ -512,13 +552,13 @@ print_hex("q", tmp, len); /* make a random key/msg */ ENSURE(yarrow_read(in, 117, &yarrow_prng) == 117); + rsa_params.padding = LTC_PKCS_1_OAEP; #ifdef LTC_TEST_EXT for (mgf_hash = 0; mgf_hash < TAB_SIZE; ++mgf_hash) { if (hash_is_valid(mgf_hash) != CRYPT_OK) continue; #else { - mgf_hash = hash_idx; #endif for (label_hash = 0; label_hash < TAB_SIZE; ++label_hash) { if (hash_is_valid(label_hash) != CRYPT_OK) @@ -526,6 +566,8 @@ print_hex("q", tmp, len); if (2 * hash_descriptor[label_hash].hashsize > 126) continue; max_msgsize = 128 - (2 * hash_descriptor[label_hash].hashsize) - 2; + rsa_params.params.hash_alg = hash_descriptor[label_hash].name; + rsa_params.params.mgf1_hash_alg = hash_descriptor[mgf_hash].name; #if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1 fprintf(stderr, "Test MGF(%s), Labelhash(%s) with max_msgsize %lu\n", hash_descriptor[mgf_hash].name, hash_descriptor[label_hash].name, max_msgsize); @@ -536,59 +578,66 @@ print_hex("q", tmp, len); len = sizeof(out); len2 = rsa_msgsize; - DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &key)); + DO(rsa_encrypt_key_v2(in, rsa_msgsize, out, &len, &rsa_params, &key)); /* change a byte */ out[8] ^= 1; - SHOULD_FAIL(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat2, &key)); + SHOULD_FAIL(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat2, &key)); /* change a byte back */ out[8] ^= 1; ENSURE(len2 == rsa_msgsize); len2 = rsa_msgsize; - DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat, &key)); + DO(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat, &key)); ENSUREX(stat == 1 && stat2 == 0, "rsa_decrypt_key (without lparam)"); COMPARE_TESTVECTOR(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key (without lparam)", cnt << 8 | rsa_msgsize); } /* encrypt the key (with lparam) */ + rsa_params.u.crypt.lparam = lparam; + rsa_params.u.crypt.lparamlen = sizeof(lparam); for (rsa_msgsize = 0; rsa_msgsize <= max_msgsize; rsa_msgsize++) { len = sizeof(out); len2 = rsa_msgsize; - DO(rsa_encrypt_key_ex(rsa_msgsize ? in : NULL, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &key)); + DO(rsa_encrypt_key_v2(rsa_msgsize ? in : NULL, rsa_msgsize, out, &len, &rsa_params, &key)); /* change a byte */ out[8] ^= 1; - SHOULD_FAIL(rsa_decrypt_key_ex(out, len, tmp, &len2, lparam, sizeof(lparam), mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat2, &key)); + SHOULD_FAIL(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat2, &key)); ENSURE(len2 == rsa_msgsize); /* change a byte back */ out[8] ^= 1; len2 = rsa_msgsize; - DO(rsa_decrypt_key_ex(out, len, tmp, &len2, lparam, sizeof(lparam), mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat, &key)); + DO(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat, &key)); ENSURE(stat == 1 && stat2 == 0); COMPARE_TESTVECTOR(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key (with lparam)", rsa_msgsize); } + rsa_params.u.crypt.lparam = NULL; + rsa_params.u.crypt.lparamlen = 0; } } - + rsa_params.params.hash_alg = "sha1"; + rsa_params.params.mgf1_hash_alg = "sha1"; /* encrypt the key PKCS #1 v1.5 (payload from 1 to 117 bytes) */ + rsa_params.padding = LTC_PKCS_1_V1_5; for (rsa_msgsize = 0; rsa_msgsize <= 117; rsa_msgsize++) { len = sizeof(out); len2 = rsa_msgsize; - DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, -1, LTC_PKCS_1_V1_5, &key)); + DO(rsa_encrypt_key_v2(in, rsa_msgsize, out, &len, &rsa_params, &key)); len2 = rsa_msgsize; - DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, -1, LTC_PKCS_1_V1_5, &stat, &key)); + DO(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat, &key)); ENSURE(stat == 1); COMPARE_TESTVECTOR(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key_ex", rsa_msgsize); } /* sign a message (unsalted, lower cholestorol and Atkins approved) now */ len = sizeof(out); - DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key)); + rsa_params.padding = LTC_PKCS_1_PSS; + DO(rsa_sign_hash_v2(in, 20, out, &len, &rsa_params, &key)); /* export key and import as both private and public */ len2 = sizeof(tmp); @@ -607,20 +656,20 @@ print_hex("q", tmp, len); dbg_malloc_stats(); /* verify with original */ - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &key)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &key)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &key)); ENSUREX(stat == 1 && stat2 == 0, "rsa_verify_hash (unsalted, origKey) failed"); /* verify with privKey */ /* change byte back to original */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &privKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); @@ -636,10 +685,10 @@ print_hex("q", tmp, len); privKey.dP = NULL; /* change byte back to original */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &privKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); @@ -653,10 +702,10 @@ print_hex("q", tmp, len); /* verify with pubKey */ /* change byte back to original */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &pubKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); @@ -668,11 +717,12 @@ print_hex("q", tmp, len); /* sign a message (salted) now (use privKey to make, pubKey to verify) */ len = sizeof(out); - DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey)); + rsa_params.params.saltlen = 8; + DO(rsa_sign_hash_v2(in, 20, out, &len, &rsa_params, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (salted) failed, %d, %d", stat, stat2); @@ -681,17 +731,19 @@ print_hex("q", tmp, len); rsa_free(&privKey); return 1; } + rsa_params.params.saltlen = 0; /* sign a message with PKCS #1 v1.5 */ len = sizeof(out); - DO(rsa_sign_hash_ex(in, 20, out, &len, LTC_PKCS_1_V1_5, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); - DO(rsa_verify_hash_ex(out, len, in, 20, LTC_PKCS_1_V1_5, hash_idx, 8, &stat, &pubKey)); + rsa_params.padding = LTC_PKCS_1_V1_5; + DO(rsa_sign_hash_v2(in, 20, out, &len, &rsa_params, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash_ex(out, len, in, 20, LTC_PKCS_1_V1_5, hash_idx, 8, &stat2, &pubKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { - fprintf(stderr, "rsa_verify_hash_ex failed, %d, %d", stat, stat2); + fprintf(stderr, "rsa_verify_hash_v2 failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); @@ -717,14 +769,14 @@ print_hex("q", tmp, len); p = in; p2 = out; p3 = tmp; - for (i = 0; i < 9; ++i) { + for (i = 0; i < 10; ++i) { len = sizeof(in); len2 = sizeof(out); /* (1) */ - DO(rsa_sign_hash_ex(p, 20, p2, &len2, LTC_PKCS_1_V1_5, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); + DO(rsa_sign_hash_v2(p, 20, p2, &len2, &rsa_params, &privKey)); /* (2) */ - DOX(rsa_verify_hash_ex(p2, len2, p, 20, LTC_PKCS_1_V1_5, hash_idx, -1, &stat, &pubKey), "should succeed"); - DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, "should succeed"); + DOX(rsa_verify_hash_v2(p2, len2, p, 20, &rsa_params, &stat, &pubKey), "should succeed"); + ENSURE(stat == 1); len3 = sizeof(tmp); /* (3) */ DO(ltc_mp.rsa_me(p2, len2, p3, &len3, PK_PUBLIC, &key)); @@ -757,8 +809,11 @@ print_hex("q", tmp, len); len3 = sizeof(tmp); /* (6) */ - SHOULD_FAIL(rsa_verify_hash_ex(p2, len2, p, 20, LTC_PKCS_1_V1_5, hash_idx, -1, &stat, &pubKey)); - DOX(stat == 0?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, "should fail"); + if (i < 8) + SHOULD_FAIL(rsa_verify_hash_v2(p2, len2, p, 20, &rsa_params, &stat, &pubKey)); + else + DO(rsa_verify_hash_v2(p2, len2, p, 20, &rsa_params, &stat, &pubKey)); + ENSURE(stat == 0); } rsa_free(&key); diff --git a/tests/sources.cmake b/tests/sources.cmake index 590607aa4..b6eed361f 100644 --- a/tests/sources.cmake +++ b/tests/sources.cmake @@ -5,6 +5,7 @@ base64_test.c bcrypt_test.c cipher_hash_test.c common.c +deprecated_test.c der_test.c dh_test.c dsa_test.c diff --git a/tests/test.c b/tests/test.c index 836720c63..e77b292cd 100644 --- a/tests/test.c +++ b/tests/test.c @@ -37,6 +37,7 @@ static const test_function test_functions[] = LTC_TEST_FN(file_test), LTC_TEST_FN(multi_test), LTC_TEST_FN(pem_test), + LTC_TEST_FN(deprecated_test), /* keep the prng_test always at the end as * it has to be handled specially when * testing with LTC_PTHREAD enabled diff --git a/tests/tomcrypt_test.h b/tests/tomcrypt_test.h index c2a582e7d..6761b22f9 100644 --- a/tests/tomcrypt_test.h +++ b/tests/tomcrypt_test.h @@ -4,6 +4,7 @@ #ifndef TOMCRYPT_TEST_H_ #define TOMCRYPT_TEST_H_ +#define LTC_DEPRECATED(x) #include "tomcrypt_private.h" #include "common.h" @@ -45,6 +46,7 @@ int ssh_test(void); int bcrypt_test(void); int no_null_termination_check_test(void); int pk_oid_test(void); +int deprecated_test(void); #ifdef LTC_PKCS_1 struct ltc_prng_descriptor* no_prng_desc_get(void);