Browse Source

Merge pull request #490 from libtom/improve/curve25519

Improve curve25519
Steffen Jaeckel 6 years ago
parent
commit
c23f4699fb

+ 207 - 1
doc/crypt.tex

@@ -4998,7 +4998,7 @@ done2:
 When the above code snippet is done (assuming all went well) there will be a shared 128-bit key in the ``key'' array
 When the above code snippet is done (assuming all went well) there will be a shared 128-bit key in the ``key'' array
 passed to ``establish\_secure\_socket()''.
 passed to ``establish\_secure\_socket()''.
 
 
-\chapter{Elliptic Curve Cryptography}
+\chapter{Elliptic Curve Cryptography - $GF(p)$}
 
 
 \mysection{Introduction}
 \mysection{Introduction}
 
 
@@ -5715,6 +5715,212 @@ ECCEncrypt ::= SEQUENCE {
 }
 }
 \end{verbatim}
 \end{verbatim}
 
 
+\chapter{Elliptic Curve Cryptography - $Montgomery/Twisted Edwards$}
+\mysection{Introduction}
+
+The library provides functionality for \textit{Curve25519}-based \textit{X25519} Diffie-Hellman shared secrets
+and \textit{EdDSA} a.k.a \textit{Ed25519} signature schemes.
+
+The implementation is based on the \textit{tweetnacl}\footnote{\url{https://tweetnacl.cr.yp.to/}} reference implementation
+as provided by Daniel J. Bernstein et.al. and only slightly modified to better fit in the library.
+
+Both algorithms share the key structure called \textit{curve25519\_key} which is used by all Curve25519 functions.
+
+As Curve25519 and Ed25519 are based on the same elliptic curve, but use different mathematics, the keys are not
+compatible to each other.
+
+It is possible to convert a Curve-Key to an Ed-Key and vice-versa, but this is not provided (yet).
+
+
+\mysection{Curve25519-based Diffie-Hellman Key Exchange - X25519}
+
+The library provides the Diffie-Hellman Key Exchange algorithm \textit{X25519} for curve25519 as specified in RFC 7748.
+
+\subsection{X25519 Key Operations}
+
+The \textit{X25519} algorithm API provides the following set of functions to create, import and export keys.
+
+\index{x25519\_make\_key}
+\begin{verbatim}
+int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
+\end{verbatim}
+
+To generate a fresh X25529 key, one can use \textit{x25519\_make\_key} which will create a private\&public key-pair.
+
+\index{x25519\_set\_key}
+\begin{verbatim}
+int x25519_set_key(const unsigned char *k,  unsigned long klen,
+                   const unsigned char *u,  unsigned long ulen,
+                        curve25519_key *key);
+\end{verbatim}
+
+To import a public or private key in raw format, one can use the function \textit{x25519\_set\_key}.
+In case both, the secret part \textit{k} and the public part \textit{u} are given, the operation validates that the given 
+public part fits to the secret part.
+
+\index{x25519\_import}
+\begin{verbatim}
+int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
+\end{verbatim}
+
+The \textit{x25519\_import} function can be used to import a public key in DER-encoded \textit{SubjectPublicKeyInfo} format.
+
+\index{x25519\_import\_x509}
+\begin{verbatim}
+int x25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
+\end{verbatim}
+
+To import a public key from a DER-encoded \textit{X.509} certificate, one can use the function \textit{x25519\_import\_x509}.
+
+\index{x25519\_import\_pkcs8}
+\begin{verbatim}
+int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                 const void *pwd, unsigned long pwdlen,
+                             curve25519_key *key);
+\end{verbatim}
+
+To import a private key in the \textit{OneAsymmetricKey} a.k.a \textit{PKCS \#8} format, either plain or PBES encrypted,
+one can use the function \textit{x25519\_import\_pkcs8}.
+
+\index{x25519\_export}
+\begin{verbatim}
+int x25519_export(       unsigned char *out, unsigned long *outlen,
+                                   int  which,
+                  const curve25519_key *key);
+\end{verbatim}
+
+To export a key, the function \textit{x25519\_export} is provided.
+
+It has support for the following output formats:
+
+\begin{figure}[H]
+\begin{center}
+\begin{tabular}{|c|c|}
+\hline \textbf{which} & \textbf{output format} \\
+\hline PK\_PRIVATE & Raw \\
+\hline PK\_PRIVATE \& PK\_STD & PKCS \#8 \\
+\hline PK\_PUBLIC & Raw \\
+\hline PK\_PUBLIC \& PK\_STD & SubjectPublicKeyInfo \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Possible x25519\_export() output formats}
+\end{figure}
+
+\subsection{X25519 Cryptographic Operations}
+
+To construct a Diffie-Hellman shared secret with a private and a public X25519 key, use the following function:
+
+\index{x25519\_shared\_secret}
+\begin{verbatim}
+int x25519_shared_secret(const curve25519_key *private_key,
+                         const curve25519_key *public_key,
+                                unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+
+This will construct the shared secret between the private- and the public-key and store the result in \textit{out} of length \textit{outlen}.
+
+\mysection{Curve25519-based EdDSA Signature Scheme - Ed25519}
+
+The library provides the EdDSA algorithm for the edwards25519 curve in the PureEdDSA variant as specified in RFC 8032.
+
+\subsection{EdDSA Key Operations}
+
+The \textit{Ed25519} algorithm API provides the following set of functions to create, import and export keys.
+
+\index{ed25519\_make\_key}
+\begin{verbatim}
+int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
+\end{verbatim}
+
+To generate a fresh Ed25529 key, one can use \textit{ed25519\_make\_key} which will create a private\&public key-pair.
+
+\index{ed25519\_set\_key}
+\begin{verbatim}
+int ed25519_set_key(const unsigned char *sk, unsigned long sklen,
+                    const unsigned char *pk, unsigned long pklen,
+                         curve25519_key *key);
+\end{verbatim}
+
+To import a public or private key in raw format, one can use the function \textit{ed25519\_set\_key}.
+In case both, the secret part \textit{sk} and the public part \textit{pk} are given, the operation validates that the given 
+public part fits to the secret part.
+
+\index{ed25519\_import}
+\begin{verbatim}
+int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
+\end{verbatim}
+
+The \textit{ed25519\_import} function can be used to import a public key in DER-encoded \textit{SubjectPublicKeyInfo} format.
+
+\index{ed25519\_import\_x509}
+\begin{verbatim}
+int ed25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
+\end{verbatim}
+
+To import a public key from a DER-encoded \textit{X.509} certificate, one can use the function \textit{ed25519\_import\_x509}.
+
+\index{ed25519\_import\_pkcs8}
+\begin{verbatim}
+int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                  const void *pwd, unsigned long pwdlen,
+                              curve25519_key *key);
+\end{verbatim}
+
+To import a private key in the \textit{OneAsymmetricKey} a.k.a \textit{PKCS \#8} format, either plain or PBES encrypted,
+one can use the function \textit{ed25519\_import\_pkcs8}.
+
+\index{ed25519\_export}
+\begin{verbatim}
+int ed25519_export(       unsigned char *out, unsigned long *outlen,
+                                    int  which,
+                   const curve25519_key *key);
+\end{verbatim}
+
+To export a key, the function \textit{ed25519\_export} is provided.
+
+It has support for the following output formats:
+
+\begin{figure}[H]
+\begin{center}
+\begin{tabular}{|c|c|}
+\hline \textbf{which} & \textbf{output format} \\
+\hline PK\_PRIVATE & Raw \\
+\hline PK\_PRIVATE \& PK\_STD & PKCS \#8 \\
+\hline PK\_PUBLIC & Raw \\
+\hline PK\_PUBLIC \& PK\_STD & SubjectPublicKeyInfo \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Possible ed25519\_export() output formats}
+\end{figure}
+
+\subsection{EdDSA Cryptographic Operations}
+
+To sign and/or verify a message use the following functions:
+
+\index{ed25519\_sign}
+\begin{verbatim}
+int ed25519_sign(const unsigned char  *msg, unsigned long msglen,
+                       unsigned char  *sig, unsigned long *siglen,
+                 const curve25519_key *private_key);
+\end{verbatim}
+
+This function will EdDSA sign the message stored in the array pointed to by \textit{msg} of length \textit{msglen} octets.  The signature
+will be stored in the array pointed to by \textit{sig} of length \textit{siglen} octets.
+
+\index{ed25519\_verify}
+\begin{verbatim}
+int ed25519_verify(const  unsigned char *msg, unsigned long msglen,
+                   const  unsigned char *sig, unsigned long siglen,
+                   int *stat, const curve25519_key *public_key);
+\end{verbatim}
+
+This function will verify the EdDSA signature in the array pointed to by \textit{sig} of length \textit{siglen} octets, against the message
+pointed to by the array \textit{msg} of length \textit{msglen}. It will store a non--zero value in \textit{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.
+
+
 \chapter{Digital Signature Algorithm}
 \chapter{Digital Signature Algorithm}
 \mysection{Introduction}
 \mysection{Introduction}
 The Digital Signature Algorithm (or DSA) is a variant of the ElGamal Signature scheme which has been modified to
 The Digital Signature Algorithm (or DSA) is a variant of the ElGamal Signature scheme which has been modified to

+ 17 - 1
libtomcrypt_VS2008.vcproj

@@ -2314,6 +2314,14 @@
 			<Filter
 			<Filter
 				Name="ec25519"
 				Name="ec25519"
 				>
 				>
+				<File
+					RelativePath="src\pk\ec25519\ec25519_export.c"
+					>
+				</File>
+				<File
+					RelativePath="src\pk\ec25519\ec25519_import_pkcs8.c"
+					>
+				</File>
 				<File
 				<File
 					RelativePath="src\pk\ec25519\tweetnacl.c"
 					RelativePath="src\pk\ec25519\tweetnacl.c"
 					>
 					>
@@ -2486,6 +2494,10 @@
 					RelativePath="src\pk\ed25519\ed25519_import.c"
 					RelativePath="src\pk\ed25519\ed25519_import.c"
 					>
 					>
 				</File>
 				</File>
+				<File
+					RelativePath="src\pk\ed25519\ed25519_import_pkcs8.c"
+					>
+				</File>
 				<File
 				<File
 					RelativePath="src\pk\ed25519\ed25519_import_x509.c"
 					RelativePath="src\pk\ed25519\ed25519_import_x509.c"
 					>
 					>
@@ -2618,6 +2630,10 @@
 					RelativePath="src\pk\x25519\x25519_import.c"
 					RelativePath="src\pk\x25519\x25519_import.c"
 					>
 					>
 				</File>
 				</File>
+				<File
+					RelativePath="src\pk\x25519\x25519_import_pkcs8.c"
+					>
+				</File>
 				<File
 				<File
 					RelativePath="src\pk\x25519\x25519_import_x509.c"
 					RelativePath="src\pk\x25519\x25519_import_x509.c"
 					>
 					>
@@ -2627,7 +2643,7 @@
 					>
 					>
 				</File>
 				</File>
 				<File
 				<File
-					RelativePath="src\pk\x25519\x25519_set_ku.c"
+					RelativePath="src\pk\x25519\x25519_set_key.c"
 					>
 					>
 				</File>
 				</File>
 				<File
 				<File

+ 38 - 36
makefile.mingw

@@ -179,46 +179,48 @@ src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.
 src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
 src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
 src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
 src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
 src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
 src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
-src/pk/dsa/dsa_verify_key.o src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o \
-src/pk/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o \
-src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o \
-src/pk/ecc/ecc_find_curve.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o \
-src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o \
-src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o \
-src/pk/ecc/ecc_recover_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_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.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/dsa/dsa_verify_key.o src/pk/ec25519/ec25519_export.o src/pk/ec25519/ec25519_import_pkcs8.o \
+src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o src/pk/ecc/ecc_ansi_x963_export.o \
+src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o \
+src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o src/pk/ecc/ecc_find_curve.o \
+src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o src/pk/ecc/ecc_get_size.o \
+src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o src/pk/ecc/ecc_import_pkcs8.o \
+src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_recover_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_sizes.o \
+src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.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_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_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_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/ecc/ltc_ecc_verify_key.o src/pk/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \
-src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o \
-src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o src/pk/ed25519/ed25519_verify.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 src/pk/rsa/rsa_export.o \
-src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_make_key.o \
-src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \
-src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o src/pk/x25519/x25519_import.o \
-src/pk/x25519/x25519_import_x509.o src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_ku.o \
-src/pk/x25519/x25519_shared_secret.o src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o \
-src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \
-src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o \
-src/stream/chacha/chacha_ivctr32.o src/stream/chacha/chacha_ivctr64.o \
-src/stream/chacha/chacha_keystream.o src/stream/chacha/chacha_memory.o \
-src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit.o \
-src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o src/stream/rc4/rc4_stream_memory.o \
-src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o src/stream/salsa20/salsa20_done.o \
-src/stream/salsa20/salsa20_ivctr64.o src/stream/salsa20/salsa20_keystream.o \
-src/stream/salsa20/salsa20_memory.o src/stream/salsa20/salsa20_setup.o \
-src/stream/salsa20/salsa20_test.o src/stream/salsa20/xsalsa20_memory.o \
-src/stream/salsa20/xsalsa20_setup.o src/stream/salsa20/xsalsa20_test.o \
-src/stream/sober128/sober128_stream.o src/stream/sober128/sober128_stream_memory.o \
-src/stream/sober128/sober128_test.o src/stream/sosemanuk/sosemanuk.o \
-src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o
+src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_x509.o \
+src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o \
+src/pk/ed25519/ed25519_verify.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 \
+src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \
+src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o \
+src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \
+src/pk/rsa/rsa_sign_saltlen_get.o src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o \
+src/pk/x25519/x25519_import.o src/pk/x25519/x25519_import_pkcs8.o src/pk/x25519/x25519_import_x509.o \
+src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_key.o src/pk/x25519/x25519_shared_secret.o \
+src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
+src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o \
+src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o src/stream/chacha/chacha_ivctr32.o \
+src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \
+src/stream/chacha/chacha_memory.o src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o \
+src/stream/rabbit/rabbit.o src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o \
+src/stream/rc4/rc4_stream_memory.o src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o \
+src/stream/salsa20/salsa20_done.o src/stream/salsa20/salsa20_ivctr64.o \
+src/stream/salsa20/salsa20_keystream.o src/stream/salsa20/salsa20_memory.o \
+src/stream/salsa20/salsa20_setup.o src/stream/salsa20/salsa20_test.o \
+src/stream/salsa20/xsalsa20_memory.o src/stream/salsa20/xsalsa20_setup.o \
+src/stream/salsa20/xsalsa20_test.o src/stream/sober128/sober128_stream.o \
+src/stream/sober128/sober128_stream_memory.o src/stream/sober128/sober128_test.o \
+src/stream/sosemanuk/sosemanuk.o src/stream/sosemanuk/sosemanuk_memory.o \
+src/stream/sosemanuk/sosemanuk_test.o
 
 
 #List of test objects to compile
 #List of test objects to compile
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \

+ 38 - 36
makefile.msvc

@@ -172,46 +172,48 @@ src/pk/dsa/dsa_decrypt_key.obj src/pk/dsa/dsa_encrypt_key.obj src/pk/dsa/dsa_exp
 src/pk/dsa/dsa_generate_key.obj src/pk/dsa/dsa_generate_pqg.obj src/pk/dsa/dsa_import.obj \
 src/pk/dsa/dsa_generate_key.obj src/pk/dsa/dsa_generate_pqg.obj src/pk/dsa/dsa_import.obj \
 src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_set.obj src/pk/dsa/dsa_set_pqg_dsaparam.obj \
 src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_set.obj src/pk/dsa/dsa_set_pqg_dsaparam.obj \
 src/pk/dsa/dsa_shared_secret.obj src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj \
 src/pk/dsa/dsa_shared_secret.obj src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj \
-src/pk/dsa/dsa_verify_key.obj src/pk/ec25519/tweetnacl.obj src/pk/ecc/ecc.obj \
-src/pk/ecc/ecc_ansi_x963_export.obj src/pk/ecc/ecc_ansi_x963_import.obj src/pk/ecc/ecc_decrypt_key.obj \
-src/pk/ecc/ecc_encrypt_key.obj src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_export_openssl.obj \
-src/pk/ecc/ecc_find_curve.obj src/pk/ecc/ecc_free.obj src/pk/ecc/ecc_get_key.obj src/pk/ecc/ecc_get_oid_str.obj \
-src/pk/ecc/ecc_get_size.obj src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_import_openssl.obj \
-src/pk/ecc/ecc_import_pkcs8.obj src/pk/ecc/ecc_import_x509.obj src/pk/ecc/ecc_make_key.obj \
-src/pk/ecc/ecc_recover_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_sizes.obj src/pk/ecc/ecc_ssh_ecdsa_encode_name.obj src/pk/ecc/ecc_verify_hash.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/dsa/dsa_verify_key.obj src/pk/ec25519/ec25519_export.obj src/pk/ec25519/ec25519_import_pkcs8.obj \
+src/pk/ec25519/tweetnacl.obj src/pk/ecc/ecc.obj src/pk/ecc/ecc_ansi_x963_export.obj \
+src/pk/ecc/ecc_ansi_x963_import.obj src/pk/ecc/ecc_decrypt_key.obj src/pk/ecc/ecc_encrypt_key.obj \
+src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_export_openssl.obj src/pk/ecc/ecc_find_curve.obj \
+src/pk/ecc/ecc_free.obj src/pk/ecc/ecc_get_key.obj src/pk/ecc/ecc_get_oid_str.obj src/pk/ecc/ecc_get_size.obj \
+src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_import_openssl.obj src/pk/ecc/ecc_import_pkcs8.obj \
+src/pk/ecc/ecc_import_x509.obj src/pk/ecc/ecc_make_key.obj src/pk/ecc/ecc_recover_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_sizes.obj \
+src/pk/ecc/ecc_ssh_ecdsa_encode_name.obj src/pk/ecc/ecc_verify_hash.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_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_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_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/ecc/ltc_ecc_verify_key.obj src/pk/ed25519/ed25519_export.obj src/pk/ed25519/ed25519_import.obj \
-src/pk/ed25519/ed25519_import_x509.obj src/pk/ed25519/ed25519_make_key.obj \
-src/pk/ed25519/ed25519_set_key.obj src/pk/ed25519/ed25519_sign.obj src/pk/ed25519/ed25519_verify.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 src/pk/rsa/rsa_export.obj \
-src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_get_size.obj src/pk/rsa/rsa_import.obj \
-src/pk/rsa/rsa_import_pkcs8.obj src/pk/rsa/rsa_import_x509.obj src/pk/rsa/rsa_make_key.obj \
-src/pk/rsa/rsa_set.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_sign_saltlen_get.obj \
-src/pk/rsa/rsa_verify_hash.obj src/pk/x25519/x25519_export.obj src/pk/x25519/x25519_import.obj \
-src/pk/x25519/x25519_import_x509.obj src/pk/x25519/x25519_make_key.obj src/pk/x25519/x25519_set_ku.obj \
-src/pk/x25519/x25519_shared_secret.obj src/prngs/chacha20.obj src/prngs/fortuna.obj src/prngs/rc4.obj \
-src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj \
-src/prngs/yarrow.obj src/stream/chacha/chacha_crypt.obj src/stream/chacha/chacha_done.obj \
-src/stream/chacha/chacha_ivctr32.obj src/stream/chacha/chacha_ivctr64.obj \
-src/stream/chacha/chacha_keystream.obj src/stream/chacha/chacha_memory.obj \
-src/stream/chacha/chacha_setup.obj src/stream/chacha/chacha_test.obj src/stream/rabbit/rabbit.obj \
-src/stream/rabbit/rabbit_memory.obj src/stream/rc4/rc4_stream.obj src/stream/rc4/rc4_stream_memory.obj \
-src/stream/rc4/rc4_test.obj src/stream/salsa20/salsa20_crypt.obj src/stream/salsa20/salsa20_done.obj \
-src/stream/salsa20/salsa20_ivctr64.obj src/stream/salsa20/salsa20_keystream.obj \
-src/stream/salsa20/salsa20_memory.obj src/stream/salsa20/salsa20_setup.obj \
-src/stream/salsa20/salsa20_test.obj src/stream/salsa20/xsalsa20_memory.obj \
-src/stream/salsa20/xsalsa20_setup.obj src/stream/salsa20/xsalsa20_test.obj \
-src/stream/sober128/sober128_stream.obj src/stream/sober128/sober128_stream_memory.obj \
-src/stream/sober128/sober128_test.obj src/stream/sosemanuk/sosemanuk.obj \
-src/stream/sosemanuk/sosemanuk_memory.obj src/stream/sosemanuk/sosemanuk_test.obj
+src/pk/ed25519/ed25519_import_pkcs8.obj src/pk/ed25519/ed25519_import_x509.obj \
+src/pk/ed25519/ed25519_make_key.obj src/pk/ed25519/ed25519_set_key.obj src/pk/ed25519/ed25519_sign.obj \
+src/pk/ed25519/ed25519_verify.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 \
+src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_get_size.obj \
+src/pk/rsa/rsa_import.obj src/pk/rsa/rsa_import_pkcs8.obj src/pk/rsa/rsa_import_x509.obj \
+src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_set.obj src/pk/rsa/rsa_sign_hash.obj \
+src/pk/rsa/rsa_sign_saltlen_get.obj src/pk/rsa/rsa_verify_hash.obj src/pk/x25519/x25519_export.obj \
+src/pk/x25519/x25519_import.obj src/pk/x25519/x25519_import_pkcs8.obj src/pk/x25519/x25519_import_x509.obj \
+src/pk/x25519/x25519_make_key.obj src/pk/x25519/x25519_set_key.obj src/pk/x25519/x25519_shared_secret.obj \
+src/prngs/chacha20.obj src/prngs/fortuna.obj src/prngs/rc4.obj src/prngs/rng_get_bytes.obj \
+src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj src/prngs/yarrow.obj \
+src/stream/chacha/chacha_crypt.obj src/stream/chacha/chacha_done.obj src/stream/chacha/chacha_ivctr32.obj \
+src/stream/chacha/chacha_ivctr64.obj src/stream/chacha/chacha_keystream.obj \
+src/stream/chacha/chacha_memory.obj src/stream/chacha/chacha_setup.obj src/stream/chacha/chacha_test.obj \
+src/stream/rabbit/rabbit.obj src/stream/rabbit/rabbit_memory.obj src/stream/rc4/rc4_stream.obj \
+src/stream/rc4/rc4_stream_memory.obj src/stream/rc4/rc4_test.obj src/stream/salsa20/salsa20_crypt.obj \
+src/stream/salsa20/salsa20_done.obj src/stream/salsa20/salsa20_ivctr64.obj \
+src/stream/salsa20/salsa20_keystream.obj src/stream/salsa20/salsa20_memory.obj \
+src/stream/salsa20/salsa20_setup.obj src/stream/salsa20/salsa20_test.obj \
+src/stream/salsa20/xsalsa20_memory.obj src/stream/salsa20/xsalsa20_setup.obj \
+src/stream/salsa20/xsalsa20_test.obj src/stream/sober128/sober128_stream.obj \
+src/stream/sober128/sober128_stream_memory.obj src/stream/sober128/sober128_test.obj \
+src/stream/sosemanuk/sosemanuk.obj src/stream/sosemanuk/sosemanuk_memory.obj \
+src/stream/sosemanuk/sosemanuk_test.obj
 
 
 #List of test objects to compile
 #List of test objects to compile
 TOBJECTS=tests/base16_test.obj tests/base32_test.obj tests/base64_test.obj tests/cipher_hash_test.obj \
 TOBJECTS=tests/base16_test.obj tests/base32_test.obj tests/base64_test.obj tests/cipher_hash_test.obj \

+ 38 - 36
makefile.unix

@@ -189,46 +189,48 @@ src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.
 src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
 src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
 src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
 src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
 src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
 src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
-src/pk/dsa/dsa_verify_key.o src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o \
-src/pk/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o \
-src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o \
-src/pk/ecc/ecc_find_curve.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o \
-src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o \
-src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o \
-src/pk/ecc/ecc_recover_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_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.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/dsa/dsa_verify_key.o src/pk/ec25519/ec25519_export.o src/pk/ec25519/ec25519_import_pkcs8.o \
+src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o src/pk/ecc/ecc_ansi_x963_export.o \
+src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o \
+src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o src/pk/ecc/ecc_find_curve.o \
+src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o src/pk/ecc/ecc_get_size.o \
+src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o src/pk/ecc/ecc_import_pkcs8.o \
+src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_recover_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_sizes.o \
+src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.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_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_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_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/ecc/ltc_ecc_verify_key.o src/pk/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \
-src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o \
-src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o src/pk/ed25519/ed25519_verify.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 src/pk/rsa/rsa_export.o \
-src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_make_key.o \
-src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \
-src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o src/pk/x25519/x25519_import.o \
-src/pk/x25519/x25519_import_x509.o src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_ku.o \
-src/pk/x25519/x25519_shared_secret.o src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o \
-src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \
-src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o \
-src/stream/chacha/chacha_ivctr32.o src/stream/chacha/chacha_ivctr64.o \
-src/stream/chacha/chacha_keystream.o src/stream/chacha/chacha_memory.o \
-src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit.o \
-src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o src/stream/rc4/rc4_stream_memory.o \
-src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o src/stream/salsa20/salsa20_done.o \
-src/stream/salsa20/salsa20_ivctr64.o src/stream/salsa20/salsa20_keystream.o \
-src/stream/salsa20/salsa20_memory.o src/stream/salsa20/salsa20_setup.o \
-src/stream/salsa20/salsa20_test.o src/stream/salsa20/xsalsa20_memory.o \
-src/stream/salsa20/xsalsa20_setup.o src/stream/salsa20/xsalsa20_test.o \
-src/stream/sober128/sober128_stream.o src/stream/sober128/sober128_stream_memory.o \
-src/stream/sober128/sober128_test.o src/stream/sosemanuk/sosemanuk.o \
-src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o
+src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_x509.o \
+src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o \
+src/pk/ed25519/ed25519_verify.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 \
+src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \
+src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o \
+src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \
+src/pk/rsa/rsa_sign_saltlen_get.o src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o \
+src/pk/x25519/x25519_import.o src/pk/x25519/x25519_import_pkcs8.o src/pk/x25519/x25519_import_x509.o \
+src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_key.o src/pk/x25519/x25519_shared_secret.o \
+src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
+src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o \
+src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o src/stream/chacha/chacha_ivctr32.o \
+src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \
+src/stream/chacha/chacha_memory.o src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o \
+src/stream/rabbit/rabbit.o src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o \
+src/stream/rc4/rc4_stream_memory.o src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o \
+src/stream/salsa20/salsa20_done.o src/stream/salsa20/salsa20_ivctr64.o \
+src/stream/salsa20/salsa20_keystream.o src/stream/salsa20/salsa20_memory.o \
+src/stream/salsa20/salsa20_setup.o src/stream/salsa20/salsa20_test.o \
+src/stream/salsa20/xsalsa20_memory.o src/stream/salsa20/xsalsa20_setup.o \
+src/stream/salsa20/xsalsa20_test.o src/stream/sober128/sober128_stream.o \
+src/stream/sober128/sober128_stream_memory.o src/stream/sober128/sober128_test.o \
+src/stream/sosemanuk/sosemanuk.o src/stream/sosemanuk/sosemanuk_memory.o \
+src/stream/sosemanuk/sosemanuk_test.o
 
 
 #List of test objects to compile (all goes to libtomcrypt_prof.a)
 #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/cipher_hash_test.o \
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \

+ 38 - 36
makefile_include.mk

@@ -349,46 +349,48 @@ src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.
 src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
 src/pk/dsa/dsa_generate_key.o src/pk/dsa/dsa_generate_pqg.o src/pk/dsa/dsa_import.o \
 src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
 src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_set.o src/pk/dsa/dsa_set_pqg_dsaparam.o \
 src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
 src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
-src/pk/dsa/dsa_verify_key.o src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o \
-src/pk/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o \
-src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o \
-src/pk/ecc/ecc_find_curve.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o \
-src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o \
-src/pk/ecc/ecc_import_pkcs8.o src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o \
-src/pk/ecc/ecc_recover_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_sizes.o src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.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/dsa/dsa_verify_key.o src/pk/ec25519/ec25519_export.o src/pk/ec25519/ec25519_import_pkcs8.o \
+src/pk/ec25519/tweetnacl.o src/pk/ecc/ecc.o src/pk/ecc/ecc_ansi_x963_export.o \
+src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o \
+src/pk/ecc/ecc_export.o src/pk/ecc/ecc_export_openssl.o src/pk/ecc/ecc_find_curve.o \
+src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_key.o src/pk/ecc/ecc_get_oid_str.o src/pk/ecc/ecc_get_size.o \
+src/pk/ecc/ecc_import.o src/pk/ecc/ecc_import_openssl.o src/pk/ecc/ecc_import_pkcs8.o \
+src/pk/ecc/ecc_import_x509.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_recover_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_sizes.o \
+src/pk/ecc/ecc_ssh_ecdsa_encode_name.o src/pk/ecc/ecc_verify_hash.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_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_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_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/ecc/ltc_ecc_verify_key.o src/pk/ed25519/ed25519_export.o src/pk/ed25519/ed25519_import.o \
-src/pk/ed25519/ed25519_import_x509.o src/pk/ed25519/ed25519_make_key.o \
-src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o src/pk/ed25519/ed25519_verify.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 src/pk/rsa/rsa_export.o \
-src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o src/pk/rsa/rsa_make_key.o \
-src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_sign_saltlen_get.o \
-src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o src/pk/x25519/x25519_import.o \
-src/pk/x25519/x25519_import_x509.o src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_ku.o \
-src/pk/x25519/x25519_shared_secret.o src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o \
-src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o \
-src/prngs/yarrow.o src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o \
-src/stream/chacha/chacha_ivctr32.o src/stream/chacha/chacha_ivctr64.o \
-src/stream/chacha/chacha_keystream.o src/stream/chacha/chacha_memory.o \
-src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o src/stream/rabbit/rabbit.o \
-src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o src/stream/rc4/rc4_stream_memory.o \
-src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o src/stream/salsa20/salsa20_done.o \
-src/stream/salsa20/salsa20_ivctr64.o src/stream/salsa20/salsa20_keystream.o \
-src/stream/salsa20/salsa20_memory.o src/stream/salsa20/salsa20_setup.o \
-src/stream/salsa20/salsa20_test.o src/stream/salsa20/xsalsa20_memory.o \
-src/stream/salsa20/xsalsa20_setup.o src/stream/salsa20/xsalsa20_test.o \
-src/stream/sober128/sober128_stream.o src/stream/sober128/sober128_stream_memory.o \
-src/stream/sober128/sober128_test.o src/stream/sosemanuk/sosemanuk.o \
-src/stream/sosemanuk/sosemanuk_memory.o src/stream/sosemanuk/sosemanuk_test.o
+src/pk/ed25519/ed25519_import_pkcs8.o src/pk/ed25519/ed25519_import_x509.o \
+src/pk/ed25519/ed25519_make_key.o src/pk/ed25519/ed25519_set_key.o src/pk/ed25519/ed25519_sign.o \
+src/pk/ed25519/ed25519_verify.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 \
+src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_get_size.o \
+src/pk/rsa/rsa_import.o src/pk/rsa/rsa_import_pkcs8.o src/pk/rsa/rsa_import_x509.o \
+src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_set.o src/pk/rsa/rsa_sign_hash.o \
+src/pk/rsa/rsa_sign_saltlen_get.o src/pk/rsa/rsa_verify_hash.o src/pk/x25519/x25519_export.o \
+src/pk/x25519/x25519_import.o src/pk/x25519/x25519_import_pkcs8.o src/pk/x25519/x25519_import_x509.o \
+src/pk/x25519/x25519_make_key.o src/pk/x25519/x25519_set_key.o src/pk/x25519/x25519_shared_secret.o \
+src/prngs/chacha20.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
+src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o \
+src/stream/chacha/chacha_crypt.o src/stream/chacha/chacha_done.o src/stream/chacha/chacha_ivctr32.o \
+src/stream/chacha/chacha_ivctr64.o src/stream/chacha/chacha_keystream.o \
+src/stream/chacha/chacha_memory.o src/stream/chacha/chacha_setup.o src/stream/chacha/chacha_test.o \
+src/stream/rabbit/rabbit.o src/stream/rabbit/rabbit_memory.o src/stream/rc4/rc4_stream.o \
+src/stream/rc4/rc4_stream_memory.o src/stream/rc4/rc4_test.o src/stream/salsa20/salsa20_crypt.o \
+src/stream/salsa20/salsa20_done.o src/stream/salsa20/salsa20_ivctr64.o \
+src/stream/salsa20/salsa20_keystream.o src/stream/salsa20/salsa20_memory.o \
+src/stream/salsa20/salsa20_setup.o src/stream/salsa20/salsa20_test.o \
+src/stream/salsa20/xsalsa20_memory.o src/stream/salsa20/xsalsa20_setup.o \
+src/stream/salsa20/xsalsa20_test.o src/stream/sober128/sober128_stream.o \
+src/stream/sober128/sober128_stream_memory.o src/stream/sober128/sober128_test.o \
+src/stream/sosemanuk/sosemanuk.o src/stream/sosemanuk/sosemanuk_memory.o \
+src/stream/sosemanuk/sosemanuk_test.o
 
 
 # List of test objects to compile (all goes to libtomcrypt_prof.a)
 # 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/cipher_hash_test.o \
 TOBJECTS=tests/base16_test.o tests/base32_test.o tests/base64_test.o tests/cipher_hash_test.o \

+ 16 - 12
src/headers/tomcrypt_pk.h

@@ -346,20 +346,22 @@ typedef struct {
 } curve25519_key;
 } curve25519_key;
 
 
 
 
-/* Ed25519 Signature API */
+/** Ed25519 Signature API */
 int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
 int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
 
 
+int ed25519_set_key(const unsigned char *sk, unsigned long sklen,
+                    const unsigned char *pk, unsigned long pklen,
+                         curve25519_key *key);
+
 int ed25519_export(       unsigned char *out, unsigned long *outlen,
 int ed25519_export(       unsigned char *out, unsigned long *outlen,
                                     int  which,
                                     int  which,
                    const curve25519_key *key);
                    const curve25519_key *key);
 
 
 int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
 int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
-
 int ed25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
 int ed25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
-
-int ed25519_set_key(const unsigned char *sk, unsigned long sklen,
-                    const unsigned char *pk, unsigned long pklen,
-                         curve25519_key *key);
+int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                  const void *pwd, unsigned long pwdlen,
+                              curve25519_key *key);
 
 
 int ed25519_sign(const unsigned char  *msg, unsigned long msglen,
 int ed25519_sign(const unsigned char  *msg, unsigned long msglen,
                        unsigned char  *sig, unsigned long *siglen,
                        unsigned char  *sig, unsigned long *siglen,
@@ -369,20 +371,22 @@ int ed25519_verify(const  unsigned char *msg, unsigned long msglen,
                    const  unsigned char *sig, unsigned long siglen,
                    const  unsigned char *sig, unsigned long siglen,
                    int *stat, const curve25519_key *public_key);
                    int *stat, const curve25519_key *public_key);
 
 
-/* X25519 Key-Exchange API */
+/** X25519 Key-Exchange API */
 int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
 int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
 
 
+int x25519_set_key(const unsigned char *k,  unsigned long klen,
+                   const unsigned char *u,  unsigned long ulen,
+                        curve25519_key *key);
+
 int x25519_export(       unsigned char *out, unsigned long *outlen,
 int x25519_export(       unsigned char *out, unsigned long *outlen,
                                    int  which,
                                    int  which,
                   const curve25519_key *key);
                   const curve25519_key *key);
 
 
 int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
 int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key);
