diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index bac91dea0..14be6ec0a 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -52,6 +52,7 @@ jobs:
- { BUILDNAME: 'NO_FAST', BUILDOPTIONS: '-DLTC_NO_FAST', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'NO_FAST+SMALL+NO_TABLES', BUILDOPTIONS: '-DLTC_NO_FAST -DLTC_SMALL_CODE -DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'NO_ASM', BUILDOPTIONS: '-DLTC_NO_ASM', BUILDSCRIPT: '.ci/run.sh' }
+ - { BUILDNAME: 'NO_DEPRECATED_APIS', BUILDOPTIONS: '-DLTC_NO_DEPRECATED_APIS', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'NO_TIMING_RESISTANCE', BUILDOPTIONS: '-DLTC_NO_ECC_TIMING_RESISTANT -DLTC_NO_RSA_BLINDING', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'FORTUNA_CUSTOM_OPTIONS', BUILDOPTIONS: '-DLTC_FORTUNA_USE_ENCRYPT_ONLY -DLTC_FORTUNA_RESEED_RATELIMIT_STATIC', BUILDSCRIPT: '.ci/run.sh' }
- { BUILDNAME: 'PTHREAD', BUILDOPTIONS: '-DLTC_PTHREAD', BUILDSCRIPT: '.ci/run.sh' }
diff --git a/demos/timing.c b/demos/timing.c
index 52dd11522..572756dda 100644
--- a/demos/timing.c
+++ b/demos/timing.c
@@ -872,7 +872,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 +898,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 +974,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 +992,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/doc/crypt.tex b/doc/crypt.tex
index 2359b368a..9d30cbb56 100644
--- a/doc/crypt.tex
+++ b/doc/crypt.tex
@@ -5812,144 +5812,97 @@ \subsection{ANSI X9.63 Import (deprecated)}
P--192 key, you have in effect 96--bits of security. The library will not warn you if you make this mistake, so it
is important to check yourself before using the signatures.
-\subsection{Signature Generation}
-To sign a message digest (hash) use the following function:
+\subsection{Signature Options}
-\index{ecc\_sign\_hash()}
-\index{ECC\_SET\_RFC6979\_HASH\_ALG()}
+The library supports ECDSA signatures in the following formats.
+
+\index{ecc\_signature\_type}
+\begin{small}
\begin{verbatim}
-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);
+typedef enum ecc_signature_type {
+ /* ASN.1 encoded, ANSI X9.62 */
+ LTC_ECCSIG_ANSIX962 = 0x0,
+ /* raw R, S values */
+ LTC_ECCSIG_RFC7518 = 0x1,
+ /* raw R, S, V (+27) values */
+ LTC_ECCSIG_ETH27 = 0x2,
+ /* SSH + ECDSA signature format defined by RFC5656 */
+ LTC_ECCSIG_RFC5656 = 0x3,
+} ecc_signature_type;
\end{verbatim}
+\end{small}
-This function will \textit{ECDSA} sign the message digest stored in the array pointed to by \code{in} of length \code{inlen} octets. The signature
-will be stored in the array pointed to by \code{out} of length \code{outlen} octets. The function requires that the \textit{ECC}
-\code{key} provided must be a private key.
-
-In order to execute standard \textit{ECDSA} it requires a properly seeded \textit{PRNG} which gets passed via \code{prng} and \code{wprng}.
-
-The deterministic signature mechanism according to \textit{RFC6979} is also supported. This does not require a \textit{PRNG}, but
-instead a valid hash function shall be set via the macro
-
-\code{ECC\_SET\_RFC6979\_HASH\_ALG(key, hash\_alg)}
+c.f. Chapter \ref{sigformat} for further details.
-The expected types of the arguments to that macro are \code{(ecc\_key*, const char*)}.
+To parametrize the signature API, a specific type \code{ltc\_ecc\_sig\_opts} exists, which must be populated with the desired values.
-\index{ecc\_sign\_hash\_rfc7518()}
+\index{ltc\_ecc\_sig\_opts}
+\begin{small}
\begin{verbatim}
-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);
-\end{verbatim}
+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;
-This function creates the same \textit{ECDSA} signature as \code{ecc\_sign\_hash()} only the output format is different.
-The format follows \url{https://tools.ietf.org/html/rfc7518#section-3.4}, sometimes it is also called plain signature.
+ /** Enable generation of a recovery ID.
+ * This must be set in case one requires the recovery ID of a
+ * signature operation.
+ */
+ int *recid;
-\index{ecc\_sign\_hash\_rfc7518\_ex()}
-\begin{verbatim}
-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);
+ /** 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;
\end{verbatim}
+\end{small}
-This function is an extended version of the \textit{ECDSA} signature in \code{ecc\_sign\_hash\_rfc7518()}, but with an additional output of the recovery ID
-for use with \code{ecc\_recover\_key()}.
+\subsection{Signature Generation}
+\label{ecc-sign}
+To sign a message digest (hash) use the following function:
-\index{ecc\_sign\_hash\_rfc5656()}
+\index{ecc\_sign\_hash\_v2()}
\begin{verbatim}
-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_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);
\end{verbatim}
-This function creates an \textit{ECDSA} signature and the output format is according to \textit{RFC5656}, i.e. \textit{SSH} compatible.
+This function will \textit{ECDSA} sign the message digest stored in the array pointed to by \code{in} of length \code{inlen} octets. The signature
+will be stored in the array pointed to by \code{out} of length \code{outlen} octets. The function requires that the \textit{ECC}
+\code{key} provided must be a private key.
-\index{ecc\_sign\_hash\_eth27()}
-\begin{verbatim}
-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);
-\end{verbatim}
+In order to execute standard \textit{ECDSA} it requires a properly seeded \textit{PRNG} which gets passed via \code{opts.prng} and \code{opts.wprng}.
-This function creates an \textit{ECDSA} signature and the output format is according to the Ethereum format.
-With this API the curve is limited to \textit{secp256k1}.
+The deterministic signature mechanism according to \textit{RFC6979} is also supported. This does not require a \textit{PRNG}, but
+instead a valid hash function name shall be set in the options' field \code{opts.rfc6979\_hash\_alg}.
\subsection{Signature Verification}
-\index{ecc\_verify\_hash()}
-\begin{verbatim}
-int ecc_verify_hash(const unsigned char *sig,
- unsigned long siglen,
- const unsigned char *hash,
- unsigned long hashlen,
- int *stat,
- const ecc_key *key);
+\label{ecc-verify}
+\index{ecc\_verify\_hash\_v2()}
+\begin{verbatim}
+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);
\end{verbatim}
This function will verify the \textit{ECDSA} signature in the array pointed to by \code{sig} of length \code{siglen} octets, against the message digest
pointed to by the array \code{hash} of length \code{hashlen}. It will store a non--zero value in \code{stat} if the signature is valid. Note:
the function will not return an error if the signature is invalid. It will return an error, if the actual signature payload is an invalid format.
The \textit{ECC} \code{key} must be the public (or private) \textit{ECC} key corresponding to the key that performed the signature.
-The function \code{ecc\_verify\_hash()} implements signature format according to \textit{ANSI X9.62} EC\textit{DSA}, and the output is compliant for GF(p) curves.
-
-\index{ecc\_verify\_hash\_rfc7518()}
-\begin{verbatim}
-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);
-\end{verbatim}
-
-This function validates the \textit{ECDSA} signature as \code{ecc\_verify\_hash()}, only the signature input format
-follows \url{https://tools.ietf.org/html/rfc7518#section-3.4}.
-
-\index{ecc\_verify\_hash\_rfc5656()}
-\begin{verbatim}
-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);
-\end{verbatim}
-
-This function validates the \textit{ECDSA} signature according to the format defined in \textit{RFC5656}, i.e. \textit{SSH} compatible.
-
-
-\index{ecc\_verify\_hash\_eth27()}
-\begin{verbatim}
-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);
-\end{verbatim}
-
-This function validates the \textit{ECDSA} signature according to the Ethereum format.
\subsection{Public Key Recovery}
\index{ecc\_recover\_key()}
@@ -5977,6 +5930,7 @@ \subsection{Public Key Recovery}
The function \code{ecc\_recover\_key()} implements multiple signature formats, and the output is compliant for GF(p) curves.
\subsection{Signature Formats}
+\label{sigformat}
The following signature formats are suported:
\begin{figure}[hpbt]
@@ -5985,10 +5939,10 @@ \subsection{Signature Formats}
\begin{center}
\begin{tabular}{|l|l|}
\hline \textbf{sigformat} & \textbf{description} \\
-\hline LTC\_ECCSIG\_ANSIX962 & ASN.1 encoded, \textit{ANSI X9.62} \\
-\hline LTC\_ECCSIG\_RFC7518 & raw R, S values as defined in \textit{RFC7518} \\
-\hline LTC\_ECCSIG\_ETH27 & raw R, S, V values (V has 27 added) \\
-\hline LTC\_ECCSIG\_RFC5656 & \textit{SSH+ECDSA} format as defined in \textit{RFC5656} \\
+\hline \code{LTC\_ECCSIG\_ANSIX962} & ASN.1 encoded, \textit{ANSI X9.62} \\
+\hline \code{LTC\_ECCSIG\_RFC7518} & raw R, S values as defined in \textit{RFC7518} \\
+\hline \code{LTC\_ECCSIG\_ETH27} & raw R, S, V values (V has 27 added) \\
+\hline \code{LTC\_ECCSIG\_RFC5656} & \textit{SSH+ECDSA} format as defined in \textit{RFC5656} \\
\hline
\end{tabular}
\end{center}
@@ -6001,6 +5955,8 @@ \subsection{Signature Formats}
(Appendix F). However, convention allows the use of v=0,1 as equivalent to v=27,28 and both are accepted by
\code{ecc\_recover\_key()}.
+When using \code{LTC\_ECCSIG\_ETH27} the curve is limited to \textit{secp256k1}.
+
\textbf{NOTE:} If you're using a tailored version of libtomcrypt, it is possible to disable \code{LTC\_DER} which will disable
the option to use \code{LTC\_ECCSIG\_ANSIX962}. Also it is possible to disable \code{LTC\_SSH} which will disable
the option to use \code{LTC\_ECCSIG\_RFC5656}.
@@ -10369,6 +10325,56 @@ \subsection{RSA Functions}
\mysection{Deprecated API functions}
+\subsection{Elliptic Curve Cryptography - $GF(p)$}
+
+\index{ecc\_sign\_hash()}
+\begin{verbatim}
+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);
+\end{verbatim}
+
+\index{ecc\_sign\_hash\_rfc7518()}
+\begin{verbatim}
+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);
+\end{verbatim}
+
+These two ECC sign functions have been deprecated in favor of \code{ecc\_sign\_hash\_v2()}.
+Please check Chapter \ref{ecc-sign} for details.
+
+\index{ecc\_verify\_hash()}
+\begin{verbatim}
+int ecc_verify_hash(const unsigned char *sig,
+ unsigned long siglen,
+ const unsigned char *hash,
+ unsigned long hashlen,
+ int *stat,
+ const ecc_key *key);
+\end{verbatim}
+
+\index{ecc\_verify\_hash\_rfc7518()}
+\begin{verbatim}
+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);
+\end{verbatim}
+
+These two ECC verify functions have been deprecated in favor of \code{ecc\_verify\_hash\_v2()}.
+Please check Chapter \ref{ecc-verify} for details.
+
\clearpage
\addcontentsline{toc}{chapter}{Index}
\printindex
diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj
index 72d7fb779..66375779f 100644
--- a/libtomcrypt_VS2008.vcproj
+++ b/libtomcrypt_VS2008.vcproj
@@ -1387,6 +1387,10 @@
RelativePath="src\misc\crc32.c"
>
+
+
@@ -2530,6 +2534,10 @@
RelativePath="src\pk\ecc\ecc_sign_hash_rfc7518.c"
>
+
+
@@ -2558,6 +2566,10 @@
RelativePath="src\pk\ecc\ecc_verify_hash_rfc7518.c"
>
+
+
diff --git a/makefile.mingw b/makefile.mingw
index 1c323f103..78052f913 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 \
@@ -194,18 +194,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 +234,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..552247f07 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 \
@@ -187,18 +187,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 +227,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..e3314b793 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 \
@@ -208,18 +208,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 +248,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..99be1ef74 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 \
@@ -379,18 +379,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 +424,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..38397f325 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
@@ -431,6 +432,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 +440,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_pk.h b/src/headers/tomcrypt_pk.h
index 72e4f992c..a6b893128 100644
--- a/src/headers/tomcrypt_pk.h
+++ b/src/headers/tomcrypt_pk.h
@@ -281,20 +281,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 +295,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 +352,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 +376,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 +420,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 +438,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_private.h b/src/headers/tomcrypt_private.h
index c0edbb912..fee3c84dd 100644
--- a/src/headers/tomcrypt_private.h
+++ b/src/headers/tomcrypt_private.h
@@ -441,15 +441,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);
diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c
index 61b5cd050..fdea4f633 100644
--- a/src/misc/crypt/crypt.c
+++ b/src/misc/crypt/crypt.c
@@ -580,6 +580,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..051ce7ed4
--- /dev/null
+++ b/src/misc/deprecated.c
@@ -0,0 +1,82 @@
+/* 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 */
+
+#endif /* LTC_NO_DEPRECATED_APIS */
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/tests/deprecated_test.c b/tests/deprecated_test.c
new file mode 100644
index 000000000..f2ed3638b
--- /dev/null
+++ b/tests/deprecated_test.c
@@ -0,0 +1,48 @@
+/* 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
+
+int deprecated_test(void)
+{
+#ifdef LTC_MECC
+ s_ecc_test();
+#endif
+ return 0;
+}
diff --git a/tests/ecc_test.c b/tests/ecc_test.c
index b70666590..4561bb680 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,32 @@ 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;
+#ifdef LTC_ECC_SHAMIR
+ unsigned long k;
+#endif
+ 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 +629,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 (k = 0; k < 2*(1+privkey.dp.cofactor); k++) {
+ recid = k;
+ 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 +1016,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 +1048,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 +1935,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 +1947,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 +1995,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 +2011,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 +2056,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/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..4488a450c 100644
--- a/tests/tomcrypt_test.h
+++ b/tests/tomcrypt_test.h
@@ -45,6 +45,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);