Expanded support for Curve25519/Curve448 and TLS v1.3 sniffer (#4335)

* Fixes for building with Ed/Curve25519 only. Fix for IoT safe demo to exit after running once. Added `WOLFSSL_DH_EXTRA` to `--enable-all` and `--enable-sniffer`. Cleanup uses of `==` in configure.ac. Various spelling fixes.

* Fix for sniffer with TLS v1.3 session tickets.

* Fix for ASN Template Ed25519 key export (missing version / not setting OID correctly).

* Add key import/export support for Curve25519/Curve448. Refactor of the 25519/448 ASN code to combine duplicate code.

* Refactor of Curve25519 code. Improved public key export to handle generation when only private is set. Improved private scalar buffer sizing.

* Fix for static ephemeral loading of file buffer.

* Added sniffer Curve25519 support and test case.

* Fix for sniffer to not use ECC for X25519 if both are set.

* Fix Curve448 public export when only private is set.

* Fix for `dh_generate_test` for small stack size.

* Reduce stack size use on new asymmetric DER import/export functions. Cleanup pub length calc.

* Fix invalid comment.
This commit is contained in:
David Garske 2021-08-31 16:28:24 -07:00 committed by GitHub
parent 0f0ba46ac5
commit 9b6cf56a6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 1353 additions and 1029 deletions

View File

@ -384,6 +384,7 @@ static int server_loop(void)
wolfSSL_CTX_free(srv_ctx); srv_ctx = NULL; wolfSSL_CTX_free(srv_ctx); srv_ctx = NULL;
server_state = 0; server_state = 0;
return -1; /* exit test loop, so it doesn't keep running forever */
} }
} }

View File

@ -3,13 +3,19 @@
# run from wolfssl root # run from wolfssl root
# SECP256R1 # SECP256R1
openssl ecparam -name secp256r1 -genkey -noout -out certs/statickeys/ecc-secp256r1.pem -noout openssl ecparam -name prime256v1 -genkey -noout -out certs/statickeys/ecc-secp256r1.pem
openssl ec -inform pem -in certs/statickeys/ecc-secp256r1.pem -outform der -out certs/statickeys/ecc-secp256r1.der openssl ec -inform pem -in certs/statickeys/ecc-secp256r1.pem -outform der -out certs/statickeys/ecc-secp256r1.der
# DH 2048-bit (keySz = 29) # DH 2048-bit (keySz = 29)
# Using one generated and capture with wolfSSL using wc_DhGenerateKeyPair (openssl generates DH keys with 2048-bits... based on the DH "p" prime size) # Using one generated and capture with wolfSSL using wc_DhGenerateKeyPair (openssl generates DH keys with 2048-bits... based on the DH "p" prime size)
#openssl genpkey -paramfile certs/statickeys/dh-ffdhe2048-params.pem -out certs/statickeys/dh-ffdhe2048.der openssl genpkey -paramfile certs/statickeys/dh-ffdhe2048-params.pem -outform -out certs/statickeys/dh-ffdhe2048.pem
openssl pkey -inform der -in certs/statickeys/dh-ffdhe2048.der -outform pem -out certs/statickeys/dh-ffdhe2048.pem openssl pkey -inform pem -in certs/statickeys/dh-ffdhe2048.pem -outform der -out certs/statickeys/dh-ffdhe2048.der
# Export DH public key as DER and convert to PEM # Export DH public key as DER and PEM
openssl pkey -inform der -in certs/statickeys/dh-ffdhe2048.der -outform der -out certs/statickeys/dh-ffdhe2048-pub.der -pubout openssl pkey -inform pem -in certs/statickeys/dh-ffdhe2048.pem -outform der -out certs/statickeys/dh-ffdhe2048-pub.der -pubout
openssl pkey -inform der -in certs/statickeys/dh-ffdhe2048.der -outform pem -out certs/statickeys/dh-ffdhe2048-pub.pem -pubout openssl pkey -inform pem -in certs/statickeys/dh-ffdhe2048.pem -outform pem -out certs/statickeys/dh-ffdhe2048-pub.pem -pubout
# X25519 (Curve25519)
openssl genpkey -algorithm x25519 -outform pem -out certs/statickeys/x25519.pem
openssl pkey -inform pem -in certs/statickeys/x25519.pem -outform der -out certs/statickeys/x25519.der
openssl pkey -inform pem -in certs/statickeys/x25519.pem -outform der -out certs/statickeys/x25519-pub.der -pubout
openssl pkey -inform pem -in certs/statickeys/x25519.pem -outform pem -out certs/statickeys/x25519-pub.pem -pubout

View File

@ -17,3 +17,10 @@ EXTRA_DIST += \
certs/statickeys/dh-ffdhe2048.pem \ certs/statickeys/dh-ffdhe2048.pem \
certs/statickeys/dh-ffdhe2048-pub.der \ certs/statickeys/dh-ffdhe2048-pub.der \
certs/statickeys/dh-ffdhe2048-pub.pem certs/statickeys/dh-ffdhe2048-pub.pem
# Curve25519 Keys
EXTRA_DIST += \
certs/statickeys/x25519.der \
certs/statickeys/x25519.pem \
certs/statickeys/x25519-pub.der \
certs/statickeys/x25519-pub.pem

Binary file not shown.

View File

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VuAyEACbyMx0UNwcICV5poOv16qKUv8Jk5mOomols4/ZbbKiY=
-----END PUBLIC KEY-----

BIN
certs/statickeys/x25519.der Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VuBCIEIHiOMVwzqRnAXjZwG6To78GJjLMVxnnTrCIArvqztw94
-----END PRIVATE KEY-----

View File

