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);