فهرست منبع

Merge pull request #705 from libtom/new-ecc-api

New ECC API
Steffen Jaeckel 3 هفته پیش
والد
کامیت
eda303df0f

+ 1 - 0
.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' }

+ 8 - 4
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);
           }

+ 123 - 117
doc/crypt.tex

@@ -5812,144 +5812,97 @@ by the size of the hash, or the size of the key, whichever is smaller.  For exam
 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 @@ extract the recovery id from such a signature in order to use this function.
 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 @@ The following signature formats are suported:
 \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 @@ The \code{LTC\_ECCSIG\_ETH27} format is based on the Ethereum Yellow Paper, see
 (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 @@ Since the function is given the entire RSA key (for private keys only) CRT is po
 
 \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

+ 12 - 0
libtomcrypt_VS2008.vcproj

@@ -1387,6 +1387,10 @@
 				RelativePath="src\misc\crc32.c"
 				>
 			</File>
+			<File
+				RelativePath="src\misc\deprecated.c"
+				>
+			</File>
 			<File
 				RelativePath="src\misc\error_to_string.c"
 				>
@@ -2530,6 +2534,10 @@
 					RelativePath="src\pk\ecc\ecc_sign_hash_rfc7518.c"
 					>
 				</File>
+				<File
+					RelativePath="src\pk\ecc\ecc_sign_hash_x962.c"
+					>
+				</File>
 				<File
 					RelativePath="src\pk\ecc\ecc_sizes.c"
 					>
@@ -2558,6 +2566,10 @@
 					RelativePath="src\pk\ecc\ecc_verify_hash_rfc7518.c"
 					>
 				</File>
+				<File
+					RelativePath="src\pk\ecc\ecc_verify_hash_x962.c"
+					>
+				</File>
 				<File
 					RelativePath="src\pk\ecc\ltc_ecc_export_point.c"
 					>

+ 22 - 21
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 \

+ 22 - 21
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 \

+ 22 - 21
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 \

+ 22 - 21
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 \

+ 3 - 0
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

+ 80 - 56
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

+ 54 - 3
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);

+ 3 - 0
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"
     ;

+ 82 - 0
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 */

+ 0 - 1
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;

+ 8 - 6
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);

+ 3 - 3
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;
    }

+ 0 - 2
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; }

+ 0 - 1
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:

+ 31 - 23
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

+ 9 - 5
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;
 }

+ 8 - 8
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:

+ 3 - 4
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,

+ 5 - 26
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 @@ error:
    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

+ 44 - 0
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

+ 31 - 22
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

+ 1 - 1
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
 */
 

+ 2 - 12
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)
 {

+ 37 - 0
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

+ 48 - 0
tests/deprecated_test.c

@@ -0,0 +1,48 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+#define LTC_DEPRECATED(x)
+#include  <tomcrypt_test.h>
+
+#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;
+}

+ 97 - 54
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));
 

+ 1 - 0
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

+ 1 - 0
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

+ 1 - 0
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);