Skip to content

Commit a6b9aff

Browse files
authored
Merge pull request #450 from libtom/pr/ecdsa-der-attempt1
Fix #449 (ECDSA forcing DER/ASN.1)
2 parents c996610 + 46f33c6 commit a6b9aff

31 files changed

+964
-452
lines changed

doc/crypt.tex

Lines changed: 97 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
\documentclass[synpaper]{book}
2+
\usepackage[T1]{fontenc}
23
\usepackage{geometry}
34
\usepackage{hyperref}
45
\usepackage{makeidx}
@@ -44,6 +45,7 @@
4445
\def\C{{\mathbb C}}
4546
\def\Q{{\mathbb Q}}
4647
\definecolor{DGray}{gray}{0.5}
48+
\newcommand{\code}[1]{\texttt{\textit{#1}}}
4749
\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}}
4850
\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
4951
\def\gap{\vspace{0.5ex}}
@@ -5801,8 +5803,14 @@ \subsection{ANSI X9.63 Import (deprecated)}
58015803

58025804

58035805
\mysection{Signatures (ECDSA)}
5804-
There are also functions to sign and verify messages. They use the ANSI X9.62 ECDSA algorithm to generate and verify signatures in the
5805-
ANSI X9.62 format.
5806+
There are also functions to sign and verify messages. They use the \textit{ANSI X9.62} \textit{ECDSA} algorithm to generate and verify signatures in the
5807+
\textit{ANSI X9.62} format.
5808+
5809+
\textbf{BEWARE:} With \textit{ECC} if you try to sign a hash that is bigger than your \textit{ECC} key you can run into problems. The math
5810+
will still work, and in effect the signature will still work. With \textit{ECC} keys the strength of the signature is limited
5811+
by the size of the hash, or the size of the key, whichever is smaller. For example, if you sign with SHA256 and a
5812+
P--192 key, you have in effect 96--bits of security. The library will not warn you if you make this mistake, so it
5813+
is important to check yourself before using the signatures.
58065814

58075815
\subsection{Signature Generation}
58085816
To sign a message digest (hash) use the following function:
@@ -5815,12 +5823,12 @@ \subsection{Signature Generation}
58155823
unsigned long *outlen,
58165824
prng_state *prng,
58175825
int wprng,
5818-
ecc_key *key);
5826+
const ecc_key *key);
58195827
\end{verbatim}
58205828

5821-
This function will ECDSA sign the message digest stored in the array pointed to by \textit{in} of length \textit{inlen} octets. The signature
5822-
will be stored in the array pointed to by \textit{out} of length \textit{outlen} octets. The function requires a properly seeded PRNG, and
5823-
the ECC \textit{key} provided must be a private key.
5829+
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
5830+
will be stored in the array pointed to by \code{out} of length \code{outlen} octets. The function requires a properly seeded \textit{PRNG}, and
5831+
the \textit{ECC} \code{key} provided must be a private key.
58245832

58255833
\index{ecc\_sign\_hash\_rfc7518()}
58265834
\begin{verbatim}
@@ -5830,27 +5838,53 @@ \subsection{Signature Generation}
58305838
unsigned long *outlen,
58315839
prng_state *prng,
58325840
int wprng,
5833-
ecc_key *key);
5841+
const ecc_key *key);
58345842
\end{verbatim}
58355843