-
 int x25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
 int x25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_key *key);
-
-int x25519_set_ku(const unsigned char *k,  unsigned long klen,
-                  const unsigned char *u,  unsigned long ulen,
-                       curve25519_key *key);
+int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                 const void *pwd, unsigned long pwdlen,
+                             curve25519_key *key);
 
 
 int x25519_shared_secret(const curve25519_key *private_key,
 int x25519_shared_secret(const curve25519_key *private_key,
                          const curve25519_key *public_key,
                          const curve25519_key *public_key,

+ 16 - 7
src/headers/tomcrypt_private.h

@@ -302,19 +302,28 @@ int dsa_int_validate_primes(const dsa_key *key, int *stat);
 
 
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
 
 
-int crypto_sign(
+int tweetnacl_crypto_sign(
   unsigned char *sm,unsigned long long *smlen,
   unsigned char *sm,unsigned long long *smlen,
   const unsigned char *m,unsigned long long mlen,
   const unsigned char *m,unsigned long long mlen,
   const unsigned char *sk, const unsigned char *pk);
   const unsigned char *sk, const unsigned char *pk);
-int crypto_sign_open(
+int tweetnacl_crypto_sign_open(
+  int *stat,
   unsigned char *m,unsigned long long *mlen,
   unsigned char *m,unsigned long long *mlen,
   const unsigned char *sm,unsigned long long smlen,
   const unsigned char *sm,unsigned long long smlen,
   const unsigned char *pk);
   const unsigned char *pk);
-int crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk);
-int crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
-int crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
-int crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
-
+int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk);
+int tweetnacl_crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
+int tweetnacl_crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
+int tweetnacl_crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
+
+typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk);
+int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                       const void *pwd, unsigned long pwdlen,
+                       enum ltc_oid_id id, sk_to_pk fp,
+                       curve25519_key *key);
+int ec25519_export(       unsigned char *out, unsigned long *outlen,
+                                    int  which,
+                   const curve25519_key *key);
 #endif /* LTC_CURVE25519 */
 #endif /* LTC_CURVE25519 */
 
 
 #ifdef LTC_DER
 #ifdef LTC_DER