@ -491,13 +491,19 @@ then
DEFAULT_MAX_CLASSIC_ASYM_KEY_BITS=4096 DEFAULT_MAX_CLASSIC_ASYM_KEY_BITS=4096
# Enable multiple attribute additions such as DC # Enable multiple attribute additions such as DC
AM_CFLAGS="-DWOLFSSL_MULTI_ATTRIB $AM_CFLAGS" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_MULTI_ATTRIB"
# Enable AES Decrypt, AES ECB, Alt Names, DER Load, Keep Certs, CRL IO with Timeout # Enable AES Decrypt, AES ECB
AM_CFLAGS="$AM_CFLAGS -DHAVE_AES_DECRYPT -DHAVE_AES_ECB -DWOLFSSL_ALT_NAMES -DWOLFSSL_DER_LOAD -DKEEP_OUR_CERT -DKEEP_PEER_CERT" AM_CFLAGS="$AM_CFLAGS -DHAVE_AES_DECRYPT -DHAVE_AES_ECB"
# Enable Alt Names, DER Load, Keep Certs, CRL IO with Timeout
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALT_NAMES -DWOLFSSL_DER_LOAD -DKEEP_OUR_CERT -DKEEP_PEER_CERT"
# Enable ECC Key Gen checks # Enable ECC Key Gen checks
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_KEYGEN" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_KEYGEN"
# Enable DH Extra
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DH_EXTRA"
fi fi
@ -577,7 +583,7 @@ then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT"
fi fi
if test "$ENABLED_FIPS" == "no" if test "$ENABLED_FIPS" = "no"
then then
test "$enable_xchacha" = "" && enable_xchacha=yes test "$enable_xchacha" = "" && enable_xchacha=yes
test "$enable_ed25519" = "" && enable_ed25519=yes test "$enable_ed25519" = "" && enable_ed25519=yes
@ -1003,8 +1009,8 @@ AC_ARG_ENABLE([opensslall],
if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || \ if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || \
test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || \ test "$ENABLED_WPAS_DPP" = "yes" || test "$ENABLED_SMIME" = "yes" || \
test "$ENABLED_HAPROXY" = "yes" || test "$ENABLED_BIND" = "yes" || \ test "$ENABLED_HAPROXY" = "yes" || test "$ENABLED_BIND" = "yes" || \
test "$ENABLED_NTP" == "yes" || test "$ENABLED_NETSNMP" = "yes" || \ test "$ENABLED_NTP" = "yes" || test "$ENABLED_NETSNMP" = "yes" || \
test "$ENABLED_OPENRESTY" = "yes" || test "$ENABLED_RSYSLOG" == "yes" test "$ENABLED_OPENRESTY" = "yes" || test "$ENABLED_RSYSLOG" = "yes"
then then
ENABLED_OPENSSLALL="yes" ENABLED_OPENSSLALL="yes"
fi fi
@ -1026,7 +1032,7 @@ if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_NGINX" = "yes" || \
test "$ENABLED_SNIFFER" = "yes" || test "$ENABLED_OPENSSLALL" = "yes" || \ test "$ENABLED_SNIFFER" = "yes" || test "$ENABLED_OPENSSLALL" = "yes" || \
test "$ENABLED_LIBWEBSOCKETS" = "yes" || \ test "$ENABLED_LIBWEBSOCKETS" = "yes" || \
test "x$ENABLED_LIGHTY" = "xyes" || test "$ENABLED_LIBSSH2" = "yes" || \ test "x$ENABLED_LIGHTY" = "xyes" || test "$ENABLED_LIBSSH2" = "yes" || \
test "x$ENABLED_NTP" = "xyes" || test "$ENABLED_RSYSLOG" == "yes" test "x$ENABLED_NTP" = "xyes" || test "$ENABLED_RSYSLOG" = "yes"
then then
ENABLED_OPENSSLEXTRA="yes" ENABLED_OPENSSLEXTRA="yes"
fi fi
@ -2893,6 +2899,11 @@ else
fi fi
fi fi
if test "x$ENABLED_SNIFFER" = "xyes" && test "x$ENABLED_DH" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DH_EXTRA"
fi
# Anonymous # Anonymous
AC_ARG_ENABLE([anon], AC_ARG_ENABLE([anon],
@ -2901,7 +2912,8 @@ AC_ARG_ENABLE([anon],
[ ENABLED_ANON=no ] [ ENABLED_ANON=no ]
) )
if test "x$ENABLED_WPAS" = "xyes" || test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_HAPROXY" = "xyes" || test "$ENABLED_RSYSLOG" == "yes" if test "x$ENABLED_WPAS" = "xyes" || test "x$ENABLED_NGINX" = "xyes" || \
test "x$ENABLED_HAPROXY" = "xyes" || test "$ENABLED_RSYSLOG" = "yes"
then then
ENABLED_ANON=yes ENABLED_ANON=yes
fi fi
@ -3593,7 +3605,7 @@ if test "$ENABLED_CRL" != "no"
then then
AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL" AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL"
fi fi
if test "$ENABLED_CRL" == "io" if test "$ENABLED_CRL" = "io"
then then
AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL_IO" AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL_IO"
fi fi
@ -6174,7 +6186,7 @@ then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TRACK_MEMORY -DWOLFSSL_DEBUG_MEMORY" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TRACK_MEMORY -DWOLFSSL_DEBUG_MEMORY"
fi fi
if test "x$ENABLED_MEMTEST" == "xfail" if test "x$ENABLED_MEMTEST" = "xfail"
then then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FORCE_MALLOC_FAIL_TEST" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_FORCE_MALLOC_FAIL_TEST"
fi fi
@ -6386,8 +6398,9 @@ AS_IF([test "x$ENABLED_LEANTLS" = "xyes" && \
AS_IF([test "x$ENABLED_SNIFFER" = "xyes" && \ AS_IF([test "x$ENABLED_SNIFFER" = "xyes" && \
test "x$ENABLED_RSA" = "xno" && \ test "x$ENABLED_RSA" = "xno" && \
test "x$ENABLED_ECC" = "xno"], test "x$ENABLED_ECC" = "xno" && \
[AC_MSG_ERROR([please enable ecc or rsa if enabling sniffer.])]) test "x$ENABLED_CURVE25519" = "xno"],
[AC_MSG_ERROR([please enable ecc, rsa or curve25519 if enabling sniffer.])])
# Lean TLS forces off prereqs of SCEP. # Lean TLS forces off prereqs of SCEP.
AS_IF([test "x$ENABLED_SCEP" = "xyes" && \ AS_IF([test "x$ENABLED_SCEP" = "xyes" && \

View File

@ -2191,6 +2191,13 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
err_sys_ex(runWithErrors, "error loading static DH key"); err_sys_ex(runWithErrors, "error loading static DH key");
} }
#endif #endif
#ifdef HAVE_CURVE25519
ret = wolfSSL_CTX_set_ephemeral_key(ctx, WC_PK_TYPE_CURVE25519,
"./certs/statickeys/x25519.pem", 0, WOLFSSL_FILETYPE_PEM);
if (ret != 0) {
err_sys_ex(runWithErrors, "error loading static X25519 key");
}
#endif
#endif /* WOLFSSL_SNIFFER && WOLFSSL_STATIC_EPHEMERAL */ #endif /* WOLFSSL_SNIFFER && WOLFSSL_STATIC_EPHEMERAL */
if (cipherList && !useDefCipherList) { if (cipherList && !useDefCipherList) {

View File

@ -91,6 +91,7 @@ EXTRA_DIST += scripts/testsuite.pcap \
scripts/sniffer-ipv6.pcap \ scripts/sniffer-ipv6.pcap \
scripts/sniffer-tls13-dh.pcap \ scripts/sniffer-tls13-dh.pcap \
scripts/sniffer-tls13-ecc.pcap \ scripts/sniffer-tls13-ecc.pcap \
scripts/sniffer-tls13-x25519.pcap \
scripts/sniffer-tls13-gen.sh \ scripts/sniffer-tls13-gen.sh \
scripts/sniffer-tls13-hrr.pcap \ scripts/sniffer-tls13-hrr.pcap \
scripts/ping.test \ scripts/ping.test \

View File

@ -39,6 +39,16 @@ then
[ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 DH\n" && exit 1 [ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 DH\n" && exit 1
fi fi
# TLS v1.3 sniffer test X25519 (and resumption)
if test $# -ne 0
then
./sslSniffer/sslSnifferTest/snifftest ./scripts/sniffer-tls13-x25519.pcap ./certs/statickeys/x25519.pem 127.0.0.1 11111
RESULT=$?
[ $RESULT -ne 0 ] && echo -e "\nsnifftest TLS v1.3 X25519\n" && exit 1
fi
# TLS v1.3 sniffer test hello_retry_request (HRR) with ECDHE # TLS v1.3 sniffer test hello_retry_request (HRR) with ECDHE
if test $# -ne 0 if test $# -ne 0
then then

View File

@ -7,6 +7,8 @@
# Script to generate wireshark trace for sniffer-tls13-dh.pcap # Script to generate wireshark trace for sniffer-tls13-dh.pcap
#./configure --enable-sniffer --enable-session-ticket --disable-ecc && make #./configure --enable-sniffer --enable-session-ticket --disable-ecc && make
# Run: with dh or ecc
if [ "$1" == "dh" ] || [ "$1" == "ecc" ]; then
# TLS v1.3 # TLS v1.3
./examples/server/server -v 4 -l TLS13-AES128-GCM-SHA256 & ./examples/server/server -v 4 -l TLS13-AES128-GCM-SHA256 &
./examples/client/client -v 4 -l TLS13-AES128-GCM-SHA256 ./examples/client/client -v 4 -l TLS13-AES128-GCM-SHA256
@ -22,8 +24,47 @@
./examples/client/client -v 4 -l TLS13-AES256-GCM-SHA384 -r ./examples/client/client -v 4 -l TLS13-AES256-GCM-SHA384 -r
./examples/server/server -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r & ./examples/server/server -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r &
./examples/client/client -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r ./examples/client/client -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r
fi
# Script to generate wireshark trace for sniffer-tls13-x25519.pcap
#./configure --enable-sniffer --enable-session-ticket --enable-curve25519 --disable-dh --disable-ecc && make
# Run: with x25519
if [ "$1" == "x25519" ]; then
# TLS v1.3
./examples/server/server -v 4 -l TLS13-AES128-GCM-SHA256 -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem &
sleep 0.1
./examples/client/client -v 4 -l TLS13-AES128-GCM-SHA256 -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem
./examples/server/server -v 4 -l TLS13-AES256-GCM-SHA384 -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem &
sleep 0.1
./examples/client/client -v 4 -l TLS13-AES256-GCM-SHA384 -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem
./examples/server/server -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem &
sleep 0.1
./examples/client/client -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem
# TLS v1.3 Resumption
./examples/server/server -v 4 -l TLS13-AES128-GCM-SHA256 -r -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem &
sleep 0.1
./examples/client/client -v 4 -l TLS13-AES128-GCM-SHA256 -r -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem
./examples/server/server -v 4 -l TLS13-AES256-GCM-SHA384 -r -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem &
sleep 0.1
./examples/client/client -v 4 -l TLS13-AES256-GCM-SHA384 -r -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem
./examples/server/server -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r -c ./certs/ed25519/server-ed25519.pem -k ./certs/ed25519/server-ed25519-priv.pem -A ./certs/ed25519/client-ed25519.pem &
sleep 0.1
./examples/client/client -v 4 -l TLS13-CHACHA20-POLY1305-SHA256 -r -c ./certs/ed25519/client-ed25519.pem -k ./certs/ed25519/client-ed25519-priv.pem -A ./certs/ed25519/root-ed25519.pem
fi
# TLS v1.3 Hello Retry Request (save this as sniffer-tls13-hrr.pcap) # TLS v1.3 Hello Retry Request (save this as sniffer-tls13-hrr.pcap)
# ./configure --enable-sniffer CFLAGS="-DWOLFSSL_SNIFFER_WATCH" --disable-dh && make # ./configure --enable-sniffer CFLAGS="-DWOLFSSL_SNIFFER_WATCH" --disable-dh && make
# Run ./scripts/sniffer-tls13-gen.sh hrr
if [ "$1" == "hrr" ]; then
# TLS v1.3 Hello Retry Request
./examples/server/server -v 4 -i -x -g & ./examples/server/server -v 4 -i -x -g &
sleep 0.1
./examples/client/client -v 4 -J ./examples/client/client -v 4 -J
fi

Binary file not shown.

View File

@ -2273,6 +2273,10 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
if (ctx->staticKE.ecKey && ctx->staticKE.weOwnEC) if (ctx->staticKE.ecKey && ctx->staticKE.weOwnEC)
FreeDer(&ctx->staticKE.ecKey); FreeDer(&ctx->staticKE.ecKey);
#endif #endif
#ifdef HAVE_CURVE25519
if (ctx->staticKE.x25519Key && ctx->staticKE.weOwnX25519)
FreeDer(&ctx->staticKE.x25519Key);
#endif
#endif #endif
#ifdef WOLFSSL_STATIC_MEMORY #ifdef WOLFSSL_STATIC_MEMORY
if (ctx->heap != NULL) { if (ctx->heap != NULL) {
@ -6213,6 +6217,9 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#ifndef NO_DH #ifndef NO_DH
ssl->staticKE.weOwnDH = 0; ssl->staticKE.weOwnDH = 0;
#endif #endif
#ifdef HAVE_CURVE25519
ssl->staticKE.weOwnX25519 = 0;
#endif
#endif #endif
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
@ -6987,6 +6994,10 @@ void SSL_ResourceFree(WOLFSSL* ssl)
if (ssl->staticKE.ecKey && ssl->staticKE.weOwnEC) if (ssl->staticKE.ecKey && ssl->staticKE.weOwnEC)
FreeDer(&ssl->staticKE.ecKey); FreeDer(&ssl->staticKE.ecKey);
#endif #endif
#ifdef HAVE_CURVE25519
if (ssl->staticKE.x25519Key && ssl->staticKE.weOwnX25519)
FreeDer(&ssl->staticKE.x25519Key);
#endif
#endif #endif
#ifdef WOLFSSL_STATIC_MEMORY #ifdef WOLFSSL_STATIC_MEMORY
@ -27404,12 +27415,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
case TLS_ASYNC_BUILD: case TLS_ASYNC_BUILD:
{ {
#if (!defined(NO_DH) && !defined(NO_RSA)) || (defined(HAVE_ECC) || \
(defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \
(defined(HAVE_CURVE448) && defined(HAVE_ED448)))
word32 preSigSz, preSigIdx;
#endif
switch(ssl->specs.kea) switch(ssl->specs.kea)
{ {
#ifndef NO_PSK #ifndef NO_PSK
@ -27670,6 +27675,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
case ecc_diffie_hellman_kea: case ecc_diffie_hellman_kea:
{ {
enum wc_HashType hashType; enum wc_HashType hashType;
word32 preSigSz, preSigIdx;
/* curve type, named curve, length(1) */ /* curve type, named curve, length(1) */
args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
@ -28003,6 +28009,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
case diffie_hellman_kea: case diffie_hellman_kea:
{ {
enum wc_HashType hashType; enum wc_HashType hashType;
word32 preSigSz, preSigIdx;
args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; args->idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ;
args->length = LENGTH_SZ * 3; /* p, g, pub */ args->length = LENGTH_SZ * 3; /* p, g, pub */

View File

@ -858,7 +858,7 @@ const char *wolfSSL_OCSP_response_status_str(long s)
return "trylater"; return "trylater";
case OCSP_SIG_REQUIRED: case OCSP_SIG_REQUIRED:
return "sigrequired"; return "sigrequired";
case OCSP_UNAUTHROIZED: case OCSP_UNAUTHORIZED:
return "unauthorized"; return "unauthorized";
default: default:
return "(UNKNOWN)"; return "(UNKNOWN)";

View File

@ -91,6 +91,20 @@
#include <wolfssl/error-ssl.h> #include <wolfssl/error-ssl.h>
#include <wolfssl/sniffer.h> #include <wolfssl/sniffer.h>
#include <wolfssl/sniffer_error.h> #include <wolfssl/sniffer_error.h>
#ifndef NO_RSA
#include <wolfssl/wolfcrypt/rsa.h>
#endif
#ifndef NO_DH
#include <wolfssl/wolfcrypt/dh.h>
#endif
#ifdef HAVE_ECC
#include <wolfssl/wolfcrypt/ecc.h>
#endif
#ifdef HAVE_CURVE25519
#include <wolfssl/wolfcrypt/curve25519.h>
#endif
#ifdef NO_INLINE #ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h> #include <wolfssl/wolfcrypt/misc.h>
#else #else
@ -2146,6 +2160,9 @@ typedef struct {
#ifdef HAVE_ECC #ifdef HAVE_ECC
DerBuffer* ecKey; DerBuffer* ecKey;
#endif #endif
#ifdef HAVE_CURVE25519
DerBuffer* x25519Key;
#endif
#if !defined(NO_RSA) && defined(WOLFSSL_STATIC_RSA) #if !defined(NO_RSA) && defined(WOLFSSL_STATIC_RSA)
DerBuffer* rsaKey; DerBuffer* rsaKey;
#endif #endif
@ -2157,14 +2174,14 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
word32 idx = 0; word32 idx = 0;
int ret; int ret;
DerBuffer* keyBuf; DerBuffer* keyBuf;
#ifdef HAVE_ECC #if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
int useEccCurveId = ECC_CURVE_DEF; int useCurveId = 0;
#endif #endif
int devId = INVALID_DEVID; int devId = INVALID_DEVID;
#ifdef HAVE_ECC #if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
if (ksInfo && ksInfo->curve_id != 0) if (ksInfo && ksInfo->curve_id != 0)
useEccCurveId = ksInfo->curve_id; useCurveId = ksInfo->curve_id;
#endif #endif
#ifdef WOLF_CRYPTO_CB #ifdef WOLF_CRYPTO_CB
devId = CryptoDeviceId; devId = CryptoDeviceId;
@ -2201,9 +2218,9 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
keys->ecKey = session->sslServer->buffers.key; /* try ECC */ keys->ecKey = session->sslServer->buffers.key; /* try ECC */
#endif #endif
} }
#ifdef HAVE_ECC #if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
else { else {
useEccCurveId = -1; /* don't try loading ECC */ useCurveId = -1; /* don't try loading further */
} }
#endif #endif
} }
@ -2365,7 +2382,11 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
#ifdef HAVE_ECC #ifdef HAVE_ECC
/* Static ECC Key */ /* Static ECC Key */
if (useEccCurveId >= ECC_CURVE_DEF && keys->ecKey) { if (useCurveId >= 0 && keys->ecKey
#ifdef HAVE_CURVE25519
&& useCurveId != ECC_X25519
#endif
) {
ecc_key key; ecc_key key;
ecc_key pubKey; ecc_key pubKey;
int length, keyInit = 0, pubKeyInit = 0; int length, keyInit = 0, pubKeyInit = 0;
@ -2422,13 +2443,13 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
} }
/* if curve not provided in key share data, then use private key curve */ /* if curve not provided in key share data, then use private key curve */
if (useEccCurveId == ECC_CURVE_DEF && key.dp) { if (useCurveId == 0 && key.dp) {
useEccCurveId = key.dp->id; useCurveId = key.dp->id;
} }
} }
if (ret == 0) { if (ret == 0) {
ret = wc_ecc_import_x963_ex(input, length, &pubKey, useEccCurveId); ret = wc_ecc_import_x963_ex(input, length, &pubKey, useCurveId);
if (ret != 0) { if (ret != 0) {
SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE); SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
} }
@ -2466,6 +2487,82 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session,
} }
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */
#ifdef HAVE_CURVE25519
/* Static Curve25519 Key */
if (useCurveId == ECC_X25519 && keys->x25519Key) {
curve25519_key key;
curve25519_key pubKey;
int length, keyInit = 0, pubKeyInit = 0;
keyBuf = keys->x25519Key;
#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK
if (KeyCb != NULL && ksInfo) {
ret = KeyCb(session, ksInfo->named_group,
session->srvKs.key, session->srvKs.key_len,
session->cliKs.key, session->cliKs.key_len,
keyBuf, KeyCbCtx, error);
if (ret != 0) {
SetError(-1, error, session, FATAL_ERROR_STATE);
return ret;
}
}
#endif
idx = 0;
ret = wc_curve25519_init_ex(&key, NULL, devId);
if (ret == 0) {
keyInit = 1;
ret = wc_curve25519_init(&pubKey);
}
if (ret == 0) {
pubKeyInit = 1;
ret = wc_Curve25519PrivateKeyDecode(keyBuf->buffer, &idx, &key,
keyBuf->length);
if (ret != 0) {
SetError(ECC_DECODE_STR, error, session, FATAL_ERROR_STATE);
}
}
if (ret == 0) {
length = CURVE25519_KEYSIZE;
if (length > *sslBytes) {
SetError(PARTIAL_INPUT_STR, error, session, FATAL_ERROR_STATE);
ret = -1;
}
}
if (ret == 0) {
ret = wc_curve25519_import_public_ex(input, length, &pubKey,
EC25519_LITTLE_ENDIAN);
if (ret != 0) {
SetError(ECC_PUB_DECODE_STR, error, session, FATAL_ERROR_STATE);
}
}
if (ret == 0) {
/* For Curve25519 length is always 32 */
session->keySz = CURVE25519_KEYSIZE;
session->sslServer->arrays->preMasterSz = ENCRYPT_LEN;
ret = wc_curve25519_shared_secret_ex(&key, &pubKey,
session->sslServer->arrays->preMasterSecret,
&session->sslServer->arrays->preMasterSz, EC25519_LITTLE_ENDIAN);
}
#ifdef WOLFSSL_SNIFFER_STATS
if (ret != 0)
INC_STAT(SnifferStats.sslKeyFails);
#endif
if (keyInit)
wc_curve25519_free(&key);
if (pubKeyInit)
wc_curve25519_free(&pubKey);
}
#endif /* HAVE_CURVE25519 */
/* store for client side as well */ /* store for client side as well */
XMEMCPY(session->sslClient->arrays->preMasterSecret, XMEMCPY(session->sslClient->arrays->preMasterSecret,
session->sslServer->arrays->preMasterSecret, session->sslServer->arrays->preMasterSecret,
@ -2553,6 +2650,9 @@ static int ProcessClientKeyExchange(const byte* input, int* sslBytes,
#ifdef HAVE_ECC #ifdef HAVE_ECC
keys.ecKey = session->sslServer->staticKE.ecKey; keys.ecKey = session->sslServer->staticKE.ecKey;
#endif #endif
#ifdef HAVE_CURVE25519
keys.x25519Key = session->sslServer->staticKE.x25519Key;
#endif
#endif #endif
keys.rsaKey = session->sslServer->buffers.key; keys.rsaKey = session->sslServer->buffers.key;
return SetupKeys(input, sslBytes, session, error, NULL, &keys); return SetupKeys(input, sslBytes, session, error, NULL, &keys);
@ -2755,19 +2855,21 @@ static int ProcessSessionTicket(const byte* input, int* sslBytes,
#ifdef WOLFSSL_TLS13 #ifdef WOLFSSL_TLS13
/* TLS v1.3 has hint age and nonce */ /* TLS v1.3 has hint age and nonce */
if (IsAtLeastTLSv1_3(ssl->version)) { if (IsAtLeastTLSv1_3(ssl->version)) {
/* Note: Must use server session for sessions */
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (SetTicket(ssl, input, len) != 0) { if (SetTicket(session->sslServer, input, len) != 0) {
SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE); SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
return -1; return -1;
} }
/* set haveSessionId to use the wolfSession cache */ /* set haveSessionId to use the wolfSession cache */
ssl->options.haveSessionId = 1; session->sslServer->options.haveSessionId = 1;
/* Use the wolf Session cache to retain resumption secret */ /* Use the wolf Session cache to retain resumption secret */
if (session->flags.cached == 0) { if (session->flags.cached == 0) {
WOLFSSL_SESSION* sess = GetSession(ssl, NULL, 0); WOLFSSL_SESSION* sess = GetSession(session->sslServer, NULL, 0);
if (sess == NULL) { if (sess == NULL) {
AddSession(ssl); /* don't re add */ AddSession(session->sslServer); /* don't re add */
#ifdef WOLFSSL_SNIFFER_STATS #ifdef WOLFSSL_SNIFFER_STATS
INC_STAT(SnifferStats.sslResumptionInserts); INC_STAT(SnifferStats.sslResumptionInserts);
#endif #endif
@ -2858,8 +2960,10 @@ static int DoResume(SnifferSession* session, char* error)
/* Resumption PSK is resumption master secret. */ /* Resumption PSK is resumption master secret. */
session->sslServer->arrays->psk_keySz = session->sslServer->specs.hash_size; session->sslServer->arrays->psk_keySz = session->sslServer->specs.hash_size;
session->sslClient->arrays->psk_keySz = session->sslClient->specs.hash_size; session->sslClient->arrays->psk_keySz = session->sslClient->specs.hash_size;
ret = DeriveResumptionPSK(session->sslServer, session->sslServer->session.ticketNonce.data, ret = DeriveResumptionPSK(session->sslServer,
session->sslServer->session.ticketNonce.len, session->sslServer->arrays->psk_key); session->sslServer->session.ticketNonce.data,
session->sslServer->session.ticketNonce.len,
session->sslServer->arrays->psk_key);
/* Copy resumption PSK to client */ /* Copy resumption PSK to client */
XMEMCPY(session->sslClient->arrays->psk_key, XMEMCPY(session->sslClient->arrays->psk_key,
session->sslServer->arrays->psk_key, session->sslServer->arrays->psk_key,
@ -3181,6 +3285,9 @@ static int ProcessServerHello(int msgSz, const byte* input, int* sslBytes,
#ifdef HAVE_ECC #ifdef HAVE_ECC
keys.ecKey = session->sslServer->staticKE.ecKey; keys.ecKey = session->sslServer->staticKE.ecKey;
#endif #endif
#ifdef HAVE_CURVE25519
keys.x25519Key = session->sslServer->staticKE.x25519Key;
#endif
#endif #endif
ret = SetupKeys(session->cliKs.key, &session->cliKs.key_len, ret = SetupKeys(session->cliKs.key, &session->cliKs.key_len,
@ -3505,6 +3612,9 @@ static int ProcessClientHello(const byte* input, int* sslBytes,
return -1; return -1;
} }
} }
#ifdef HAVE_SESSION_TICKET
ssl->options.useTicket = 1;
#endif
XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN); XMEMCPY(session->ticketID, input + extLen - ID_LEN, ID_LEN);
} }
break; break;
@ -3700,13 +3810,15 @@ static int ProcessFinished(const byte* input, int size, int* sslBytes,
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
/* derive resumption secret for next session - on finished (from client) */ /* derive resumption secret for next session - on finished (from client) */
ret += DeriveResumptionSecret(session->sslClient, session->sslClient->session.masterSecret); ret += DeriveResumptionSecret(session->sslClient,
session->sslClient->session.masterSecret);
/* copy resumption secret to server */ /* copy resumption secret to server */
XMEMCPY(session->sslServer->session.masterSecret, XMEMCPY(session->sslServer->session.masterSecret,
session->sslClient->session.masterSecret, SECRET_LEN); session->sslClient->session.masterSecret, SECRET_LEN);
#ifdef SHOW_SECRETS #ifdef SHOW_SECRETS
PrintSecret("resumption secret", session->sslClient->session.masterSecret, SECRET_LEN); PrintSecret("resumption secret",
session->sslClient->session.masterSecret, SECRET_LEN);
#endif #endif
#endif #endif
} }

View File

@ -54025,10 +54025,10 @@ static int SetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo,
WOLFSSL_ENTER("SetStaticEphemeralKey"); WOLFSSL_ENTER("SetStaticEphemeralKey");
/* if just free'ing key then skip loading */ /* if just free'ing key then skip loading */
if (key != NULL && keySz > 0) { if (key != NULL) {
#ifndef NO_FILESYSTEM #ifndef NO_FILESYSTEM
/* load file from filesystem */ /* load file from filesystem */
if (key && keySz == 0) { if (key != NULL && keySz == 0) {
size_t keyBufSz = 0; size_t keyBufSz = 0;
keyFile = (const char*)key; keyFile = (const char*)key;
ret = wc_FileLoad(keyFile, &keyBuf, &keyBufSz, heap); ret = wc_FileLoad(keyFile, &keyBuf, &keyBufSz, heap);
@ -54053,6 +54053,8 @@ static int SetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo,
if (ret == 0 && keyAlgo == WC_PK_TYPE_NONE) { if (ret == 0 && keyAlgo == WC_PK_TYPE_NONE) {
if (keyFormat == ECDSAk) if (keyFormat == ECDSAk)
keyAlgo = WC_PK_TYPE_ECDH; keyAlgo = WC_PK_TYPE_ECDH;
else if (keyFormat == X25519k)
keyAlgo = WC_PK_TYPE_CURVE25519;
else else
keyAlgo = WC_PK_TYPE_DH; keyAlgo = WC_PK_TYPE_DH;
} }
@ -54088,6 +54090,20 @@ static int SetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo,
} }
} }
#endif #endif
#ifdef HAVE_CURVE25519
if (keyAlgo == WC_PK_TYPE_NONE) {
word32 idx = 0;
curve25519_key x25519Key;
ret = wc_curve25519_init_ex(&x25519Key, heap, INVALID_DEVID);
if (ret == 0) {
ret = wc_Curve25519PrivateKeyDecode(keyBuf, &idx, &x25519Key,
keySz);
if (ret == 0)
keyAlgo = WC_PK_TYPE_CURVE25519;
wc_curve25519_free(&x25519Key);
}
}
#endif
if (keyAlgo != WC_PK_TYPE_NONE) { if (keyAlgo != WC_PK_TYPE_NONE) {
ret = AllocDer(&der, keySz, PRIVATEKEY_TYPE, heap); ret = AllocDer(&der, keySz, PRIVATEKEY_TYPE, heap);
@ -54107,34 +54123,51 @@ static int SetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo,
/* if key is already allocated then set free it */ /* if key is already allocated then set free it */
#ifndef NO_DH #ifndef NO_DH
if (keyAlgo == WC_PK_TYPE_DH && staticKE->dhKey && staticKE->weOwnDH) if (keyAlgo == WC_PK_TYPE_DH && staticKE->dhKey && staticKE->weOwnDH) {
FreeDer(&staticKE->dhKey); FreeDer(&staticKE->dhKey);
}
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
if (keyAlgo == WC_PK_TYPE_ECDH && staticKE->ecKey && staticKE->weOwnEC) if (keyAlgo == WC_PK_TYPE_ECDH && staticKE->ecKey && staticKE->weOwnEC) {
FreeDer(&staticKE->ecKey); FreeDer(&staticKE->ecKey);
}
#endif
#ifdef HAVE_CURVE25519
if (keyAlgo == WC_PK_TYPE_CURVE25519 && staticKE->x25519Key &&
staticKE->weOwnX25519) {
FreeDer(&staticKE->x25519Key);
}
#endif #endif
switch (keyAlgo) { switch (keyAlgo) {
#ifndef NO_DH #ifndef NO_DH
case WC_PK_TYPE_DH: case WC_PK_TYPE_DH:
staticKE->dhKey = der; staticKE->dhKey = der; der = NULL;
staticKE->weOwnDH = 1; staticKE->weOwnDH = 1;
break; break;
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
case WC_PK_TYPE_ECDH: case WC_PK_TYPE_ECDH:
staticKE->ecKey = der; staticKE->ecKey = der; der = NULL;
staticKE->weOwnEC = 1; staticKE->weOwnEC = 1;
break; break;
#endif
#ifdef HAVE_CURVE25519
case WC_PK_TYPE_CURVE25519:
staticKE->x25519Key = der; der = NULL;
staticKE->weOwnX25519 = 1;
break;
#endif #endif
default: default:
/* not supported */ /* not supported */
ret = NOT_COMPILED_IN; ret = NOT_COMPILED_IN;
FreeDer(&der);
break; break;
} }
if (ret != 0) {
FreeDer(&der);
}
WOLFSSL_LEAVE("SetStaticEphemeralKey", ret); WOLFSSL_LEAVE("SetStaticEphemeralKey", ret);
return ret; return ret;
@ -54184,6 +54217,11 @@ static int GetStaticEphemeralKey(StaticKeyExchangeInfo_t* staticKE, int keyAlgo,
case WC_PK_TYPE_ECDH: case WC_PK_TYPE_ECDH:
der = staticKE->ecKey; der = staticKE->ecKey;
break; break;
#endif
#ifdef HAVE_CURVE25519
case WC_PK_TYPE_CURVE25519:
der = staticKE->x25519Key;
break;
#endif #endif
default: default:
/* not supported */ /* not supported */

View File

@ -4611,7 +4611,7 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
ephmSuite = 1; ephmSuite = 1;
break; break;
#ifdef WOLFSSL_STATIC_DH #if defined(HAVE_ECC) && defined(WOLFSSL_STATIC_DH)
/* ECDH_RSA */ /* ECDH_RSA */
case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
@ -4632,7 +4632,7 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
sig = 1; sig = 1;
key |= ssl->pkCurveOID == pkOid; key |= ssl->pkCurveOID == pkOid;
break; break;
#endif /* WOLFSSL_STATIC_DH */ #endif /* HAVE_ECC && WOLFSSL_STATIC_DH */
#endif #endif
default: default:
if (oid == ECC_X25519_OID && defOid == oid) { if (oid == ECC_X25519_OID && defOid == oid) {
@ -6858,12 +6858,25 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
} }
/* Make an Curve25519 key. */ /* Make an Curve25519 key. */
ret = wc_curve25519_init((curve25519_key*)kse->key); ret = wc_curve25519_init_ex((curve25519_key*)kse->key, ssl->heap,
INVALID_DEVID);
if (ret == 0) { if (ret == 0) {
key = (curve25519_key*)kse->key; key = (curve25519_key*)kse->key;
#ifdef WOLFSSL_STATIC_EPHEMERAL
if (ssl->staticKE.x25519Key) {
DerBuffer* keyDer = ssl->staticKE.x25519Key;
word32 idx = 0;
WOLFSSL_MSG("Using static X25519 key");
ret = wc_Curve25519PrivateKeyDecode(keyDer->buffer, &idx, key,
keyDer->length);
}
else
#endif
{
ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key); ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
} }
} }
}
if (ret == 0 && kse->pubKey == NULL) { if (ret == 0 && kse->pubKey == NULL) {
/* Allocate space for the public key. */ /* Allocate space for the public key. */

View File

@ -6547,7 +6547,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
#ifdef HAVE_ED25519 #ifdef HAVE_ED25519
if (args->sigAlgo == ed25519_sa_algo && if (args->sigAlgo == ed25519_sa_algo &&
!ssl->peerEd25519KeyPresent) { !ssl->peerEd25519KeyPresent) {
WOLFSSL_MSG("Peer sent ED22519 sig but not ED22519 cert"); WOLFSSL_MSG("Peer sent ED25519 sig but not ED25519 cert");
ret = SIG_VERIFY_E; ret = SIG_VERIFY_E;
goto exit_dcv; goto exit_dcv;
} }

View File

@ -97,20 +97,27 @@ enum {
#define STORE_DATA_BLOCK_SZ 1024 #define STORE_DATA_BLOCK_SZ 1024
#endif #endif
#if defined(HAVE_ECC) && !defined(NO_ECC_SECP) && (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES))
#define DEFAULT_SERVER_EPH_KEY_ECC "../../certs/statickeys/ecc-secp256r1.pem" #define DEFAULT_SERVER_EPH_KEY_ECC "../../certs/statickeys/ecc-secp256r1.pem"
#define DEFAULT_SERVER_EPH_KEY_DH "../../certs/statickeys/dh-ffdhe2048.pem"
#ifndef DEFAULT_SERVER_EPH_KEY
#if defined(HAVE_ECC) && !defined(NO_ECC_SECP) && \
(!defined(NO_ECC256) || defined(HAVE_ALL_CURVES))
#if !defined(NO_DH)
#define DEFAULT_SERVER_EPH_KEY DEFAULT_SERVER_EPH_KEY_ECC "," DEFAULT_SERVER_EPH_KEY_DH
#else #else
#define DEFAULT_SERVER_EPH_KEY DEFAULT_SERVER_EPH_KEY_ECC #define DEFAULT_SERVER_EPH_KEY_ECC ""
#endif #endif
#elif !defined(NO_DH) #ifndef NO_DH
#define DEFAULT_SERVER_EPH_KEY DEFAULT_SERVER_EPH_KEY_DH #define DEFAULT_SERVER_EPH_KEY_DH "../../certs/statickeys/dh-ffdhe2048.pem"
#else
#define DEFAULT_SERVER_EPH_KEY_DH ""
#endif #endif
#ifdef HAVE_CURVE25519
#define DEFAULT_SERVER_EPH_KEY_X25519 "../../certs/statickeys/x25519.pem"
#else
#define DEFAULT_SERVER_EPH_KEY_X25519 ""
#endif
#ifndef DEFAULT_SERVER_EPH_KEY
#define DEFAULT_SERVER_EPH_KEY \
DEFAULT_SERVER_EPH_KEY_ECC "," \
DEFAULT_SERVER_EPH_KEY_DH "," \
DEFAULT_SERVER_EPH_KEY_X25519
#endif #endif
#define DEFAULT_SERVER_KEY_RSA "../../certs/server-key.pem" #define DEFAULT_SERVER_KEY_RSA "../../certs/server-key.pem"

View File

@ -20233,7 +20233,7 @@ static int test_wc_curve25519_shared_secret_ex(void)
static int test_wc_curve25519_make_pub(void) static int test_wc_curve25519_make_pub(void)
{ {
int ret = 0; int ret = 0;
#if defined(HAVE_CURVE25519) #ifdef HAVE_CURVE25519
WC_RNG rng; WC_RNG rng;
curve25519_key key; curve25519_key key;
byte out[CURVE25519_KEYSIZE]; byte out[CURVE25519_KEYSIZE];
@ -20248,45 +20248,45 @@ static int test_wc_curve25519_make_pub (void)
} }
} }
if (ret == 0) { if (ret == 0) {
ret = wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof key.k.point, key.k.point); ret = wc_curve25519_make_pub((int)sizeof(out), out, (int)sizeof(key.k), key.k);
} }
/*test bad cases*/ /*test bad cases*/
if (ret == 0) { if (ret == 0) {
ret = wc_curve25519_make_pub((int)sizeof key.k.point - 1, key.k.point, (int)sizeof out, out); ret = wc_curve25519_make_pub((int)sizeof(key.k) - 1, key.k, (int)sizeof out, out);
if (ret == ECC_BAD_ARG_E) { if (ret == ECC_BAD_ARG_E) {
ret = 0; ret = 0;
} }
} }
if (ret == 0) { if (ret == 0) {
ret = wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof key.k.point, NULL); ret = wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof(key.k), NULL);
if (ret == ECC_BAD_ARG_E) { if (ret == ECC_BAD_ARG_E) {
ret = 0; ret = 0;
} }
} }
if (ret == 0) { if (ret == 0) {
ret = wc_curve25519_make_pub((int)sizeof out - 1, out, (int)sizeof key.k.point, key.k.point); ret = wc_curve25519_make_pub((int)sizeof out - 1, out, (int)sizeof(key.k), key.k);
if (ret == ECC_BAD_ARG_E) { if (ret == ECC_BAD_ARG_E) {
ret = 0; ret = 0;
} }
} }
if (ret == 0) { if (ret == 0) {
ret = wc_curve25519_make_pub((int)sizeof out, NULL, (int)sizeof key.k.point, key.k.point); ret = wc_curve25519_make_pub((int)sizeof out, NULL, (int)sizeof(key.k), key.k);
if (ret == ECC_BAD_ARG_E) { if (ret == ECC_BAD_ARG_E) {
ret = 0; ret = 0;
} }
} }
if (ret == 0) { if (ret == 0) {
/* verify clamping test */ /* verify clamping test */
key.k.point[0] |= ~248; key.k[0] |= ~248;
ret = wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof key.k.point, key.k.point); ret = wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof(key.k), key.k);
if (ret == ECC_BAD_ARG_E) { if (ret == ECC_BAD_ARG_E) {
ret = 0; ret = 0;
} }
key.k.point[0] &= 248; key.k[0] &= 248;
} }
/* repeat the expected-to-succeed test. */ /* repeat the expected-to-succeed test. */
if (ret == 0) { if (ret == 0) {
ret = wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof key.k.point, key.k.point); ret = wc_curve25519_make_pub((int)sizeof out, out, (int)sizeof(key.k), key.k);
} }
printf(resultFmt, ret == 0 ? passed : failed); printf(resultFmt, ret == 0 ? passed : failed);

File diff suppressed because it is too large Load Diff

View File

@ -57,6 +57,41 @@ const curve25519_set_type curve25519_sets[] = {
static const unsigned char kCurve25519BasePoint[CURVE25519_KEYSIZE] = {9}; static const unsigned char kCurve25519BasePoint[CURVE25519_KEYSIZE] = {9};
/* Curve25519 private key must be less than order */
/* These functions clamp private k and check it */
static WC_INLINE int curve25519_priv_clamp(byte* priv)
{
priv[0] &= 248;
priv[CURVE25519_KEYSIZE-1] &= 127;
priv[CURVE25519_KEYSIZE-1] |= 64;
return 0;
}
static WC_INLINE int curve25519_priv_clamp_check(const byte* priv)
{
/* check that private part of key has been clamped */
int ret = 0;
if ((priv[0] & ~248) ||
(priv[CURVE25519_KEYSIZE-1] & 128)) {
ret = ECC_BAD_ARG_E;
}
return ret;
}
static WC_INLINE void curve25519_copy_point(byte* out, const byte* point,
int endian)
{
int i;
if (endian == EC25519_BIG_ENDIAN) {
/* put shared secret key in Big Endian format */
for (i = 0; i < CURVE25519_KEYSIZE; i++) {
out[i] = point[CURVE25519_KEYSIZE - i -1];
}
}
else { /* put shared secret key in Little Endian format */
XMEMCPY(out, point, CURVE25519_KEYSIZE);
}
}
/* compute the public key from an existing private key, using bare vectors. /* compute the public key from an existing private key, using bare vectors.
* *
* return value is propagated from curve25519() (0 on success), or * return value is propagated from curve25519() (0 on success), or
@ -66,27 +101,28 @@ int wc_curve25519_make_pub(int public_size, byte* pub, int private_size,
const byte* priv) const byte* priv)
{ {
int ret; int ret;
#ifdef FREESCALE_LTC_ECC
const ECPoint* basepoint = nxp_ltc_curve25519_GetBasePoint();
ECPoint wc_pub;
#endif
if ( (public_size != CURVE25519_KEYSIZE) || if ( (public_size != CURVE25519_KEYSIZE) ||
(private_size != CURVE25519_KEYSIZE)) { (private_size != CURVE25519_KEYSIZE)) {
return ECC_BAD_ARG_E; return ECC_BAD_ARG_E;
} }
if ((pub == NULL) || (priv == NULL)) if ((pub == NULL) || (priv == NULL)) {
return ECC_BAD_ARG_E;
/* check clamping */
if ((priv[0] & ~248) ||
(priv[CURVE25519_KEYSIZE-1] & 128)) {
return ECC_BAD_ARG_E; return ECC_BAD_ARG_E;
} }
/* check clamping */
ret = curve25519_priv_clamp_check(priv);
if (ret != 0)
return ret;
#ifdef FREESCALE_LTC_ECC #ifdef FREESCALE_LTC_ECC
{
const ECPoint* basepoint = nxp_ltc_curve25519_GetBasePoint();
ECPoint wc_pub;
/* input basepoint on Weierstrass curve */ /* input basepoint on Weierstrass curve */
ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass); ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass);
if (ret == 0) if (ret == 0) {
XMEMCPY(pub, wc_pub.point, CURVE25519_KEYSIZE); XMEMCPY(pub, wc_pub.point, CURVE25519_KEYSIZE);
} }
#else #else
@ -117,7 +153,7 @@ int wc_curve25519_generic(int public_size, byte* pub,
int basepoint_size, const byte* basepoint) int basepoint_size, const byte* basepoint)
{ {
#ifdef FREESCALE_LTC_ECC #ifdef FREESCALE_LTC_ECC
/* unsupported with NXP LTC, onlly supports single basepoint with /* unsupported with NXP LTC, only supports single basepoint with
* nxp_ltc_curve25519_GetBasePoint() */ * nxp_ltc_curve25519_GetBasePoint() */
return WC_HW_E; return WC_HW_E;
#else #else
@ -132,10 +168,9 @@ int wc_curve25519_generic(int public_size, byte* pub,
return ECC_BAD_ARG_E; return ECC_BAD_ARG_E;
/* check clamping */ /* check clamping */
if ((priv[0] & ~248) || ret = curve25519_priv_clamp_check(priv);
(priv[CURVE25519_KEYSIZE-1] & 128)) { if (ret != 0)
return ECC_BAD_ARG_E; return ret;
}
fe_init(); fe_init();
@ -171,15 +206,12 @@ int wc_curve25519_make_priv(WC_RNG* rng, int keysize, byte* key)
/* random number for private key */ /* random number for private key */
ret = wc_RNG_GenerateBlock(rng, key, keysize); ret = wc_RNG_GenerateBlock(rng, key, keysize);
if (ret != 0) if (ret == 0) {
return ret;
/* Clamp the private key */ /* Clamp the private key */
key[0] &= 248; ret = curve25519_priv_clamp(key);
key[CURVE25519_KEYSIZE-1] &= 63; /* same &=127 because |=64 after */ }
key[CURVE25519_KEYSIZE-1] |= 64;
return 0; return ret;
} }
/* generate a new keypair. /* generate a new keypair.
@ -203,11 +235,14 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
} }
#endif #endif
ret = wc_curve25519_make_priv(rng, keysize, key->k.point); ret = wc_curve25519_make_priv(rng, keysize, key->k);
if (ret < 0) if (ret == 0) {
key->privSet = 1;
ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point,
(int)sizeof(key->k), key->k);
key->pubSet = (ret == 0);
}
return ret; return ret;
return wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point,
(int)sizeof(key->k.point), key->k.point);
} }
#ifdef HAVE_CURVE25519_SHARED_SECRET #ifdef HAVE_CURVE25519_SHARED_SECRET
@ -224,11 +259,7 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
curve25519_key* public_key, curve25519_key* public_key,
byte* out, word32* outlen, int endian) byte* out, word32* outlen, int endian)
{ {
#ifdef FREESCALE_LTC_ECC ECPoint o;
ECPoint o = {{0}};
#else
unsigned char o[CURVE25519_KEYSIZE];
#endif
int ret = 0; int ret = 0;
/* sanity check */ /* sanity check */
@ -237,10 +268,17 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
/* avoid implementation fingerprinting */ /* make sure we have a populated private and public key */
if (public_key->p.point[CURVE25519_KEYSIZE-1] > 0x7F) if (!private_key->privSet || !public_key->pubSet) {
return ECC_BAD_ARG_E; return ECC_BAD_ARG_E;
}
/* avoid implementation fingerprinting - make sure signed bit is not set */
if (public_key->p.point[CURVE25519_KEYSIZE-1] & 0x80) {
return ECC_BAD_ARG_E;
}
XMEMSET(&o, 0, sizeof(o));
#ifdef WOLF_CRYPTO_CB #ifdef WOLF_CRYPTO_CB
if (private_key->devId != INVALID_DEVID) { if (private_key->devId != INVALID_DEVID) {
@ -254,54 +292,28 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
#ifdef FREESCALE_LTC_ECC #ifdef FREESCALE_LTC_ECC
/* input point P on Curve25519 */ /* input point P on Curve25519 */
ret = nxp_ltc_curve25519(&o, private_key->k.point, &public_key->p, ret = nxp_ltc_curve25519(&o, private_key->k, &public_key->p,
kLTC_Curve25519); kLTC_Curve25519);
#else #else
#if defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM) #if defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM)
SAVE_VECTOR_REGISTERS(); SAVE_VECTOR_REGISTERS();
#endif #endif
ret = curve25519(o, private_key->k.point, public_key->p.point); ret = curve25519(o.point, private_key->k, public_key->p.point);
#if defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM) #if defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM)
RESTORE_VECTOR_REGISTERS(); RESTORE_VECTOR_REGISTERS();
#endif #endif
#endif #endif
if (ret != 0) { if (ret != 0) {
#ifdef FREESCALE_LTC_ECC ForceZero(&o, sizeof(o));
ForceZero(o.point, CURVE25519_KEYSIZE);
ForceZero(o.pointY, CURVE25519_KEYSIZE);
#else
ForceZero(o, CURVE25519_KEYSIZE);
#endif
return ret; return ret;
} }
if (endian == EC25519_BIG_ENDIAN) { curve25519_copy_point(out, o.point, endian);
int i;
/* put shared secret key in Big Endian format */
for (i = 0; i < CURVE25519_KEYSIZE; i++)
#ifdef FREESCALE_LTC_ECC
out[i] = o.point[CURVE25519_KEYSIZE - i -1];
#else
out[i] = o[CURVE25519_KEYSIZE - i -1];
#endif
}
else /* put shared secret key in Little Endian format */
#ifdef FREESCALE_LTC_ECC
XMEMCPY(out, o.point, CURVE25519_KEYSIZE);
#else
XMEMCPY(out, o, CURVE25519_KEYSIZE);
#endif
*outlen = CURVE25519_KEYSIZE; *outlen = CURVE25519_KEYSIZE;
#ifdef FREESCALE_LTC_ECC ForceZero(&o, sizeof(o));
ForceZero(o.point, CURVE25519_KEYSIZE);
ForceZero(o.pointY, CURVE25519_KEYSIZE);
#else
ForceZero(o, CURVE25519_KEYSIZE);
#endif
return ret; return ret;
} }
@ -322,27 +334,29 @@ int wc_curve25519_export_public(curve25519_key* key, byte* out, word32* outLen)
int wc_curve25519_export_public_ex(curve25519_key* key, byte* out, int wc_curve25519_export_public_ex(curve25519_key* key, byte* out,
word32* outLen, int endian) word32* outLen, int endian)
{ {
if (key == NULL || out == NULL || outLen == NULL) int ret = 0;
if (key == NULL || out == NULL || outLen == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
}
/* check and set outgoing key size */ /* check and set outgoing key size */
if (*outLen < CURVE25519_KEYSIZE) { if (*outLen < CURVE25519_KEYSIZE) {
*outLen = CURVE25519_KEYSIZE; *outLen = CURVE25519_KEYSIZE;
return ECC_BAD_ARG_E; return ECC_BAD_ARG_E;
} }
/* calculate public if missing */
if (!key->pubSet) {
ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point,
(int)sizeof(key->k), key->k);
key->pubSet = (ret == 0);
}
/* export public point with endianess */
curve25519_copy_point(out, key->p.point, endian);
*outLen = CURVE25519_KEYSIZE; *outLen = CURVE25519_KEYSIZE;
if (endian == EC25519_BIG_ENDIAN) { return ret;
int i;
/* read keys in Big Endian format */
for (i = 0; i < CURVE25519_KEYSIZE; i++)
out[i] = key->p.point[CURVE25519_KEYSIZE - i - 1];
}
else
XMEMCPY(out, key->p.point, CURVE25519_KEYSIZE);
return 0;
} }
#endif /* HAVE_CURVE25519_KEY_EXPORT */ #endif /* HAVE_CURVE25519_KEY_EXPORT */
@ -362,29 +376,28 @@ int wc_curve25519_import_public(const byte* in, word32 inLen,
int wc_curve25519_import_public_ex(const byte* in, word32 inLen, int wc_curve25519_import_public_ex(const byte* in, word32 inLen,
curve25519_key* key, int endian) curve25519_key* key, int endian)
{ {
#ifdef FREESCALE_LTC_ECC
ltc_pkha_ecc_point_t ltcPoint;
#endif
/* sanity check */ /* sanity check */
if (key == NULL || in == NULL) if (key == NULL || in == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
}
/* check size of incoming keys */ /* check size of incoming keys */
if (inLen != CURVE25519_KEYSIZE) if (inLen != CURVE25519_KEYSIZE) {
return ECC_BAD_ARG_E; return ECC_BAD_ARG_E;
if (endian == EC25519_BIG_ENDIAN) {
int i;
/* read keys in Big Endian format */
for (i = 0; i < CURVE25519_KEYSIZE; i++)
key->p.point[i] = in[CURVE25519_KEYSIZE - i - 1];
} }
else
XMEMCPY(key->p.point, in, inLen); /* import public point with endianess */
curve25519_copy_point(key->p.point, in, endian);
key->pubSet = 1;
key->dp = &curve25519_sets[0]; key->dp = &curve25519_sets[0];
/* LTC needs also Y coordinate - let's compute it */ /* LTC needs also Y coordinate - let's compute it */
#ifdef FREESCALE_LTC_ECC #ifdef FREESCALE_LTC_ECC
ltc_pkha_ecc_point_t ltcPoint;
ltcPoint.X = &key->p.point[0]; ltcPoint.X = &key->p.point[0];
ltcPoint.Y = &key->p.pointY[0]; ltcPoint.Y = &key->p.pointY[0];
LTC_PKHA_Curve25519ComputeY(&ltcPoint); LTC_PKHA_Curve25519ComputeY(&ltcPoint);
@ -481,18 +494,11 @@ int wc_curve25519_export_private_raw_ex(curve25519_key* key, byte* out,
*outLen = CURVE25519_KEYSIZE; *outLen = CURVE25519_KEYSIZE;
return ECC_BAD_ARG_E; return ECC_BAD_ARG_E;
} }
/* export private scalar with endianess */
curve25519_copy_point(out, key->k, endian);
*outLen = CURVE25519_KEYSIZE; *outLen = CURVE25519_KEYSIZE;
if (endian == EC25519_BIG_ENDIAN) {
int i;
/* put the key in Big Endian format */
for (i = 0; i < CURVE25519_KEYSIZE; i++)
out[i] = key->k.point[CURVE25519_KEYSIZE - i - 1];
}
else
XMEMCPY(out, key->k.point, CURVE25519_KEYSIZE);
return 0; return 0;
} }
@ -572,31 +578,23 @@ int wc_curve25519_import_private_ex(const byte* priv, word32 privSz,
curve25519_key* key, int endian) curve25519_key* key, int endian)
{ {
/* sanity check */ /* sanity check */
if (key == NULL || priv == NULL) if (key == NULL || priv == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
}
/* check size of incoming keys */ /* check size of incoming keys */
if ((int)privSz != CURVE25519_KEYSIZE) if ((int)privSz != CURVE25519_KEYSIZE) {
return ECC_BAD_ARG_E; return ECC_BAD_ARG_E;
if (endian == EC25519_BIG_ENDIAN) {
int i;
/* read the key in Big Endian format */
for (i = 0; i < CURVE25519_KEYSIZE; i++)
key->k.point[i] = priv[CURVE25519_KEYSIZE - i - 1];
} }
else
XMEMCPY(key->k.point, priv, CURVE25519_KEYSIZE); /* import private scalar with endianess */
curve25519_copy_point(key->k, priv, endian);
key->privSet = 1;
key->dp = &curve25519_sets[0]; key->dp = &curve25519_sets[0];
/* Clamp the key */ /* Clamp the key */
key->k.point[0] &= 248; return curve25519_priv_clamp(key->k);
key->k.point[privSz-1] &= 63; /* same &=127 because |=64 after */
key->k.point[privSz-1] |= 64;
return 0;
} }
#endif /* HAVE_CURVE25519_KEY_IMPORT */ #endif /* HAVE_CURVE25519_KEY_IMPORT */
@ -637,15 +635,12 @@ void wc_curve25519_free(curve25519_key* key)
return; return;
key->dp = NULL; key->dp = NULL;
ForceZero(key->p.point, sizeof(key->p.point)); ForceZero(key->k, sizeof(key->k));
ForceZero(key->k.point, sizeof(key->k.point)); XMEMSET(&key->p, 0, sizeof(key->p));
#ifdef FREESCALE_LTC_ECC key->pubSet = 0;
ForceZero(key->p.point, sizeof(key->p.pointY)); key->privSet = 0;
ForceZero(key->k.point, sizeof(key->k.pointY));
#endif
} }
/* get key size */ /* get key size */
int wc_curve25519_size(curve25519_key* key) int wc_curve25519_size(curve25519_key* key)
{ {
@ -656,4 +651,3 @@ int wc_curve25519_size(curve25519_key* key)
} }
#endif /*HAVE_CURVE25519*/ #endif /*HAVE_CURVE25519*/

View File

@ -42,6 +42,28 @@
#include <wolfcrypt/src/misc.c> #include <wolfcrypt/src/misc.c>
#endif #endif
int wc_curve448_make_pub(int public_size, byte* pub, int private_size,
const byte* priv)
{
int ret;
unsigned char basepoint[CURVE448_KEY_SIZE] = {5};
if ((pub == NULL) || (priv == NULL)) {
return ECC_BAD_ARG_E;
}
if ((public_size != CURVE448_PUB_KEY_SIZE) ||
(private_size != CURVE448_KEY_SIZE)) {
return ECC_BAD_ARG_E;
}
fe448_init();
/* compute public key */
ret = curve448(pub, priv, basepoint);
return ret;
}
/* Make a new curve448 private/public key. /* Make a new curve448 private/public key.
* *
@ -54,7 +76,6 @@
*/ */
int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key) int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key)
{ {
unsigned char basepoint[CURVE448_KEY_SIZE] = {5};
int ret = 0; int ret = 0;
if ((key == NULL) || (rng == NULL)) { if ((key == NULL) || (rng == NULL)) {
@ -67,21 +88,25 @@ int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key)
} }
if (ret == 0) { if (ret == 0) {
fe448_init();
/* random number for private key */ /* random number for private key */
ret = wc_RNG_GenerateBlock(rng, key->k, keysize); ret = wc_RNG_GenerateBlock(rng, key->k, keysize);
} }
if (ret == 0) { if (ret == 0) {
/* Clamp the private key */ key->privSet = 1;
/* clamp private */
key->k[0] &= 0xfc; key->k[0] &= 0xfc;
key->k[CURVE448_KEY_SIZE-1] |= 0x80; key->k[CURVE448_KEY_SIZE-1] |= 0x80;
/* compute public key */ /* compute public */
ret = curve448(key->p, key->k, basepoint); ret = wc_curve448_make_pub((int)sizeof(key->p), key->p,
if (ret != 0) { (int)sizeof(key->k), key->k);
ForceZero(key->k, keysize); if (ret == 0) {
ForceZero(key->p, keysize); key->pubSet = 1;
}
else {
ForceZero(key->k, sizeof(key->k));
XMEMSET(key->p, 0, sizeof(key->p));
} }
} }
@ -137,6 +162,10 @@ int wc_curve448_shared_secret_ex(curve448_key* private_key,
(outLen == NULL) || (*outLen < CURVE448_PUB_KEY_SIZE)) { (outLen == NULL) || (*outLen < CURVE448_PUB_KEY_SIZE)) {
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
} }
/* make sure we have a populated private and public key */
if (ret == 0 && (!private_key->privSet || !public_key->pubSet)) {
ret = ECC_BAD_ARG_E;
}
if (ret == 0) { if (ret == 0) {
ret = curve448(o, private_key->k, public_key->p); ret = curve448(o, private_key->k, public_key->p);
@ -207,9 +236,16 @@ int wc_curve448_export_public_ex(curve448_key* key, byte* out, word32* outLen,
*outLen = CURVE448_PUB_KEY_SIZE; *outLen = CURVE448_PUB_KEY_SIZE;
ret = ECC_BAD_ARG_E; ret = ECC_BAD_ARG_E;
} }
if (ret == 0) {
/* calculate public if missing */
if (!key->pubSet) {
ret = wc_curve448_make_pub((int)sizeof(key->p), key->p,
(int)sizeof(key->k), key->k);
key->pubSet = (ret == 0);
}
}
if (ret == 0) { if (ret == 0) {
*outLen = CURVE448_PUB_KEY_SIZE; *outLen = CURVE448_PUB_KEY_SIZE;
if (endian == EC448_BIG_ENDIAN) { if (endian == EC448_BIG_ENDIAN) {
/* read keys in Big Endian format */ /* read keys in Big Endian format */
for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) { for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) {
@ -278,6 +314,7 @@ int wc_curve448_import_public_ex(const byte* in, word32 inLen,
} }
else else
XMEMCPY(key->p, in, inLen); XMEMCPY(key->p, in, inLen);
key->pubSet = 1;
} }
return ret; return ret;
@ -569,6 +606,8 @@ int wc_curve448_import_private_ex(const byte* priv, word32 privSz,
/* Clamp the key */ /* Clamp the key */
key->k[0] &= 0xfc; key->k[0] &= 0xfc;
key->k[CURVE448_KEY_SIZE-1] |= 0x80; key->k[CURVE448_KEY_SIZE-1] |= 0x80;
key->privSet = 1;
} }
return ret; return ret;
@ -608,8 +647,10 @@ int wc_curve448_init(curve448_key* key)
void wc_curve448_free(curve448_key* key) void wc_curve448_free(curve448_key* key)
{ {
if (key != NULL) { if (key != NULL) {
ForceZero(key->p, sizeof(key->p));
ForceZero(key->k, sizeof(key->k)); ForceZero(key->k, sizeof(key->k));
XMEMSET(key->p, 0, sizeof(key->p));
key->pubSet = 0;
key->privSet = 0;
} }
} }

View File

@ -16278,7 +16278,11 @@ exit_gen_test:
static int dh_generate_test(WC_RNG *rng) static int dh_generate_test(WC_RNG *rng)
{ {
int ret = 0; int ret = 0;
DhKey smallKey; #ifdef WOLFSSL_SMALL_STACK
DhKey *smallKey = (DhKey*)XMALLOC(sizeof(DhKey), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
#else
DhKey smallKey[1];
#endif
byte p[2] = { 0, 5 }; byte p[2] = { 0, 5 };
byte g[2] = { 0, 2 }; byte g[2] = { 0, 2 };
#if !defined(WOLFSSL_SP_MATH) #if !defined(WOLFSSL_SP_MATH)
@ -16294,7 +16298,13 @@ static int dh_generate_test(WC_RNG *rng)
word32 pubSz = sizeof(pub); word32 pubSz = sizeof(pub);
#endif #endif
ret = wc_InitDhKey_ex(&smallKey, HEAP_HINT, devId); #ifdef WOLFSSL_SMALL_STACK
if (smallKey == NULL) {
ERROR_OUT(-8010, exit_gen_test);
}
#endif
ret = wc_InitDhKey_ex(smallKey, HEAP_HINT, devId);
if (ret != 0) if (ret != 0)
return -8010; return -8010;
@ -16308,32 +16318,32 @@ static int dh_generate_test(WC_RNG *rng)
if (ret != BAD_FUNC_ARG) { if (ret != BAD_FUNC_ARG) {
ERROR_OUT(-8012, exit_gen_test); ERROR_OUT(-8012, exit_gen_test);
} }
ret = wc_DhSetKey(&smallKey, NULL, sizeof(p), g, sizeof(g)); ret = wc_DhSetKey(smallKey, NULL, sizeof(p), g, sizeof(g));
if (ret != BAD_FUNC_ARG) { if (ret != BAD_FUNC_ARG) {
ERROR_OUT(-8013, exit_gen_test); ERROR_OUT(-8013, exit_gen_test);
} }
ret = wc_DhSetKey(&smallKey, p, 0, g, sizeof(g)); ret = wc_DhSetKey(smallKey, p, 0, g, sizeof(g));
if (ret != BAD_FUNC_ARG) { if (ret != BAD_FUNC_ARG) {
ERROR_OUT(-8014, exit_gen_test); ERROR_OUT(-8014, exit_gen_test);
} }
ret = wc_DhSetKey(&smallKey, p, sizeof(p), NULL, sizeof(g)); ret = wc_DhSetKey(smallKey, p, sizeof(p), NULL, sizeof(g));
if (ret != BAD_FUNC_ARG) { if (ret != BAD_FUNC_ARG) {
ERROR_OUT(-8015, exit_gen_test); ERROR_OUT(-8015, exit_gen_test);
} }
ret = wc_DhSetKey(&smallKey, p, sizeof(p), g, 0); ret = wc_DhSetKey(smallKey, p, sizeof(p), g, 0);
if (ret != BAD_FUNC_ARG) { if (ret != BAD_FUNC_ARG) {
ERROR_OUT(-8016, exit_gen_test); ERROR_OUT(-8016, exit_gen_test);
} }
ret = wc_DhSetKey(&smallKey, p, sizeof(p), g, sizeof(g)); ret = wc_DhSetKey(smallKey, p, sizeof(p), g, sizeof(g));
if (ret != 0) { if (ret != 0) {
ERROR_OUT(-8017, exit_gen_test); ERROR_OUT(-8017, exit_gen_test);
} }
#if !defined(WOLFSSL_SP_MATH) #if !defined(WOLFSSL_SP_MATH)
/* Use API. */ /* Use API. */
ret = wc_DhGenerateKeyPair(&smallKey, rng, priv, &privSz, pub, &pubSz); ret = wc_DhGenerateKeyPair(smallKey, rng, priv, &privSz, pub, &pubSz);
#if defined(WOLFSSL_ASYNC_CRYPT) #if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &smallKey.asyncDev, WC_ASYNC_FLAG_NONE); ret = wc_AsyncWait(ret, &smallKey->asyncDev, WC_ASYNC_FLAG_NONE);
#endif #endif
if (ret != 0) { if (ret != 0) {
ret = -8018; ret = -8018;
@ -16344,7 +16354,12 @@ static int dh_generate_test(WC_RNG *rng)
#endif #endif
exit_gen_test: exit_gen_test:
wc_FreeDhKey(&smallKey); wc_FreeDhKey(smallKey);
#ifdef WOLFSSL_SMALL_STACK
if (smallKey != NULL) {
XFREE(smallKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
return ret; return ret;
} }
@ -24900,6 +24915,83 @@ static int curve25519_check_public_test(void)
#endif /* HAVE_CURVE25519_SHARED_SECRET && HAVE_CURVE25519_KEY_IMPORT */ #endif /* HAVE_CURVE25519_SHARED_SECRET && HAVE_CURVE25519_KEY_IMPORT */
#if defined(HAVE_CURVE25519_KEY_EXPORT) && defined(HAVE_CURVE25519_KEY_IMPORT)
static int curve255519_der_test(void)
{
int ret = 0;
/* certs/statickeys/x25519.der */
const byte kCurve25519PrivDer[] = {
0x30, 0x2E, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x6E,
0x04, 0x22, 0x04, 0x20, 0x78, 0x8E, 0x31, 0x5C, 0x33, 0xA9, 0x19, 0xC0,
0x5E, 0x36, 0x70, 0x1B, 0xA4, 0xE8, 0xEF, 0xC1, 0x89, 0x8C, 0xB3, 0x15,
0xC6, 0x79, 0xD3, 0xAC, 0x22, 0x00, 0xAE, 0xFA, 0xB3, 0xB7, 0x0F, 0x78
};
/* certs/statickeys/x25519-pub.der */
const byte kCurve25519PubDer[] = {
0x30, 0x2A, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x6E, 0x03, 0x21, 0x00,
0x09, 0xBC, 0x8C, 0xC7, 0x45, 0x0D, 0xC1, 0xC2, 0x02, 0x57, 0x9A, 0x68,
0x3A, 0xFD, 0x7A, 0xA8, 0xA5, 0x2F, 0xF0, 0x99, 0x39, 0x98, 0xEA, 0x26,
0xA2, 0x5B, 0x38, 0xFD, 0x96, 0xDB, 0x2A, 0x26
};
curve25519_key key;
byte output[128];
word32 outputSz = 128;
word32 idx;
if (wc_curve25519_init_ex(&key, HEAP_HINT, devId) != 0) {
return -10723;
}
/* Test decode / encode of Curve25519 private key only */
if (ret == 0) {
idx = 0;
ret = wc_Curve25519PrivateKeyDecode(kCurve25519PrivDer, &idx, &key,
(word32)sizeof(kCurve25519PrivDer));
}
if (ret == 0) {
outputSz = (word32)sizeof(output);
ret = wc_Curve25519PrivateKeyToDer(&key, output, outputSz);
if (ret >= 0) {
outputSz = ret;
ret = 0;
}
else {
ret = -10724;
}
}
if (ret == 0 && (outputSz != (word32)sizeof(kCurve25519PrivDer) ||
XMEMCMP(output, kCurve25519PrivDer, outputSz) != 0)) {
ret = -10725;
}
/* Test decode / encode of Curve25519 public key only */
if (ret == 0) {
idx = 0;
ret = wc_Curve25519PublicKeyDecode(kCurve25519PubDer, &idx, &key,
(word32)sizeof(kCurve25519PubDer));
}
if (ret == 0) {
outputSz = (word32)sizeof(output);
ret = wc_Curve25519PublicKeyToDer(&key, output, outputSz, 1);
if (ret >= 0) {
outputSz = ret;
ret = 0;
}
else {
ret = -10726;
}
}
if (ret == 0 && (outputSz != (word32)sizeof(kCurve25519PubDer) ||
XMEMCMP(output, kCurve25519PubDer, outputSz) != 0)) {
ret = -10727;
}
wc_curve25519_free(&key);
return ret;
}
#endif /* HAVE_CURVE25519_KEY_EXPORT && HAVE_CURVE25519_KEY_IMPORT */
WOLFSSL_TEST_SUBROUTINE int curve25519_test(void) WOLFSSL_TEST_SUBROUTINE int curve25519_test(void)
{ {
WC_RNG rng; WC_RNG rng;
@ -25082,6 +25174,12 @@ WOLFSSL_TEST_SUBROUTINE int curve25519_test(void)
return ret; return ret;
#endif /* HAVE_CURVE25519_SHARED_SECRET && HAVE_CURVE25519_KEY_IMPORT */ #endif /* HAVE_CURVE25519_SHARED_SECRET && HAVE_CURVE25519_KEY_IMPORT */
#if defined(HAVE_CURVE25519_KEY_IMPORT) && defined(HAVE_CURVE25519_KEY_IMPORT)
ret = curve255519_der_test();
if (ret != 0)
return ret;
#endif
/* clean up keys when done */ /* clean up keys when done */
wc_curve25519_free(&pubKey); wc_curve25519_free(&pubKey);
wc_curve25519_free(&userB); wc_curve25519_free(&userB);

View File

@ -2763,6 +2763,10 @@ typedef struct {
#ifdef HAVE_ECC #ifdef HAVE_ECC
DerBuffer* ecKey; DerBuffer* ecKey;
#endif #endif
#ifdef HAVE_CURVE25519
DerBuffer* x25519Key;
#endif
/* bits */ /* bits */
#ifndef NO_DH #ifndef NO_DH
byte weOwnDH:1; byte weOwnDH:1;
@ -2770,6 +2774,9 @@ typedef struct {
#ifdef HAVE_ECC #ifdef HAVE_ECC
byte weOwnEC:1; byte weOwnEC:1;
#endif #endif
#ifdef HAVE_CURVE25519
byte weOwnX25519:1;
#endif
} StaticKeyExchangeInfo_t; } StaticKeyExchangeInfo_t;
#endif #endif

View File

@ -160,7 +160,7 @@ enum ASNItem_DataType {
/* A template entry describing an ASN.1 item. */ /* A template entry describing an ASN.1 item. */
typedef struct ASNItem { typedef struct ASNItem {
/* Depth of ASN.1 item - how many consturcted ASN.1 items above. */ /* Depth of ASN.1 item - how many constructed ASN.1 items above. */
byte depth; byte depth;
/* BER/DER tag to expect. */ /* BER/DER tag to expect. */
byte tag; byte tag;
@ -232,7 +232,7 @@ typedef struct ASNGetData {
struct { struct {
/* Buffer to hold ASN.1 data. */ /* Buffer to hold ASN.1 data. */
byte* data; byte* data;
/* Maxumum length of buffer. */ /* Maximum length of buffer. */
word32* length; word32* length;
} buffer; } buffer;
/* Refernce to ASN.1 item's data. */ /* Refernce to ASN.1 item's data. */
@ -366,7 +366,7 @@ WOLFSSL_LOCAL void SetASN_OID(ASNSetData *dataASN, int oid, int oidType);
(dataASN)->data.mp = num; \ (dataASN)->data.mp = num; \
} while (0) } while (0)
/* Setup ASN data item to get a positve or negative number into an mp_int. /* Setup ASN data item to get a positive or negative number into an mp_int.
* *
* @param [in] dataASN Dynamic ASN data item. * @param [in] dataASN Dynamic ASN data item.
* @param [in] num Multi-precision number object. * @param [in] num Multi-precision number object.
@ -572,7 +572,7 @@ WOLFSSL_LOCAL void SetASN_OID(ASNSetData *dataASN, int oid, int oidType);
#define GetASNItem_UnusedBits(dataASN) \ #define GetASNItem_UnusedBits(dataASN) \
(*(dataASN.data.ref.data - 1)) (*(dataASN.data.ref.data - 1))
/* Set the data items at indeces start to end inclusive to not be encoded. /* Set the data items at indices start to end inclusive to not be encoded.
* *
* @param [in] dataASN Dynamic ASN data item. * @param [in] dataASN Dynamic ASN data item.
* @param [in] start First item not to be encoded. * @param [in] start First item not to be encoded.
@ -962,8 +962,10 @@ enum Key_Sum {
RSAk = 645, RSAk = 645,
NTRUk = 274, NTRUk = 274,
ECDSAk = 518, ECDSAk = 518,
ED25519k = 256, ED25519k = 256, /* 1.3.101.112 */
ED448k = 257, X25519k = 254, /* 1.3.101.110 */
ED448k = 257, /* 1.3.101.113 */
X448k = 255, /* 1.3.101.111 */
DHk = 647, /* dhKeyAgreement OID: 1.2.840.113549.1.3.1 */ DHk = 647, /* dhKeyAgreement OID: 1.2.840.113549.1.3.1 */
}; };
@ -1031,8 +1033,11 @@ enum Extensions_Sum {
ISSUE_ALT_NAMES_OID = 132, /* 2.5.29.18 */ ISSUE_ALT_NAMES_OID = 132, /* 2.5.29.18 */
TLS_FEATURE_OID = 92, /* 1.3.6.1.5.5.7.1.24 */ TLS_FEATURE_OID = 92, /* 1.3.6.1.5.5.7.1.24 */
NETSCAPE_CT_OID = 753, /* 2.16.840.1.113730.1.1 */ NETSCAPE_CT_OID = 753, /* 2.16.840.1.113730.1.1 */
OCSP_NOCHECK_OID = 121 /* 1.3.6.1.5.5.7.48.1.5 OCSP_NOCHECK_OID = 121, /* 1.3.6.1.5.5.7.48.1.5
id-pkix-ocsp-nocheck */ id-pkix-ocsp-nocheck */
AKEY_PACKAGE_OID = 1048 /* 2.16.840.1.101.2.1.2.78.5
RFC 5958 - Asymmetric Key Packages */
}; };
enum CertificatePolicy_Sum { enum CertificatePolicy_Sum {
@ -1886,7 +1891,7 @@ enum Ocsp_Response_Status {
OCSP_INTERNAL_ERROR = 2, /* Internal error in issuer */ OCSP_INTERNAL_ERROR = 2, /* Internal error in issuer */
OCSP_TRY_LATER = 3, /* Try again later */ OCSP_TRY_LATER = 3, /* Try again later */
OCSP_SIG_REQUIRED = 5, /* Must sign the request (4 is skipped) */ OCSP_SIG_REQUIRED = 5, /* Must sign the request (4 is skipped) */
OCSP_UNAUTHROIZED = 6 /* Request unauthorized */ OCSP_UNAUTHORIZED = 6 /* Request unauthorized */
}; };
@ -1929,7 +1934,8 @@ struct CertStatus {
byte nextDate[MAX_DATE_SIZE]; byte nextDate[MAX_DATE_SIZE];
byte thisDateFormat; byte thisDateFormat;
byte nextDateFormat; byte nextDateFormat;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY)
WOLFSSL_ASN1_TIME thisDateParsed; WOLFSSL_ASN1_TIME thisDateParsed;
WOLFSSL_ASN1_TIME nextDateParsed; WOLFSSL_ASN1_TIME nextDateParsed;
byte* thisDateAsn; byte* thisDateAsn;

View File

@ -47,10 +47,18 @@ This library defines the interface APIs for X509 certificates.
typedef struct ed25519_key ed25519_key; typedef struct ed25519_key ed25519_key;
#define WC_ED25519KEY_TYPE_DEFINED #define WC_ED25519KEY_TYPE_DEFINED
#endif #endif
#ifndef WC_CURVE25519KEY_TYPE_DEFINED
typedef struct curve25519_key curve25519_key;
#define WC_CURVE25519KEY_TYPE_DEFINED
#endif
#ifndef WC_ED448KEY_TYPE_DEFINED #ifndef WC_ED448KEY_TYPE_DEFINED
typedef struct ed448_key ed448_key; typedef struct ed448_key ed448_key;
#define WC_ED448KEY_TYPE_DEFINED #define WC_ED448KEY_TYPE_DEFINED
#endif #endif
#ifndef WC_CURVE448KEY_TYPE_DEFINED
typedef struct curve448_key curve448_key;
#define WC_CURVE448KEY_TYPE_DEFINED
#endif
#ifndef WC_RSAKEY_TYPE_DEFINED #ifndef WC_RSAKEY_TYPE_DEFINED
typedef struct RsaKey RsaKey; typedef struct RsaKey RsaKey;
#define WC_RSAKEY_TYPE_DEFINED #define WC_RSAKEY_TYPE_DEFINED
@ -571,54 +579,69 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz);
WOLFSSL_API int wc_EccPublicKeyDerSize(ecc_key*, int with_AlgCurve); WOLFSSL_API int wc_EccPublicKeyDerSize(ecc_key*, int with_AlgCurve);
#endif #endif
/* RFC 5958 (Asymmetric Key Packages) */
#if !defined(WC_ENABLE_ASYM_KEY_EXPORT) && \
((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)) || \
(defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT)) || \
(defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT)) || \
(defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_EXPORT)))
#define WC_ENABLE_ASYM_KEY_EXPORT
#endif
#if !defined(WC_ENABLE_ASYM_KEY_IMPORT) && \
((defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)) || \
(defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_IMPORT)) || \
(defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)) || \
(defined(HAVE_CURVE448) && defined(HAVE_CURVE448_KEY_IMPORT)))
#define WC_ENABLE_ASYM_KEY_IMPORT
#endif
#ifdef HAVE_ED25519 #ifdef HAVE_ED25519
/* private key helpers */
#ifdef HAVE_ED25519_KEY_IMPORT #ifdef HAVE_ED25519_KEY_IMPORT
WOLFSSL_API int wc_Ed25519PrivateKeyDecode(const byte*, word32*, WOLFSSL_API int wc_Ed25519PrivateKeyDecode(const byte*, word32*, ed25519_key*, word32);
ed25519_key*, word32); WOLFSSL_API int wc_Ed25519PublicKeyDecode(const byte*, word32*, ed25519_key*, word32);
#endif #endif
#ifdef HAVE_ED25519_KEY_EXPORT #ifdef HAVE_ED25519_KEY_EXPORT
WOLFSSL_API int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, WOLFSSL_API int wc_Ed25519KeyToDer(ed25519_key*, byte*, word32);
word32 inLen); WOLFSSL_API int wc_Ed25519PrivateKeyToDer(ed25519_key*, byte*, word32);
WOLFSSL_API int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, WOLFSSL_API int wc_Ed25519PublicKeyToDer(ed25519_key*, byte*, word32, int);
word32 inLen);
#endif #endif
#endif /* HAVE_ED25519 */
/* public key helper */ #ifdef HAVE_CURVE25519
WOLFSSL_API int wc_Ed25519PublicKeyDecode(const byte*, word32*, #ifdef HAVE_CURVE25519_KEY_IMPORT
ed25519_key*, word32); WOLFSSL_API int wc_Curve25519PrivateKeyDecode(const byte*, word32*, curve25519_key*, word32);
#if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) && \ WOLFSSL_API int wc_Curve25519PublicKeyDecode(const byte*, word32*, curve25519_key*, word32);
defined(HAVE_ED25519_KEY_EXPORT)
WOLFSSL_API int wc_Ed25519PublicKeyToDer(ed25519_key*, byte* output,
word32 inLen, int with_AlgCurve);
#endif #endif
#ifdef HAVE_CURVE25519_KEY_EXPORT
WOLFSSL_API int wc_Curve25519PrivateKeyToDer(curve25519_key*, byte*, word32);
WOLFSSL_API int wc_Curve25519PublicKeyToDer(curve25519_key*, byte*, word32, int);
#endif #endif
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_ED448 #ifdef HAVE_ED448
/* private key helpers */
#ifdef HAVE_ED448_KEY_IMPORT #ifdef HAVE_ED448_KEY_IMPORT
WOLFSSL_API int wc_Ed448PrivateKeyDecode(const byte*, word32*, WOLFSSL_API int wc_Ed448PrivateKeyDecode(const byte*, word32*, ed448_key*, word32);
ed448_key*, word32); WOLFSSL_API int wc_Ed448PublicKeyDecode(const byte*, word32*, ed448_key*, word32);
#endif #endif
#ifdef HAVE_ED448_KEY_EXPORT #ifdef HAVE_ED448_KEY_EXPORT
WOLFSSL_API int wc_Ed448KeyToDer(ed448_key* key, byte* output, WOLFSSL_API int wc_Ed448KeyToDer(ed448_key*, byte*, word32);
word32 inLen); WOLFSSL_API int wc_Ed448PrivateKeyToDer(ed448_key*, byte*, word32);
WOLFSSL_API int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, WOLFSSL_API int wc_Ed448PublicKeyToDer(ed448_key*, byte*, word32, int);
word32 inLen);
#endif #endif
#endif /* HAVE_ED448 */
/* public key helper */ #ifdef HAVE_CURVE448
WOLFSSL_API int wc_Ed448PublicKeyDecode(const byte*, word32*, #ifdef HAVE_CURVE448_KEY_IMPORT
ed448_key*, word32); WOLFSSL_API int wc_Curve448PrivateKeyDecode(const byte*, word32*, curve448_key*, word32);
#if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) && \ WOLFSSL_API int wc_Curve448PublicKeyDecode(const byte*, word32*, curve448_key*, word32);
defined(HAVE_ED448_KEY_EXPORT)
WOLFSSL_API int wc_Ed448PublicKeyToDer(ed448_key*, byte* output,
word32 inLen, int with_AlgCurve);
#endif #endif
#ifdef HAVE_CURVE448_KEY_EXPORT
WOLFSSL_API int wc_Curve448PrivateKeyToDer(curve448_key*, byte*, word32);
WOLFSSL_API int wc_Curve448PublicKeyToDer(curve448_key*, byte*, word32, int);
#endif #endif
#endif /* HAVE_CURVE448 */
/* DER encode signature */ /* DER encode signature */
WOLFSSL_API word32 wc_EncodeSignature(byte* out, const byte* digest, WOLFSSL_API word32 wc_EncodeSignature(byte* out, const byte* digest,

View File

@ -64,8 +64,14 @@ typedef struct {
#ifdef FREESCALE_LTC_ECC #ifdef FREESCALE_LTC_ECC
byte pointY[CURVE25519_KEYSIZE]; byte pointY[CURVE25519_KEYSIZE];
#endif #endif
byte pointSz;
} ECPoint; } ECPoint;
#ifndef WC_CURVE25519KEY_TYPE_DEFINED
typedef struct curve25519_key curve25519_key;
#define WC_CURVE25519KEY_TYPE_DEFINED
#endif
/* A CURVE25519 Key */ /* A CURVE25519 Key */
typedef struct curve25519_key { typedef struct curve25519_key {
int idx; /* Index into the ecc_sets[] for the parameters of int idx; /* Index into the ecc_sets[] for the parameters of
@ -73,8 +79,8 @@ typedef struct curve25519_key {
curve in dp */ curve in dp */
const curve25519_set_type* dp; /* domain parameters, either points to const curve25519_set_type* dp; /* domain parameters, either points to
curves (idx >= 0) or user supplied */ curves (idx >= 0) or user supplied */
ECPoint p; /* public key */ ECPoint p; /* public point for key */
ECPoint k; /* private key */ byte k[CURVE25519_KEYSIZE]; /* private scaler for key */
#ifdef WOLFSSL_ASYNC_CRYPT #ifdef WOLFSSL_ASYNC_CRYPT
WC_ASYNC_DEV asyncDev; WC_ASYNC_DEV asyncDev;
@ -82,6 +88,10 @@ typedef struct curve25519_key {
#if defined(WOLF_CRYPTO_CB) #if defined(WOLF_CRYPTO_CB)
int devId; int devId;
#endif #endif
/* bit fields */
byte pubSet:1;
byte privSet:1;
} curve25519_key; } curve25519_key;
enum { enum {

View File

@ -43,6 +43,10 @@
#define CURVE448_KEY_SIZE 56 #define CURVE448_KEY_SIZE 56
#define CURVE448_PUB_KEY_SIZE 56 #define CURVE448_PUB_KEY_SIZE 56
#ifndef WC_CURVE448KEY_TYPE_DEFINED
typedef struct curve448_key curve448_key;
#define WC_CURVE448KEY_TYPE_DEFINED
#endif
/* A CURVE448 Key */ /* A CURVE448 Key */
typedef struct curve448_key { typedef struct curve448_key {
@ -52,6 +56,10 @@ typedef struct curve448_key {
#ifdef WOLFSSL_ASYNC_CRYPT #ifdef WOLFSSL_ASYNC_CRYPT
WC_ASYNC_DEV asyncDev; WC_ASYNC_DEV asyncDev;
#endif #endif
/* bit fields */
byte pubSet:1;
byte privSet:1;
} curve448_key; } curve448_key;
enum { enum {
@ -62,6 +70,10 @@ enum {
WOLFSSL_API WOLFSSL_API
int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key); int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key);
WOLFSSL_API
int wc_curve448_make_pub(int public_size, byte* pub, int private_size,
const byte* priv);
WOLFSSL_API WOLFSSL_API
int wc_curve448_shared_secret(curve448_key* private_key, int wc_curve448_shared_secret(curve448_key* private_key,
curve448_key* public_key, curve448_key* public_key,

View File

@ -180,6 +180,10 @@ enum {
#endif #endif
}; };
#endif /* HAVE_ECC */
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448) || defined(WOLFCRYPT_HAVE_SAKKE)
/* Curve Types */ /* Curve Types */
typedef enum ecc_curve_id { typedef enum ecc_curve_id {
ECC_CURVE_INVALID = -1, ECC_CURVE_INVALID = -1,
@ -227,7 +231,6 @@ typedef enum ecc_curve_id {
#ifdef HAVE_CURVE448 #ifdef HAVE_CURVE448
ECC_X448, ECC_X448,
#endif #endif
#ifdef WOLFCRYPT_HAVE_SAKKE #ifdef WOLFCRYPT_HAVE_SAKKE
ECC_SAKKE_1, ECC_SAKKE_1,
#endif #endif
@ -237,6 +240,9 @@ typedef enum ecc_curve_id {
#endif #endif
ECC_CURVE_MAX ECC_CURVE_MAX
} ecc_curve_id; } ecc_curve_id;
#endif
#ifdef HAVE_ECC
#ifdef HAVE_OID_ENCODING #ifdef HAVE_OID_ENCODING
typedef word16 ecc_oid_t; typedef word16 ecc_oid_t;