5836-
This function creates the same ECDSA signature as \textit{ecc\_sign\_hash} only the output format is different.
5844+
This function creates the same \textit{ECDSA} signature as \code{ecc\_sign\_hash()} only the output format is different.
58375845
The format follows \url{https://tools.ietf.org/html/rfc7518#section-3.4}, sometimes it is also called plain signature.
58385846

5839-
\index{ecc\_sign\_hash\_ex()}
5847+
\index{ecc\_sign\_hash\_rfc7518\_ex()}
58405848
\begin{verbatim}
5841-
int ecc_sign_hash_ex(const unsigned char *in,
5842-
unsigned long inlen,
5843-
unsigned char *out,
5844-
unsigned long *outlen,
5845-
prng_state *prng,
5846-
int wprng,
5847-
ecc_signature_type sigformat,
5848-
int *recid,
5849-
ecc_key *key);
5849+
int ecc_sign_hash_rfc7518_ex(const unsigned char *in,
5850+
unsigned long inlen,
5851+
unsigned char *out,
5852+
unsigned long *outlen,
5853+
prng_state *prng,
5854+
int wprng,
5855+
int *recid,
5856+
const ecc_key *key);
5857+
\end{verbatim}
5858+
5859+
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
5860+
for use with \code{ecc\_recover\_key()}.
5861+
5862+
\index{ecc\_sign\_hash\_rfc5656()}
5863+
\begin{verbatim}
5864+
int ecc_sign_hash_rfc5656(const unsigned char *in,
5865+
unsigned long inlen,
5866+
unsigned char *out,
5867+
unsigned long *outlen,
5868+
prng_state *prng,
5869+
int wprng,
5870+
const ecc_key *key);
5871+
\end{verbatim}
5872+
5873+
This function creates an \textit{ECDSA} signature and the output format is according to \textit{RFC5656}, i.e. \textit{SSH} compatible.
5874+
5875+
\index{ecc\_sign\_hash\_eth27()}
5876+
\begin{verbatim}
5877+
int ecc_sign_hash_eth27(const unsigned char *in,
5878+
unsigned long inlen,
5879+
unsigned char *out,
5880+
unsigned long *outlen,
5881+
prng_state *prng,
5882+
int wprng,
5883+
const ecc_key *key);
58505884
\end{verbatim}
58515885

5852-
This function is an extended version of the ECDSA signature in \textit{ecc\_sign\_hash}, but with a choice of output formats
5853-
and an optional output of the recovery ID for use with \textit{ecc\_recover\_key}.
5886+
This function creates an \textit{ECDSA} signature and the output format is according to the Ethereum format.
5887+
With this API the curve is limited to \textit{secp256k1}.
58545888

58555889
\subsection{Signature Verification}
58565890
\index{ecc\_verify\_hash()}
@@ -5860,14 +5894,14 @@ \subsection{Signature Verification}
58605894
const unsigned char *hash,
58615895
unsigned long hashlen,
58625896
int *stat,
5863-
ecc_key *key);
5897+
const ecc_key *key);
58645898
\end{verbatim}
58655899

5866-
This function will verify the ECDSA signature in the array pointed to by \textit{sig} of length \textit{siglen} octets, against the message digest
5867-
pointed to by the array \textit{hash} of length \textit{hashlen}. It will store a non--zero value in \textit{stat} if the signature is valid. Note:
5900+
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
5901+
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:
58685902
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.
5869-
The ECC \textit{key} must be the public (or private) ECC key corresponding to the key that performed the signature.
5870-
The function \textit{ecc\_verify\_hash} implements signature format according to X9.62 ECDSA, and the output is compliant for GF(p) curves.
5903+
The \textit{ECC} \code{key} must be the public (or private) \textit{ECC} key corresponding to the key that performed the signature.
5904+
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.
58715905

58725906
\index{ecc\_verify\_hash\_rfc7518()}
58735907
\begin{verbatim}
@@ -5876,30 +5910,36 @@ \subsection{Signature Verification}
58765910
const unsigned char *hash,
58775911
unsigned long hashlen,
58785912
int *stat,
5879-
ecc_key *key);
5913+
const ecc_key *key);
58805914
\end{verbatim}
58815915