+ 100 - 0
src/pk/ec25519/ec25519_export.c

@@ -0,0 +1,100 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+  @file ec25519_export.c
+  Generic export of a Curve/Ed25519 key to a binary packet, Steffen Jaeckel
+*/
+
+#ifdef LTC_CURVE25519
+
+/**
+   Generic export of a Curve/Ed25519 key to a binary packet
+   @param out    [out] The destination for the key
+   @param outlen [in/out] The max size and resulting size of the Ed25519 key
+   @param type   Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC)
+   @param key    The key you wish to export
+   @return CRYPT_OK if successful
+*/
+int ec25519_export(       unsigned char *out, unsigned long *outlen,
+                                    int  which,
+                   const curve25519_key *key)
+{
+   int err, std;
+   const char* OID;
+   unsigned long oid[16], oidlen;
+   ltc_asn1_list alg_id[1];
+   unsigned char private_key[34];
+   unsigned long version, private_key_len = sizeof(private_key);
+
+   LTC_ARGCHK(out       != NULL);
+   LTC_ARGCHK(outlen    != NULL);
+   LTC_ARGCHK(key       != NULL);
+
+   std = which & PK_STD;
+   which &= ~PK_STD;
+
+   if (which == PK_PRIVATE) {
+      if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
+
+      if (std == PK_STD) {
+         if ((err = pk_get_oid(key->algo, &OID)) != CRYPT_OK) {
+            return err;
+         }
+         oidlen = sizeof(oid)/sizeof(oid[0]);
+         if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
+            return err;
+         }
+
+         LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
+
+         /* encode private key as PKCS#8 */
+         if ((err = der_encode_octet_string(key->priv, 32uL, private_key, &private_key_len)) != CRYPT_OK) {
+            return err;
+         }
+
+         version = 0;
+         err = der_encode_sequence_multi(out, outlen,
+                                   LTC_ASN1_SHORT_INTEGER,            1uL, &version,
+                                   LTC_ASN1_SEQUENCE,                 1uL, alg_id,
+                                   LTC_ASN1_OCTET_STRING, private_key_len, private_key,
+                                   LTC_ASN1_EOL,                      0uL, NULL);
+      } else {
+         if (*outlen < sizeof(key->priv)) {
+            err = CRYPT_BUFFER_OVERFLOW;
+         } else {
+            XMEMCPY(out, key->priv, sizeof(key->priv));
+            err = CRYPT_OK;
+         }
+         *outlen = sizeof(key->priv);
+      }
+   } else {
+      if (std == PK_STD) {
+         /* encode public key as SubjectPublicKeyInfo */
+         err = x509_encode_subject_public_key_info(out, outlen, key->algo, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0);
+      } else {
+         if (*outlen < sizeof(key->pub)) {
+            err = CRYPT_BUFFER_OVERFLOW;
+         } else {
+            XMEMCPY(out, key->pub, sizeof(key->pub));
+            err = CRYPT_OK;
+         }
+         *outlen = sizeof(key->pub);
+      }
+   }
+
+   return err;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */

+ 97 - 0
src/pk/ec25519/ec25519_import_pkcs8.c

@@ -0,0 +1,97 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+  @file ec25519_import_pkcs8.c
+  Generic import of a Curve/Ed25519 private key in PKCS#8 format, Steffen Jaeckel
+*/
+
+#ifdef LTC_CURVE25519
+
+/**
+  Generic import of a Curve/Ed25519 private key in PKCS#8 format
+  @param in        The DER-encoded PKCS#8-formatted private key
+  @param inlen     The length of the input data
+  @param passwd    The password to decrypt the private key
+  @param passwdlen Password's length (octets)
+  @param key       [out] Where to import the key to
+  @return CRYPT_OK if successful, on error all allocated memory is freed automatically
+*/
+int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                       const void *pwd, unsigned long pwdlen,
+                       enum ltc_oid_id id, sk_to_pk fp,
+                       curve25519_key *key)
+{
+   int err = CRYPT_INVALID_ARG;
+   ltc_asn1_list *l = NULL;
+   const char *oid;
+   ltc_asn1_list alg_id[1];
+   unsigned char private_key[34];
+   unsigned long version, key_len;
+   unsigned long tmpoid[16];
+
+   LTC_ARGCHK(in  != NULL);
+   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(fp != NULL);
+
+   if ((err = pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) {
+
+      LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid) / sizeof(tmpoid[0]));
+
+      key_len = sizeof(private_key);
+      if ((err = der_decode_sequence_multi(l->data, l->size,
+                                           LTC_ASN1_SHORT_INTEGER,      1uL, &version,
+                                           LTC_ASN1_SEQUENCE,           1uL, alg_id,
+                                           LTC_ASN1_OCTET_STRING,   key_len, private_key,
+                                           LTC_ASN1_EOL,                0uL, NULL))
+          != CRYPT_OK) {
+         /* If there are attributes added after the private_key it is tagged with version 1 and
+          * we get an 'input too long' error but the rest is already decoded and can be
+          * handled the same as for version 0
+          */
+         if ((err == CRYPT_INPUT_TOO_LONG) && (version == 1)) {
+            version = 0;
+         } else {
+            goto out;
+         }
+      }
+
+      if ((err = pk_get_oid(id, &oid)) != CRYPT_OK) {
+         goto out;
+      }
+      if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
+         goto out;
+      }
+
+      if (version == 0) {
+         key_len = sizeof(key->priv);
+         if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
+            fp(key->pub, key->priv);
+            key->type = PK_PRIVATE;
+            key->algo = id;
+         }
+      } else {
+         err = CRYPT_PK_INVALID_TYPE;
+      }
+   }
+out:
+   if (l) der_free_sequence_flexi(l);
+#ifdef LTC_CLEAN_STACK
+   zeromem(private_key, sizeof(private_key));
+#endif
+
+   return err;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */

+ 30 - 149
src/pk/ec25519/tweetnacl.c

@@ -31,22 +31,6 @@ static const gf
   Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
   Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
   I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
   I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
 
 
-static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
-
-static u32 ld32(const u8 *x)
-{
-  u32 u = x[3];
-  u = (u<<8)|x[2];
-  u = (u<<8)|x[1];
-  return (u<<8)|x[0];
-}
-
-sv st32(u8 *x,u32 u)
-{
-  int i;
-  FOR(i,4) { x[i] = u; u >>= 8; }
-}
-
 static int vn(const u8 *x,const u8 *y,int n)
 static int vn(const u8 *x,const u8 *y,int n)
 {
 {
   int i;
   int i;
@@ -55,116 +39,11 @@ static int vn(const u8 *x,const u8 *y,int n)
   return (1 & ((d - 1) >> 8)) - 1;
   return (1 & ((d - 1) >> 8)) - 1;
 }
 }
 
 
-int crypto_verify_16(const u8 *x,const u8 *y)
-{
-  return vn(x,y,16);
-}
-
-int crypto_verify_32(const u8 *x,const u8 *y)
+static int tweetnacl_crypto_verify_32(const u8 *x,const u8 *y)
 {
 {
   return vn(x,y,32);
   return vn(x,y,32);
 }
 }
 
 
-sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h)
-{
-  u32 w[16],x[16],y[16],t[4];
-  int i,j,m;
-
-  FOR(i,4) {
-    x[5*i] = ld32(c+4*i);
-    x[1+i] = ld32(k+4*i);
-    x[6+i] = ld32(in+4*i);
-    x[11+i] = ld32(k+16+4*i);
-  }
-
-  FOR(i,16) y[i] = x[i];
-
-  FOR(i,20) {
-    FOR(j,4) {
-      FOR(m,4) t[m] = x[(5*j+4*m)%16];
-      t[1] ^= L32(t[0]+t[3], 7);
-      t[2] ^= L32(t[1]+t[0], 9);
-      t[3] ^= L32(t[2]+t[1],13);
-      t[0] ^= L32(t[3]+t[2],18);
-      FOR(m,4) w[4*j+(j+m)%4] = t[m];
-    }
-    FOR(m,16) x[m] = w[m];
-  }
-
-  if (h) {
-    FOR(i,16) x[i] += y[i];
-    FOR(i,4) {
-      x[5*i] -= ld32(c+4*i);
-      x[6+i] -= ld32(in+4*i);
-    }
-    FOR(i,4) {
-      st32(out+4*i,x[5*i]);
-      st32(out+16+4*i,x[6+i]);
-    }
-  } else
-    FOR(i,16) st32(out + 4 * i,x[i] + y[i]);
-}
-
-int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
-{
-  core(out,in,k,c,0);
-  return 0;
-}
-
-int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
-{
-  core(out,in,k,c,1);
-  return 0;
-}
-
-static const u8 sigma[16] = "expand 32-byte k";
-
-int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k)
-{
-  u8 z[16],x[64];
-  u32 u,i;
-  if (!b) return 0;
-  FOR(i,16) z[i] = 0;
-  FOR(i,8) z[i] = n[i];
-  while (b >= 64) {
-    crypto_core_salsa20(x,z,k,sigma);
-    FOR(i,64) c[i] = (m?m[i]:0) ^ x[i];
-    u = 1;
-    for (i = 8;i < 16;++i) {
-      u += (u32) z[i];
-      z[i] = u;
-      u >>= 8;
-    }
-    b -= 64;
-    c += 64;
-    if (m) m += 64;
-  }
-  if (b) {
-    crypto_core_salsa20(x,z,k,sigma);
-    FOR(i,b) c[i] = (m?m[i]:0) ^ x[i];
-  }
-  return 0;
-}
-
-int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k)
-{
-  return crypto_stream_salsa20_xor(c,0,d,n,k);
-}
-
-int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k)
-{
-  u8 s[32];
-  crypto_core_hsalsa20(s,n,k,sigma);
-  return crypto_stream_salsa20(c,d,n+16,s);
-}
-
-int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
-{
-  u8 s[32];
-  crypto_core_hsalsa20(s,n,k,sigma);
-  return crypto_stream_salsa20_xor(c,m,d,n+16,s);
-}
-
 sv set25519(gf r, const gf a)
 sv set25519(gf r, const gf a)
 {
 {
   int i;
   int i;
@@ -223,7 +102,7 @@ static int neq25519(const gf a, const gf b)
   u8 c[32],d[32];
   u8 c[32],d[32];
   pack25519(c,a);
   pack25519(c,a);
   pack25519(d,b);
   pack25519(d,b);
-  return crypto_verify_32(c,d);
+  return tweetnacl_crypto_verify_32(c,d);
 }
 }
 
 
 static u8 par25519(const gf a)
 static u8 par25519(const gf a)
@@ -292,7 +171,7 @@ sv pow2523(gf o,const gf i)
   FOR(a,16) o[a]=c[a];
   FOR(a,16) o[a]=c[a];
 }
 }
 
 
-int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
+int tweetnacl_crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
 {
 {
   u8 z[32];
   u8 z[32];
   i64 x[80],r,i;
   i64 x[80],r,i;
@@ -343,12 +222,12 @@ int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
   return 0;
   return 0;
 }
 }
 
 
-int crypto_scalarmult_base(u8 *q,const u8 *n)
+int tweetnacl_crypto_scalarmult_base(u8 *q,const u8 *n)
 {
 {
-  return crypto_scalarmult(q,n,_9);
+  return tweetnacl_crypto_scalarmult(q,n,_9);
 }
 }
 
 
-static int crypto_hash(u8 *out,const u8 *m,u64 n)
+static int tweetnacl_crypto_hash(u8 *out,const u8 *m,u64 n)
 {
 {
   unsigned long len;
   unsigned long len;
   int err, hash_idx;
   int err, hash_idx;
@@ -430,11 +309,11 @@ sv scalarbase(gf p[4],const u8 *s)
   scalarmult(p,q,s);
   scalarmult(p,q,s);
 }
 }
 
 
-int crypto_sk_to_pk(u8 *pk, const u8 *sk)
+int tweetnacl_crypto_sk_to_pk(u8 *pk, const u8 *sk)
 {
 {
   u8 d[64];
   u8 d[64];
   gf p[4];
   gf p[4];
-  crypto_hash(d, sk, 32);
+  tweetnacl_crypto_hash(d, sk, 32);
   d[0] &= 248;
   d[0] &= 248;
   d[31] &= 127;
   d[31] &= 127;
   d[31] |= 64;
   d[31] |= 64;
@@ -445,7 +324,7 @@ int crypto_sk_to_pk(u8 *pk, const u8 *sk)
   return 0;
   return 0;
 }
 }
 
 
-int crypto_sign_keypair(prng_state *prng, int wprng, u8 *pk, u8 *sk)
+int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, u8 *pk, u8 *sk)
 {
 {
   int err;
   int err;
 
 
@@ -458,7 +337,7 @@ int crypto_sign_keypair(prng_state *prng, int wprng, u8 *pk, u8 *sk)
      return CRYPT_ERROR_READPRNG;
      return CRYPT_ERROR_READPRNG;
   }
   }
 
 
-  if ((err = crypto_sk_to_pk(pk, sk)) != CRYPT_OK) {
+  if ((err = tweetnacl_crypto_sk_to_pk(pk, sk)) != CRYPT_OK) {
      return err;
      return err;
   }
   }
 
 
@@ -503,28 +382,28 @@ sv reduce(u8 *r)
   modL(r,x);
   modL(r,x);
 }
 }
 
 
-int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk,const u8 *pk)
+int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,const u8 *pk)
 {
 {
   u8 d[64],h[64],r[64];
   u8 d[64],h[64],r[64];
   i64 i,j,x[64];
   i64 i,j,x[64];
   gf p[4];
   gf p[4];
 
 
-  crypto_hash(d, sk, 32);
+  tweetnacl_crypto_hash(d, sk, 32);
   d[0] &= 248;
   d[0] &= 248;
   d[31] &= 127;
   d[31] &= 127;
   d[31] |= 64;
   d[31] |= 64;
 
 
-  *smlen = n+64;
-  FOR(i,(i64)n) sm[64 + i] = m[i];
+  *smlen = mlen+64;
+  FOR(i,(i64)mlen) sm[64 + i] = m[i];
   FOR(i,32) sm[32 + i] = d[32 + i];
   FOR(i,32) sm[32 + i] = d[32 + i];
 
 
-  crypto_hash(r, sm+32, n+32);
+  tweetnacl_crypto_hash(r, sm+32, mlen+32);
   reduce(r);
   reduce(r);
   scalarbase(p,r);
   scalarbase(p,r);
   pack(sm,p);
   pack(sm,p);
 
 
   FOR(i,32) sm[i+32] = pk[i];
   FOR(i,32) sm[i+32] = pk[i];
-  crypto_hash(h,sm,n + 64);
+  tweetnacl_crypto_hash(h,sm,mlen + 64);
   reduce(h);
   reduce(h);
 
 
   FOR(i,64) x[i] = 0;
   FOR(i,64) x[i] = 0;
@@ -571,22 +450,23 @@ static int unpackneg(gf r[4],const u8 p[32])
   return 0;
   return 0;
 }
 }
 
 
-int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
+int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen,const u8 *pk)
 {
 {
   u64 i;
   u64 i;
   u8 s[32],t[32],h[64];
   u8 s[32],t[32],h[64];
   gf p[4],q[4];
   gf p[4],q[4];
 
 
-  if (*mlen < n) return CRYPT_BUFFER_OVERFLOW;
+  *stat = 0;
+  if (*mlen < smlen) return CRYPT_BUFFER_OVERFLOW;
   *mlen = -1;
   *mlen = -1;
-  if (n < 64) return CRYPT_INVALID_ARG;
+  if (smlen < 64) return CRYPT_INVALID_ARG;
 
 
   if (unpackneg(q,pk)) return CRYPT_ERROR;
   if (unpackneg(q,pk)) return CRYPT_ERROR;
 
 
-  XMEMMOVE(m,sm,n);
+  XMEMMOVE(m,sm,smlen);
   XMEMMOVE(s,m + 32,32);
   XMEMMOVE(s,m + 32,32);
   XMEMMOVE(m + 32,pk,32);
   XMEMMOVE(m + 32,pk,32);
-  crypto_hash(h,m,n);
+  tweetnacl_crypto_hash(h,m,smlen);
   reduce(h);
   reduce(h);
   scalarmult(p,q,h);
   scalarmult(p,q,h);
 
 
@@ -594,15 +474,16 @@ int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
   add(p,q);
   add(p,q);
   pack(t,p);
   pack(t,p);
 
 
-  n -= 64;
-  if (crypto_verify_32(sm, t)) {
-    FOR(i,n) m[i] = 0;
-    zeromem(m, n);
-    return CRYPT_INVALID_PACKET;
+  smlen -= 64;
+  if (tweetnacl_crypto_verify_32(sm, t)) {
+    FOR(i,smlen) m[i] = 0;
+    zeromem(m, smlen);
+    return CRYPT_OK;
   }
   }
 
 
-  XMEMMOVE(m,m + 64,n);
-  *mlen = n;
+  *stat = 1;
+  XMEMMOVE(m,m + 64,smlen);
+  *mlen = smlen;
   return CRYPT_OK;
   return CRYPT_OK;
 }
 }
 
 

+ 4 - 55
src/pk/ed25519/ed25519_export.c

@@ -10,13 +10,13 @@
 
 
 /**
 /**
   @file ed25519_export.c
   @file ed25519_export.c
-  Export a Ed25519 key to a binary packet, Steffen Jaeckel
+  Export an Ed25519 key to a binary packet, Steffen Jaeckel
 */
 */
 
 
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
 
 
 /**
 /**
-   Export a Ed25519 key to a binary packet
+   Export an Ed25519 key to a binary packet
    @param out    [out] The destination for the key
    @param out    [out] The destination for the key
    @param outlen [in/out] The max size and resulting size of the Ed25519 key
    @param outlen [in/out] The max size and resulting size of the Ed25519 key
    @param type   Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC)
    @param type   Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC)
@@ -27,62 +27,11 @@ int ed25519_export(       unsigned char *out, unsigned long *outlen,
                                     int  which,
                                     int  which,
                    const curve25519_key *key)
                    const curve25519_key *key)
 {
 {
-   int err, std;
-   const char* OID;
-   unsigned long oid[16], oidlen;
-   ltc_asn1_list alg_id[1];
-   unsigned char private_key[34];
-   unsigned long version, private_key_len = sizeof(private_key);
-
-   LTC_ARGCHK(out       != NULL);
-   LTC_ARGCHK(outlen    != NULL);
-   LTC_ARGCHK(key       != NULL);
+   LTC_ARGCHK(key != NULL);
 
 
    if (key->algo != PKA_ED25519) return CRYPT_PK_INVALID_TYPE;
    if (key->algo != PKA_ED25519) return CRYPT_PK_INVALID_TYPE;
 
 
-   std = which & PK_STD;
-   which &= ~PK_STD;
-
-   if (which == PK_PRIVATE) {
-      if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
-
-      if ((err = pk_get_oid(PKA_ED25519, &OID)) != CRYPT_OK) {
-         return err;
-      }
-      oidlen = sizeof(oid)/sizeof(oid[0]);
-      if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
-         return err;
-      }
-
-      LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
-
-      /* encode private key as PKCS#8 */
-      if ((err = der_encode_octet_string(key->priv, 32uL, private_key, &private_key_len)) != CRYPT_OK) {
-         return err;
-      }
-
-      version = 0;
-      err = der_encode_sequence_multi(out, outlen,
-                                LTC_ASN1_SHORT_INTEGER,            1uL, &version,
-                                LTC_ASN1_SEQUENCE,                 1uL, alg_id,
-                                LTC_ASN1_OCTET_STRING, private_key_len, private_key,
-                                LTC_ASN1_EOL,                      0uL, NULL);
-   } else {
-      if (std == PK_STD) {
-         /* encode public key as SubjectPublicKeyInfo */
-         err = x509_encode_subject_public_key_info(out, outlen, PKA_ED25519, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0);
-      } else {
-         if (*outlen < sizeof(key->pub)) {
-            err = CRYPT_BUFFER_OVERFLOW;
-         } else {
-            XMEMCPY(out, key->pub, sizeof(key->pub));
-            err = CRYPT_OK;
-         }
-         *outlen = sizeof(key->pub);
-      }
-   }
-
-   return err;
+   return ec25519_export(out, outlen, which, key);
 }
 }
 
 
 #endif
 #endif