5882-
This function validate the ECDSA signature as \textit{ecc\_verify\_hash} only the signature input format
5916+
This function validates the \textit{ECDSA} signature as \code{ecc\_verify\_hash()}, only the signature input format
58835917
follows \url{https://tools.ietf.org/html/rfc7518#section-3.4}.
58845918

5885-
\index{ecc\_verify\_hash\_ex()}
5919+
\index{ecc\_verify\_hash\_rfc5656()}
58865920
\begin{verbatim}
5887-
int ecc_verify_hash_ex(const unsigned char *sig,
5888-
unsigned long siglen,
5889-
const unsigned char *hash,
5890-
unsigned long hashlen,
5891-
ecc_signature_type sigformat,
5892-
int *stat,
5893-
ecc_key *key);
5921+
int ecc_verify_hash_rfc5656(const unsigned char *sig,
5922+
unsigned long siglen,
5923+
const unsigned char *hash,
5924+
unsigned long hashlen,
5925+
int *stat,
5926+
const ecc_key *key);
58945927
\end{verbatim}
58955928

5896-
This function validates an ECDSA signature as \textit{ecc\_verify\_hash} but with a choice of signature formats.
5929+
This function validates the \textit{ECDSA} signature according to the format defined in \textit{RFC5656}, i.e. \textit{SSH} compatible.
58975930

5898-
{\bf BEWARE:} With ECC if you try to sign a hash that is bigger than your ECC key you can run into problems. The math
5899-
will still work, and in effect the signature will still work. With ECC keys the strength of the signature is limited
5900-
by the size of the hash, or the size of the key, whichever is smaller. For example, if you sign with SHA256 and a
5901-
P--192 key, you have in effect 96--bits of security. The library will not warn you if you make this mistake, so it
5902-
is important to check yourself before using the signatures.
5931+
5932+
\index{ecc\_verify\_hash\_eth27()}
5933+
\begin{verbatim}
5934+
int ecc_verify_hash_eth27(const unsigned char *sig,
5935+
unsigned long siglen,
5936+
const unsigned char *hash,
5937+
unsigned long hashlen,
5938+
int *stat,
5939+
const ecc_key *key);
5940+
\end{verbatim}
5941+
5942+
This function validates the \textit{ECDSA} signature according to the Ethereum format.
59035943

59045944
\subsection{Public Key Recovery}
59055945
\index{ecc\_recover\_key()}
@@ -5913,18 +5953,18 @@ \subsection{Public Key Recovery}
59135953
ecc_key *key);
59145954
\end{verbatim}
59155955

5916-
This function will recover (a) public key from the ECDSA signature in the array pointed to by \textit{sig} of length \textit{siglen} octets, the message digest
5917-
pointed to by the array \textit{hash} of length \textit{hashlen}, and the recovery id \textit{recid}. It will store the recovered
5918-
key into \textit{key} and return CRYPT\_OK if recovery succeeds, or an error if recovery fails.
5956+
This function will recover (a) public key from the \textit{ECDSA} signature in the array pointed to by \code{sig} of length \code{siglen} octets, the message digest
5957+
pointed to by the array \code{hash} of length \code{hashlen}, and the recovery id \code{recid}. It will store the recovered
5958+
key into \code{key} and return \code{CRYPT\_OK} if recovery succeeds, or an error if recovery fails.
59195959
This is for compatibility with the (v,r,s) signatures used in Ethereum, where public keys are not explicitly shared,
5920-
only the parity of the public key. For curves like secp256k1, recid will take values of 0 or 1, corresponding to the
5921-
parity of the public key's y coordinate. For curves like secp112r2, with a cofactor of 4, values 0..7 are possible,
5960+
only the parity of the public key. For curves like \textit{secp256k1}, \code{recid} will take values of 0 or 1, corresponding to the
5961+
parity of the public key's y coordinate. For curves like \textit{secp112r2}, with a cofactor of 4, values 0..7 are possible,
59225962
with the low bit corresponding to the parity and the higher bits specifying the public key's x coordinate's multiple
59235963
of the curve's order.
5924-
If the signature format contains the recovery id (currently only \textit{LTC\_ECCSIG\_ETH27}), \textit{recid} can be -1
5964+
If the signature format contains the recovery id (currently only \code{LTC\_ECCSIG\_ETH27}), \code{recid} can be -1
59255965
which signals that the recovery id from the signature blob should be used. This means an application does not need to
59265966
extract the recovery id from such a signature in order to use this function.
5927-
The function \textit{ecc\_recover\_key} implements multiple signature formats, and the output is compliant for GF(p) curves.
5967+
The function \code{ecc\_recover\_key()} implements multiple signature formats, and the output is compliant for GF(p) curves.
59285968