+ 2 - 57
src/pk/ed25519/ed25519_import.c

@@ -16,7 +16,7 @@
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
 
 
 /**
 /**
-  Import a Ed25519 key from a binary packet
+  Import an Ed25519 public key
   @param in     The packet to read
   @param in     The packet to read
   @param inlen  The length of the input packet
   @param inlen  The length of the input packet
   @param key    [out] Where to import the key to
   @param key    [out] Where to import the key to
@@ -25,71 +25,16 @@
 int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key)
 int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key)
 {
 {
    int err;
    int err;
-   const char* oid;
-   ltc_asn1_list alg_id[1];
-   unsigned char private_key[34];
-   unsigned long version, key_len;
-   unsigned long tmpoid[16];
+   unsigned long key_len;
 
 
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(key != NULL);
    LTC_ARGCHK(key != NULL);
 
 
-   /* There's only one case where the inlen is equal to the pubkey-size
-    * and that's a raw pubkey, so let's just do a raw import.
-    */
-   if (inlen == sizeof(key->pub)) {
-      XMEMCPY(key->pub, in, sizeof(key->pub));
-      key->type = PK_PUBLIC;
-      key->algo = PKA_ED25519;
-      return CRYPT_OK;
-   }
-
    key_len = sizeof(key->pub);
    key_len = sizeof(key->pub);
    if ((err = x509_decode_subject_public_key_info(in, inlen, PKA_ED25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
    if ((err = x509_decode_subject_public_key_info(in, inlen, PKA_ED25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
       key->type = PK_PUBLIC;
       key->type = PK_PUBLIC;
       key->algo = PKA_ED25519;
       key->algo = PKA_ED25519;
-      return CRYPT_OK;
    }
    }
-
-   LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
-
-   key_len = sizeof(private_key);
-   err = der_decode_sequence_multi(in, inlen,
-                                LTC_ASN1_SHORT_INTEGER,    1uL, &version,
-                                LTC_ASN1_SEQUENCE,         1uL, alg_id,
-                                LTC_ASN1_OCTET_STRING, key_len, private_key,
-                                LTC_ASN1_EOL,              0uL, NULL);
-   if (err != CRYPT_OK) {
-      if ((err == CRYPT_INPUT_TOO_LONG) && (version == 1)) {
-         version = 0;
-      } else {
-         goto out;
-      }
-   }
-
-   if ((err = pk_get_oid(PKA_ED25519, &oid)) != CRYPT_OK) {
-      goto out;
-   }
-   if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
-      goto out;
-   }
-
-   if (version == 0) {
-      key_len = sizeof(key->priv);
-      if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
-         crypto_sk_to_pk(key->pub, key->priv);
-         key->type = PK_PRIVATE;
-         key->algo = PKA_ED25519;
-      }
-   } else {
-      err = CRYPT_PK_INVALID_TYPE;
-   }
-
-out:
-#ifdef LTC_CLEAN_STACK
-   zeromem(private_key, sizeof(private_key));
-#endif
-
    return err;
    return err;
 }
 }
 
 

+ 38 - 0
src/pk/ed25519/ed25519_import_pkcs8.c

@@ -0,0 +1,38 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+  @file ed25519_import_pkcs8.c
+  Import an Ed25519 key in PKCS#8 format, Steffen Jaeckel
+*/
+
+#ifdef LTC_CURVE25519
+
+/**
+  Import an Ed25519 private key in PKCS#8 format
+  @param in        The DER-encoded PKCS#8-formatted private key
+  @param inlen     The length of the input data
+  @param passwd    The password to decrypt the private key
+  @param passwdlen Password's length (octets)
+  @param key       [out] Where to import the key to
+  @return CRYPT_OK if successful, on error all allocated memory is freed automatically
+*/
+int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                                  const void *pwd, unsigned long pwdlen,
+                              curve25519_key *key)
+{
+   return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, PKA_ED25519, tweetnacl_crypto_sk_to_pk, key);
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */

+ 2 - 2
src/pk/ed25519/ed25519_import_x509.c

@@ -10,7 +10,7 @@
 
 
 /**
 /**
   @file ed25519_import_x509.c
   @file ed25519_import_x509.c
-  Import a Ed25519 key from a X.509 certificate, Steffen Jaeckel
+  Import an Ed25519 key from a X.509 certificate, Steffen Jaeckel
 */
 */
 
 
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
@@ -23,7 +23,7 @@ static int _ed25519_decode(const unsigned char *in, unsigned long inlen, curve25
 }
 }
 
 
 /**
 /**
-  Import a Ed25519 public key from a X.509 certificate
+  Import an Ed25519 public key from a X.509 certificate
   @param in     The DER encoded X.509 certificate
   @param in     The DER encoded X.509 certificate
   @param inlen  The length of the certificate
   @param inlen  The length of the certificate
   @param key    [out] Where to import the key to
   @param key    [out] Where to import the key to

+ 3 - 3
src/pk/ed25519/ed25519_make_key.c

@@ -10,13 +10,13 @@
 
 
 /**
 /**
   @file ed25519_make_key.c
   @file ed25519_make_key.c
-  Create a Ed25519 key, Steffen Jaeckel
+  Create an Ed25519 key, Steffen Jaeckel
 */
 */
 
 
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
 
 
 /**
 /**
-   Create a Ed25519 key
+   Create an Ed25519 key
    @param prng     An active PRNG state
    @param prng     An active PRNG state
    @param wprng    The index of the PRNG desired
    @param wprng    The index of the PRNG desired
    @param key      [out] Destination of a newly created private key pair
    @param key      [out] Destination of a newly created private key pair
@@ -29,7 +29,7 @@ int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key)
    LTC_ARGCHK(prng != NULL);
    LTC_ARGCHK(prng != NULL);
    LTC_ARGCHK(key  != NULL);
    LTC_ARGCHK(key  != NULL);
 
 
-   if ((err = crypto_sign_keypair(prng, wprng, key->pub, key->priv)) != CRYPT_OK) {
+   if ((err = tweetnacl_crypto_sign_keypair(prng, wprng, key->pub, key->priv)) != CRYPT_OK) {
       return err;
       return err;
    }
    }
 
 

+ 3 - 3
src/pk/ed25519/ed25519_set_key.c

@@ -10,13 +10,13 @@
 
 
 /**
 /**
   @file ed25519_set_ku.c
   @file ed25519_set_ku.c
-  Set the parameters of a Ed25519 key, Steffen Jaeckel
+  Set the parameters of an Ed25519 key, Steffen Jaeckel
 */
 */
 
 
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
 
 
 /**
 /**
-   Set the parameters of a Ed25519 key
+   Set the parameters of an Ed25519 key
 
 
    In case sk and pk are given it is validated that pk is really the
    In case sk and pk are given it is validated that pk is really the
    corresponding public part of the key pair.
    corresponding public part of the key pair.
@@ -37,7 +37,7 @@ int ed25519_set_key(const unsigned char *sk, unsigned long sklen,
    if (sk != NULL) {
    if (sk != NULL) {
       LTC_ARGCHK(sklen == 32uL);
       LTC_ARGCHK(sklen == 32uL);
       XMEMCPY(key->priv, sk, sizeof(key->priv));
       XMEMCPY(key->priv, sk, sizeof(key->priv));
-      crypto_sk_to_pk(key->pub, key->priv);
+      tweetnacl_crypto_sk_to_pk(key->pub, key->priv);
       if (pk != NULL) {
       if (pk != NULL) {
          LTC_ARGCHK(pklen == 32uL);
          LTC_ARGCHK(pklen == 32uL);
          if (XMEM_NEQ(pk, key->pub, sizeof(key->pub)) != 0) {
          if (XMEM_NEQ(pk, key->pub, sizeof(key->pub)) != 0) {

+ 7 - 7
src/pk/ed25519/ed25519_sign.c

@@ -10,15 +10,15 @@
 
 
 /**
 /**
   @file ed25519_shared_secret.c
   @file ed25519_shared_secret.c
-  Create a Ed25519 signature, Steffen Jaeckel
+  Create an Ed25519 signature, Steffen Jaeckel
 */
 */
 
 
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
 
 
 /**
 /**
-   Create a Ed25519 signature.
-   @param private_key     The private ed25519 key in the pair
-   @param public_key      The public ed25519 key in the pair
+   Create an Ed25519 signature.
+   @param private_key     The private Ed25519 key in the pair
+   @param public_key      The public Ed25519 key in the pair
    @param out             [out] The destination of the shared data
    @param out             [out] The destination of the shared data
    @param outlen          [in/out] The max size and resulting size of the shared data.
    @param outlen          [in/out] The max size and resulting size of the shared data.
    @return CRYPT_OK if successful
    @return CRYPT_OK if successful
@@ -48,9 +48,9 @@ int ed25519_sign(const unsigned char  *msg, unsigned long msglen,
    s = XMALLOC(smlen);
    s = XMALLOC(smlen);
    if (s == NULL) return CRYPT_MEM;
    if (s == NULL) return CRYPT_MEM;
 
 
-   err = crypto_sign(s, &smlen,
-                     msg, msglen,
-                     private_key->priv, private_key->pub);
+   err = tweetnacl_crypto_sign(s, &smlen,
+                               msg, msglen,
+                               private_key->priv, private_key->pub);
 
 
    XMEMCPY(sig, s, 64uL);
    XMEMCPY(sig, s, 64uL);
    *siglen = 64uL;
    *siglen = 64uL;

+ 8 - 11
src/pk/ed25519/ed25519_verify.c

@@ -10,15 +10,15 @@
 
 
 /**
 /**
   @file ed25519_verify.c
   @file ed25519_verify.c
-  Verify a Ed25519 signature, Steffen Jaeckel
+  Verify an Ed25519 signature, Steffen Jaeckel
 */
 */
 
 
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
 
 
 /**
 /**
-   Verify a Ed25519 signature.
-   @param private_key     The private curve25519 key in the pair
-   @param public_key      The public curve25519 key in the pair
+   Verify an Ed25519 signature.
+   @param private_key     The private Ed25519 key in the pair
+   @param public_key      The public Ed25519 key in the pair
    @param out             [out] The destination of the shared data
    @param out             [out] The destination of the shared data
    @param outlen          [in/out] The max size and resulting size of the shared data.
    @param outlen          [in/out] The max size and resulting size of the shared data.
    @param stat            [out] The result of the signature verification, 1==valid, 0==invalid
    @param stat            [out] The result of the signature verification, 1==valid, 0==invalid
@@ -51,19 +51,16 @@ int ed25519_verify(const  unsigned char *msg, unsigned long msglen,
    XMEMCPY(m, sig, siglen);
    XMEMCPY(m, sig, siglen);
    XMEMCPY(m + siglen, msg, msglen);
    XMEMCPY(m + siglen, msg, msglen);
 
 
-   err = crypto_sign_open(m, &mlen,
-                          m, mlen,
-                          public_key->pub);
+   err = tweetnacl_crypto_sign_open(stat,
+                                    m, &mlen,
+                                    m, mlen,
+                                    public_key->pub);
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
    zeromem(m, mlen);
    zeromem(m, mlen);
 #endif
 #endif
    XFREE(m);
    XFREE(m);
 
 
-   if (err == CRYPT_OK) {
-      *stat = 1;
-   }
-
    return err;
    return err;
 }
 }
 
 

+ 2 - 2
src/pk/rsa/rsa_import_pkcs8.c

@@ -39,10 +39,10 @@
  */
  */
 
 
 /**
 /**
-  Import an RSAPublicKey or RSAPrivateKey in PKCS#8 format
+  Import an RSAPrivateKey in PKCS#8 format
   @param in        The packet to import from
   @param in        The packet to import from
   @param inlen     It's length (octets)
   @param inlen     It's length (octets)
-  @param passwd    The password for decrypting privkey (NOT SUPPORTED YET)
+  @param passwd    The password for decrypting privkey
   @param passwdlen Password's length (octets)
   @param passwdlen Password's length (octets)
   @param key       [out] Destination for newly imported key
   @param key       [out] Destination for newly imported key
   @return CRYPT_OK if successful, upon error allocated memory is freed
   @return CRYPT_OK if successful, upon error allocated memory is freed

+ 2 - 53
src/pk/x25519/x25519_export.c

@@ -27,62 +27,11 @@ int x25519_export(      unsigned char *out, unsigned long *outlen,
                                   int  which,
                                   int  which,
                   const    curve25519_key *key)
                   const    curve25519_key *key)
 {
 {
-   int err, std;
-   const char* OID;
-   unsigned long oid[16], oidlen;
-   ltc_asn1_list alg_id[1];
-   unsigned char private_key[34];
-   unsigned long version, private_key_len = sizeof(private_key);
-
-   LTC_ARGCHK(out       != NULL);
-   LTC_ARGCHK(outlen    != NULL);
-   LTC_ARGCHK(key       != NULL);
+   LTC_ARGCHK(key != NULL);
 
 
    if (key->algo != PKA_X25519) return CRYPT_PK_INVALID_TYPE;
    if (key->algo != PKA_X25519) return CRYPT_PK_INVALID_TYPE;
 
 
-   std = which & PK_STD;
-   which &= ~PK_STD;
-
-   if (which == PK_PRIVATE) {
-      if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
-
-      if ((err = pk_get_oid(PKA_X25519, &OID)) != CRYPT_OK) {
-         return err;
-      }
-      oidlen = sizeof(oid)/sizeof(oid[0]);
-      if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
-         return err;
-      }
-
-      LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
-
-      /* encode private key as PKCS#8 */
-      if ((err = der_encode_octet_string(key->priv, 32uL, private_key, &private_key_len)) != CRYPT_OK) {
-         return err;
-      }
-
-      version = 0;
-      err = der_encode_sequence_multi(out, outlen,
-                                LTC_ASN1_SHORT_INTEGER,            1uL, &version,
-                                LTC_ASN1_SEQUENCE,                 1uL, alg_id,
-                                LTC_ASN1_OCTET_STRING, private_key_len, private_key,
-                                LTC_ASN1_EOL,                      0uL, NULL);
-   } else {
-      if (std == PK_STD) {
-         /* encode public key as SubjectPublicKeyInfo */
-         err = x509_encode_subject_public_key_info(out, outlen, PKA_X25519, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0uL);
-      } else {
-         if (*outlen < sizeof(key->pub)) {
-            err = CRYPT_BUFFER_OVERFLOW;
-         } else {
-            XMEMCPY(out, key->pub, sizeof(key->pub));
-            err = CRYPT_OK;
-         }
-         *outlen = sizeof(key->pub);
-      }
-   }
-
-   return err;
+   return ec25519_export(out, outlen, which, key);
 }
 }
 
 
 #endif
 #endif

+ 1 - 41
src/pk/x25519/x25519_import.c

@@ -25,11 +25,7 @@
 int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key)
 int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *key)
 {
 {
    int err;
    int err;
-   const char *oid;
-   ltc_asn1_list alg_id[1];
-   unsigned char private_key[34];
-   unsigned long version, key_len;
-   unsigned long tmpoid[16];
+   unsigned long key_len;
 
 
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(key != NULL);
    LTC_ARGCHK(key != NULL);
@@ -48,43 +44,7 @@ int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *
    if ((err = x509_decode_subject_public_key_info(in, inlen, PKA_X25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
    if ((err = x509_decode_subject_public_key_info(in, inlen, PKA_X25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
       key->type = PK_PUBLIC;
       key->type = PK_PUBLIC;
       key->algo = PKA_X25519;
       key->algo = PKA_X25519;
-      return CRYPT_OK;
-   }
-
-   LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
-
-   key_len = sizeof(private_key);
-   if ((err = der_decode_sequence_multi(in, inlen,
-                             LTC_ASN1_SHORT_INTEGER,    1uL, &version,
-                             LTC_ASN1_SEQUENCE,         1uL, alg_id,
-                             LTC_ASN1_OCTET_STRING, key_len, private_key,
-                             LTC_ASN1_EOL,              0uL, NULL)) != CRYPT_OK) {
-      goto out;
-   }
-
-   if ((err = pk_get_oid(PKA_X25519, &oid)) != CRYPT_OK) {
-      goto out;
    }
    }
-   if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
-      goto out;
-   }
-
-   if (version == 0) {
-      key_len = sizeof(key->priv);
-      if ((err = der_decode_octet_string(private_key, sizeof(private_key), key->priv, &key_len)) == CRYPT_OK) {
-         crypto_scalarmult_base(key->pub, key->priv);
-         key->type = PK_PRIVATE;
-         key->algo = PKA_X25519;
-      }
-   } else {
-      err = CRYPT_PK_INVALID_TYPE;
-   }
-
-out:
-#ifdef LTC_CLEAN_STACK
-   zeromem(private_key, sizeof(private_key));
-#endif
-
    return err;
    return err;
 }
 }
 
 

+ 38 - 0
src/pk/x25519/x25519_import_pkcs8.c

@@ -0,0 +1,38 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+#include "tomcrypt_private.h"
+
+/**
+  @file x25519_import_pkcs8.c
+  Import a X25519 key in PKCS#8 format, Steffen Jaeckel
+*/
+
+#ifdef LTC_CURVE25519
+
+/**
+  Import a X25519 private key in PKCS#8 format
+  @param in        The DER-encoded PKCS#8-formatted private key
+  @param inlen     The length of the input data
+  @param passwd    The password to decrypt the private key
+  @param passwdlen Password's length (octets)
+  @param key       [out] Where to import the key to
+  @return CRYPT_OK if successful, on error all allocated memory is freed automatically
+*/
+int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
+                       const void *pwd, unsigned long pwdlen,
+                       curve25519_key *key)
+{
+   return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, PKA_X25519, tweetnacl_crypto_scalarmult_base, key);
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */

+ 1 - 1
src/pk/x25519/x25519_make_key.c

@@ -37,7 +37,7 @@ int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key)
       return CRYPT_ERROR_READPRNG;
       return CRYPT_ERROR_READPRNG;
    }
    }
 
 
-   crypto_scalarmult_base(key->pub, key->priv);
+   tweetnacl_crypto_scalarmult_base(key->pub, key->priv);
 
 
    key->type = PK_PRIVATE;
    key->type = PK_PRIVATE;
    key->algo = PKA_X25519;
    key->algo = PKA_X25519;

+ 4 - 4
src/pk/x25519/x25519_set_ku.c → src/pk/x25519/x25519_set_key.c

@@ -28,16 +28,16 @@
    @param key      [out] Destination of the key
    @param key      [out] Destination of the key
    @return CRYPT_OK if successful
    @return CRYPT_OK if successful
 */
 */