59295969
\subsection{Signature Formats}
59305970
The following signature formats are suported:
@@ -5935,10 +5975,10 @@ \subsection{Signature Formats}
59355975
\begin{center}
59365976
\begin{tabular}{|l|l|}
59375977
\hline \textbf{sigformat} & \textbf{description} \\
5938-
\hline LTC\_ECCSIG\_ANSIX962 & ASN.1 encoded, ANSI X9.62 \\
5939-
\hline LTC\_ECCSIG\_RFC7518 & raw R, S values as defined in RFC7518 \\
5978+
\hline LTC\_ECCSIG\_ANSIX962 & ASN.1 encoded, \textit{ANSI X9.62} \\
5979+
\hline LTC\_ECCSIG\_RFC7518 & raw R, S values as defined in \textit{RFC7518} \\
59405980
\hline LTC\_ECCSIG\_ETH27 & raw R, S, V values (V has 27 added) \\
5941-
\hline LTC\_ECCSIG\_RFC5656 & SSH+ECDSA format as defined in RFC5656 \\
5981+
\hline LTC\_ECCSIG\_RFC5656 & \textit{SSH+ECDSA} format as defined in \textit{RFC5656} \\
59425982
\hline
59435983
\end{tabular}
59445984
\end{center}
@@ -5947,9 +5987,13 @@ \subsection{Signature Formats}
59475987
\label{fig:sigformat}
59485988
\end{figure}
59495989

5950-
The \textit{LTC\_ECCSIG\_ETH27} format is based on the Ethereum Yellow Paper, see \url{https://github.com/ethereum/yellowpaper}
5990+
The \code{LTC\_ECCSIG\_ETH27} format is based on the Ethereum Yellow Paper, see \url{https://github.com/ethereum/yellowpaper}
59515991
(Appendix F). However, convention allows the use of v=0,1 as equivalent to v=27,28 and both are accepted by
5952-
\textit{ecc\_recover\_key}.
5992+
\code{ecc\_recover\_key()}.
5993+
5994+
\textbf{NOTE:} If you're using a tailored version of libtomcrypt, it is possible to disable \code{LTC\_DER} which will disable
5995+
the option to use \code{LTC\_ECCSIG\_ANSIX962}. Also it is possible to disable \code{LTC\_SSH} which will disable
5996+
the option to use \code{LTC\_ECCSIG\_RFC5656}.
59535997

59545998
\mysection{Shared Secret (ECDH)}
59555999
To construct a Diffie-Hellman shared secret with a private and public ECC key, use the following function:

libtomcrypt_VS2008.vcproj

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,6 +2510,22 @@
25102510
RelativePath="src\pk\ecc\ecc_sign_hash.c"
25112511
>
25122512
</File>
2513+
<File
2514+
RelativePath="src\pk\ecc\ecc_sign_hash_eth27.c"
2515+
>
2516+
</File>
2517+
<File
2518+
RelativePath="src\pk\ecc\ecc_sign_hash_internal.c"
2519+
>
2520+
</File>
2521+
<File
2522+
RelativePath="src\pk\ecc\ecc_sign_hash_rfc5656.c"
2523+
>
2524+
</File>
2525+
<File
2526+
RelativePath="src\pk\ecc\ecc_sign_hash_rfc7518.c"
2527+
>
2528+
</File>
25132529
<File
25142530
RelativePath="src\pk\ecc\ecc_sizes.c"
25152531
>
@@ -2522,6 +2538,22 @@
25222538
RelativePath="src\pk\ecc\ecc_verify_hash.c"
25232539
>
25242540
</File>
2541+
<File
2542+
RelativePath="src\pk\ecc\ecc_verify_hash_eth27.c"
2543+
>
2544+
</File>
2545+
<File
2546+
RelativePath="src\pk\ecc\ecc_verify_hash_internal.c"
2547+
>
2548+
</File>
2549+
<File
2550+
RelativePath="src\pk\ecc\ecc_verify_hash_rfc5656.c"
2551+
>
2552+
</File>
2553+
<File
2554+
RelativePath="src\pk\ecc\ecc_verify_hash_rfc7518.c"
2555+
>
2556+
</File>
25252557
<File
25262558
RelativePath="src\pk\ecc\ltc_ecc_export_point.c"
25272559
>

makefile.mingw

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,12 @@ src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.
193193
src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o \
194194
src/pk/ecc/ecc_recover_key.o src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o \
195195
src/pk/ecc/ecc_set_key.o src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o \
196-
src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o \
197-
src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
196+
src/pk/ecc/ecc_sign_hash_eth27.o src/pk/ecc/ecc_sign_hash_internal.o \
197+
src/pk/ecc/ecc_sign_hash_rfc5656.o src/pk/ecc/ecc_sign_hash_rfc7518.o src/pk/ecc/ecc_sizes.o \
198+
src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ecc_verify_hash_eth27.o \
199+
src/pk/ecc/ecc_verify_hash_internal.o src/pk/ecc/ecc_verify_hash_rfc5656.o \
200+
src/pk/ecc/ecc_verify_hash_rfc7518.o src/pk/ecc/ltc_ecc_export_point.o \
201+
src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
198202
src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \
199203
src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
200204
src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \

makefile.msvc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,12 @@ src/pk/ecc/ecc_get_size.obj src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_import_open
186186
src/pk/ecc/ecc_import_pkcs8.obj src/pk/ecc/ecc_import_x509.obj src/pk/ecc/ecc_make_key.obj \
187187
src/pk/ecc/ecc_recover_key.obj src/pk/ecc/ecc_set_curve.obj src/pk/ecc/ecc_set_curve_internal.obj \
188188
src/pk/ecc/ecc_set_key.obj src/pk/ecc/ecc_shared_secret.obj src/pk/ecc/ecc_sign_hash.obj \
189-
src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_ssh_ecdsa_encode_name.obj src/pk/ecc/ecc_verify_hash.obj \
190-
src/pk/ecc/ltc_ecc_export_point.obj src/pk/ecc/ltc_ecc_import_point.obj src/pk/ecc/ltc_ecc_is_point.obj \
189+
src/pk/ecc/ecc_sign_hash_eth27.obj src/pk/ecc/ecc_sign_hash_internal.obj \
190+
src/pk/ecc/ecc_sign_hash_rfc5656.obj src/pk/ecc/ecc_sign_hash_rfc7518.obj src/pk/ecc/ecc_sizes.obj \
191+
src/pk/ecc/ecc_ssh_ecdsa_encode_name.obj src/pk/ecc/ecc_verify_hash.obj src/pk/ecc/ecc_verify_hash_eth27.obj \
192+
src/pk/ecc/ecc_verify_hash_internal.obj src/pk/ecc/ecc_verify_hash_rfc5656.obj \
193+
src/pk/ecc/ecc_verify_hash_rfc7518.obj src/pk/ecc/ltc_ecc_export_point.obj \
194+
src/pk/ecc/ltc_ecc_import_point.obj src/pk/ecc/ltc_ecc_is_point.obj \
191195
src/pk/ecc/ltc_ecc_is_point_at_infinity.obj src/pk/ecc/ltc_ecc_map.obj src/pk/ecc/ltc_ecc_mul2add.obj \
192196
src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \
193197
src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \

makefile.unix

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,12 @@ src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.
207207
src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o \
208208
src/pk/ecc/ecc_recover_key.o src/pk/ecc/ecc_set_curve.o src/pk/ecc/ecc_set_curve_internal.o \
209209
src/pk/ecc/ecc_set_key.o src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o \
210-
src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o \
211-
src/pk/ecc/ltc_ecc_export_point.o src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
210+
src/pk/ecc/ecc_sign_hash_eth27.o src/pk/ecc/ecc_sign_hash_internal.o \
211+
src/pk/ecc/ecc_sign_hash_rfc5656.o src/pk/ecc/ecc_sign_hash_rfc7518.o src/pk/ecc/ecc_sizes.o \
212+
src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ecc_verify_hash_eth27.o \
213+
src/pk/ecc/ecc_verify_hash_internal.o src/pk/ecc/ecc_verify_hash_rfc5656.o \
214+
src/pk/ecc/ecc_verify_hash_rfc7518.o src/pk/ecc/ltc_ecc_export_point.o \
215+
src/pk/ecc/ltc_ecc_import_point.o src/pk/ecc/ltc_ecc_is_point.o \
212216
src/pk/ecc/ltc_ecc_is_point_at_infinity.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \
213217
src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
214218
src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \

0 commit comments

Comments
 (0)