-int x25519_set_ku(const unsigned char *k, unsigned long klen,
-                  const unsigned char *u, unsigned long ulen,
-                           curve25519_key *key)
+int x25519_set_key(const unsigned char *k, unsigned long klen,
+                   const unsigned char *u, unsigned long ulen,
+                        curve25519_key *key)
 {
 {
    LTC_ARGCHK(key != NULL);
    LTC_ARGCHK(key != NULL);
 
 
    if (k != NULL) {
    if (k != NULL) {
       LTC_ARGCHK(klen == 32uL);
       LTC_ARGCHK(klen == 32uL);
       XMEMCPY(key->priv, k, sizeof(key->priv));
       XMEMCPY(key->priv, k, sizeof(key->priv));
-      crypto_scalarmult_base(key->pub, key->priv);
+      tweetnacl_crypto_scalarmult_base(key->pub, key->priv);
       if (u != NULL) {
       if (u != NULL) {
          LTC_ARGCHK(ulen == 32uL);
          LTC_ARGCHK(ulen == 32uL);
          if (XMEM_NEQ(u, key->pub, sizeof(key->pub)) != 0) {
          if (XMEM_NEQ(u, key->pub, sizeof(key->pub)) != 0) {

+ 3 - 3
src/pk/x25519/x25519_shared_secret.c

@@ -17,8 +17,8 @@
 
 
 /**
 /**
    Create a X25519 shared secret.
    Create a X25519 shared secret.
-   @param private_key     The private Curve25519 key in the pair
-   @param public_key      The public Curve25519 key in the pair
+   @param private_key     The private X25519 key in the pair
+   @param public_key      The public X25519 key in the pair
    @param out             [out] The destination of the shared data
    @param out             [out] The destination of the shared data
    @param outlen          [in/out] The max size and resulting size of the shared data.
    @param outlen          [in/out] The max size and resulting size of the shared data.
    @return CRYPT_OK if successful
    @return CRYPT_OK if successful
@@ -39,7 +39,7 @@ int x25519_shared_secret(const    curve25519_key *private_key,
       return CRYPT_BUFFER_OVERFLOW;
       return CRYPT_BUFFER_OVERFLOW;
    }
    }
 
 
-   crypto_scalarmult(out, private_key->priv, public_key->pub);
+   tweetnacl_crypto_scalarmult(out, private_key->priv, public_key->pub);
    *outlen = 32uL;
    *outlen = 32uL;
 
 
    return CRYPT_OK;
    return CRYPT_OK;

+ 28 - 4
tests/ed25519_test.c

@@ -43,6 +43,13 @@ static int _rfc_8410_10_test(void)
                        { "MHICAQEwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC"
                        { "MHICAQEwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC"
                          "oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB"
                          "oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB"
                          "Z9w7lshQhqowtrbLDFw4rXAxZuE=", -1 },
                          "Z9w7lshQhqowtrbLDFw4rXAxZuE=", -1 },
+                         /* Another self-created testvector.
+                          * `openssl genpkey -algorithm ed25519 -pass stdin -aes128`
+                          */
+                       { "MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAiFflnrBOdwjwICCAAw"
+                         "DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEMzFYoqiT6gxwFx2EA55MUYEQFD1"
+                         "ZLxPNhm4YAsMZaxu5qpLjiZbkWsTHxURb6WhSW8GAbNbTwxeOaA02sUhJg8rx44/"
+                         "N9PzN2QGzIQ1Yv/vHqQ=", -1 },
    };
    };
    unsigned n;
    unsigned n;
    curve25519_key key;
    curve25519_key key;
@@ -52,10 +59,22 @@ static int _rfc_8410_10_test(void)
    for (n = 0; n < sizeof(rfc_8410_10)/sizeof(rfc_8410_10[0]); ++n) {
    for (n = 0; n < sizeof(rfc_8410_10)/sizeof(rfc_8410_10[0]); ++n) {
       buflen = sizeof(buf);
       buflen = sizeof(buf);
       DO(base64_decode(rfc_8410_10[n].b64, strlen(rfc_8410_10[n].b64), buf, &buflen));
       DO(base64_decode(rfc_8410_10[n].b64, strlen(rfc_8410_10[n].b64), buf, &buflen));
-      if (rfc_8410_10[n].type == -2) {
-         DO(ed25519_import_x509(buf, buflen, &key));
-      } else {
-         DO(ed25519_import(buf, buflen, &key));
+      switch (n) {
+         case 0:
+            DO(ed25519_import(buf, buflen, &key));
+            break;
+         case 1:
+            DO(ed25519_import_x509(buf, buflen, &key));
+            break;
+         case 2:
+         case 3:
+            DO(ed25519_import_pkcs8(buf, buflen, NULL, 0, &key));
+            break;
+         case 4:
+            DO(ed25519_import_pkcs8(buf, buflen, "123456", 6, &key));
+            break;
+         default:
+            return CRYPT_FAIL_TESTVECTOR;
       }
       }
       zeromem(buf, sizeof(buf));
       zeromem(buf, sizeof(buf));
       if (rfc_8410_10[n].type > 0) {
       if (rfc_8410_10[n].type > 0) {
@@ -212,6 +231,11 @@ static int _rfc_8032_7_1_test(void)
 int ed25519_test(void)
 int ed25519_test(void)
 {
 {
    int ret;
    int ret;
+   curve25519_key key;
+
+   if ((ret = ed25519_make_key(&yarrow_prng, find_prng("yarrow"), &key)) != CRYPT_OK) {
+      return ret;
+   }
 
 
    if (ltc_mp.name == NULL) return CRYPT_NOP;
    if (ltc_mp.name == NULL) return CRYPT_NOP;
 
 

+ 47 - 9
tests/x25519_test.c

@@ -56,7 +56,7 @@ static int _rfc_7748_5_2_test(void)
    unsigned long n;
    unsigned long n;
 
 
    for (n = 0; n < sizeof(rfc_7748_5_2)/sizeof(rfc_7748_5_2[0]); ++n) {
    for (n = 0; n < sizeof(rfc_7748_5_2)/sizeof(rfc_7748_5_2[0]); ++n) {
-      crypto_scalarmult(out, rfc_7748_5_2[n].scalar, rfc_7748_5_2[n].u_in);
+      tweetnacl_crypto_scalarmult(out, rfc_7748_5_2[n].scalar, rfc_7748_5_2[n].u_in);
       if (compare_testvector(out, sizeof(out), rfc_7748_5_2[n].u_out, sizeof(rfc_7748_5_2[n].u_out), "x25519 RFC 7748 Ch. 5.2", n) != 0) {
       if (compare_testvector(out, sizeof(out), rfc_7748_5_2[n].u_out, sizeof(rfc_7748_5_2[n].u_out), "x25519 RFC 7748 Ch. 5.2", n) != 0) {
          return CRYPT_FAIL_TESTVECTOR;
          return CRYPT_FAIL_TESTVECTOR;
       }
       }
@@ -101,10 +101,10 @@ static int _rfc_7748_6_test(void)
    unsigned char buf[32];
    unsigned char buf[32];
    unsigned long buflen = sizeof(buf);
    unsigned long buflen = sizeof(buf);
 
 
-   DO(x25519_set_ku(alice_private, sizeof(alice_private), alice_public, sizeof(alice_public), &alice_priv));
-   DO(x25519_set_ku(bob_private, sizeof(bob_private), bob_public, sizeof(bob_public), &bob_priv));
-   DO(x25519_set_ku(NULL, 0, alice_public, sizeof(alice_public), &alice_pub));
-   DO(x25519_set_ku(NULL, 0, bob_public, sizeof(bob_public), &bob_pub));
+   DO(x25519_set_key(alice_private, sizeof(alice_private), alice_public, sizeof(alice_public), &alice_priv));
+   DO(x25519_set_key(bob_private, sizeof(bob_private), bob_public, sizeof(bob_public), &bob_priv));
+   DO(x25519_set_key(NULL, 0, alice_public, sizeof(alice_public), &alice_pub));
+   DO(x25519_set_key(NULL, 0, bob_public, sizeof(bob_public), &bob_pub));
 
 
    DO(x25519_shared_secret(&alice_priv, &bob_pub, buf, &buflen));
    DO(x25519_shared_secret(&alice_priv, &bob_pub, buf, &buflen));
    DO(compare_testvector(buf, buflen, shared_secret, sizeof(shared_secret), "x25519 - RFC 7748 Ch. 6", 0));
    DO(compare_testvector(buf, buflen, shared_secret, sizeof(shared_secret), "x25519 - RFC 7748 Ch. 6", 0));
@@ -120,7 +120,7 @@ static int _rfc_7748_6_test(void)
 static int _rfc_8410_10_test(void)
 static int _rfc_8410_10_test(void)
 {
 {
    const struct {
    const struct {
-      const char* b64;
+      const char *b64;
    } rfc_8410_10[] = {
    } rfc_8410_10[] = {
                          /* RFC 8410 - 10.2.  Example X25519 Certificate */
                          /* RFC 8410 - 10.2.  Example X25519 Certificate */
                        { "MIIBLDCB36ADAgECAghWAUdKKo3DMDAFBgMrZXAwGTEXMBUGA1UEAwwOSUVURiBUZX"
                        { "MIIBLDCB36ADAgECAghWAUdKKo3DMDAFBgMrZXAwGTEXMBUGA1UEAwwOSUVURiBUZX"
@@ -129,7 +129,8 @@ static int _rfc_8410_10_test(void)
                          "ga9OukqY6qm05qo0UwQzAPBgNVHRMBAf8EBTADAQEAMA4GA1UdDwEBAAQEAwIDCDAg"
                          "ga9OukqY6qm05qo0UwQzAPBgNVHRMBAf8EBTADAQEAMA4GA1UdDwEBAAQEAwIDCDAg"
                          "BgNVHQ4BAQAEFgQUmx9e7e0EM4Xk97xiPFl1uQvIuzswBQYDK2VwA0EAryMB/t3J5v"
                          "BgNVHQ4BAQAEFgQUmx9e7e0EM4Xk97xiPFl1uQvIuzswBQYDK2VwA0EAryMB/t3J5v"
                          "/BzKc9dNZIpDmAgs3babFOTQbs+BolzlDUwsPrdGxO3YNGhW7Ibz3OGhhlxXrCe1Cg"
                          "/BzKc9dNZIpDmAgs3babFOTQbs+BolzlDUwsPrdGxO3YNGhW7Ibz3OGhhlxXrCe1Cg"
-                         "w1AH9efZBw==" },
+                         "w1AH9efZBw=="
+                       },
    };
    };
    unsigned n;
    unsigned n;
    curve25519_key key;
    curve25519_key key;
@@ -144,6 +145,40 @@ static int _rfc_8410_10_test(void)
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 
+static int _x25519_pkcs8_test(void)
+{
+   const struct {
+      const char *b64, *pass;
+   } _x25519_pkcs8[] = {
+                          /* `openssl genpkey -algorithm x25519 -pass stdin -aes128` */
+                          {
+                            "MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjG5kRkEihOvQICCAAw"
+                            "DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEHPLHLoCvesRyeToyMtGHWcEQM1+"
+                            "FMpSO5DplX3d+YGTAvf0WxWaBff1q4bfKDn/7IoWQT1e4Fe6Psj62Vy9T69o3+Uy"
+                            "VM6mdIOXGOkAtaMSsSk=",
+                            "123456"
+                          },
+                          /* `openssl genpkey -algorithm x25519 -pass stdin` */
+                          {
+                            "MC4CAQAwBQYDK2VuBCIEIEAInaUdx+fQFfghpCzw/WdItRT3+FnPSkrU9TcIZTZW",
+                            NULL
+                          },
+   };
+   unsigned n;
+   curve25519_key key;
+   unsigned char buf[1024];
+   unsigned long buflen, passlen;
+   for (n = 0; n < sizeof(_x25519_pkcs8)/sizeof(_x25519_pkcs8[0]); ++n) {
+      buflen = sizeof(buf);
+      DO(base64_decode(_x25519_pkcs8[n].b64, strlen(_x25519_pkcs8[n].b64), buf, &buflen));
+      if (_x25519_pkcs8[n].pass != NULL) passlen = strlen(_x25519_pkcs8[n].pass);
+      else passlen = 0;
+      DO(x25519_import_pkcs8(buf, buflen, _x25519_pkcs8[n].pass, passlen, &key));
+      zeromem(buf, sizeof(buf));
+   }
+   return CRYPT_OK;
+}
+
 static int _x25519_compat_test(void)
 static int _x25519_compat_test(void)
 {
 {
    curve25519_key priv, pub, imported;
    curve25519_key priv, pub, imported;
@@ -157,8 +192,8 @@ static int _x25519_compat_test(void)
 
 
    DO(x25519_make_key(&yarrow_prng, prng_idx, &priv));
    DO(x25519_make_key(&yarrow_prng, prng_idx, &priv));
 
 
-   DO(x25519_export(buf, &buflen, PK_PRIVATE, &priv));
-   DO(x25519_import(buf, buflen, &imported));
+   DO(x25519_export(buf, &buflen, PK_PRIVATE | PK_STD, &priv));
+   DO(x25519_import_pkcs8(buf, buflen, NULL, 0, &imported));
    DO(do_compare_testvector(&priv, sizeof(priv), &imported, sizeof(imported), "priv after ex-&import", __LINE__));
    DO(do_compare_testvector(&priv, sizeof(priv), &imported, sizeof(imported), "priv after ex-&import", __LINE__));
    XMEMSET(&imported, 0, sizeof(imported));
    XMEMSET(&imported, 0, sizeof(imported));
 
 
@@ -201,6 +236,9 @@ int x25519_test(void)
    if ((ret = _rfc_8410_10_test()) != CRYPT_OK) {
    if ((ret = _rfc_8410_10_test()) != CRYPT_OK) {
       return ret;
       return ret;
    }
    }
+   if ((ret = _x25519_pkcs8_test()) != CRYPT_OK) {
+      return ret;
+   }
    if ((ret = _x25519_compat_test()) != CRYPT_OK) {
    if ((ret = _x25519_compat_test()) != CRYPT_OK) {
       return ret;
       return ret;
    }
    }