diff --git a/certs/ed25519/client-ed25519-priv.der b/certs/ed25519/client-ed25519-priv.der new file mode 100644 index 000000000..e5a27a411 Binary files /dev/null and b/certs/ed25519/client-ed25519-priv.der differ diff --git a/certs/ed25519/client-ed25519-priv.pem b/certs/ed25519/client-ed25519-priv.pem new file mode 100644 index 000000000..22f1d7de5 --- /dev/null +++ b/certs/ed25519/client-ed25519-priv.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIBGdNYxa3ommO8aYO1oGaGSRQBqDYB0sKOdR3bqejqIQ +-----END PRIVATE KEY----- diff --git a/certs/ed25519/server-ed25519-priv.der b/certs/ed25519/server-ed25519-priv.der new file mode 100644 index 000000000..a157ffd09 Binary files /dev/null and b/certs/ed25519/server-ed25519-priv.der differ diff --git a/certs/ed25519/server-ed25519-priv.pem b/certs/ed25519/server-ed25519-priv.pem new file mode 100644 index 000000000..6f1e1312f --- /dev/null +++ b/certs/ed25519/server-ed25519-priv.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEINjpdrI/H/eIdfXd+HrGSTBu6Z/LnR4rwBjvu3WJ5ndn +-----END PRIVATE KEY----- diff --git a/certs/include.am b/certs/include.am index 55e8632f2..7a227aa95 100755 --- a/certs/include.am +++ b/certs/include.am @@ -72,6 +72,8 @@ EXTRA_DIST += \ certs/ed25519/client-ed25519-key.der \ certs/ed25519/client-ed25519-key.pem \ certs/ed25519/client-ed25519.pem \ + certs/ed25519/client-ed25519-priv.pem \ + certs/ed25519/client-ed25519-priv.pem \ certs/ed25519/root-ed25519.der \ certs/ed25519/root-ed25519-key.der \ certs/ed25519/root-ed25519-key.pem \ @@ -79,7 +81,9 @@ EXTRA_DIST += \ certs/ed25519/server-ed25519.der \ certs/ed25519/server-ed25519-key.der \ certs/ed25519/server-ed25519-key.pem \ - certs/ed25519/server-ed25519.pem + certs/ed25519/server-ed25519.pem \ + certs/ed25519/server-ed25519-priv.der \ + certs/ed25519/server-ed25519-priv.pem # ECC CA prime256v1 EXTRA_DIST += \ diff --git a/examples/client/client.c b/examples/client/client.c index ba048b1af..35f46e98e 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -874,7 +874,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int err = 0; int scr = 0; /* allow secure renegotiation */ int forceScr = 0; /* force client initiaed scr */ +#ifndef WOLFSSL_NO_CLIENT_AUTH int useClientCert = 1; +#else + int useClientCert = 0; +#endif int fewerPackets = 0; int atomicUser = 0; #ifdef HAVE_PK_CALLBACKS diff --git a/examples/server/server.c b/examples/server/server.c index f31cf3b24..44e3b5910 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -405,6 +405,9 @@ static void Usage(void) printf("-n Use NTRU key (needed for NTRU suites)\n"); #endif printf("-B Benchmark throughput using bytes and print stats\n"); +#ifdef HAVE_CRL + printf("-V Disable CRL\n"); +#endif #ifdef WOLFSSL_TRUST_PEER_CERT printf("-E Path to load trusted peer cert\n"); #endif @@ -462,7 +465,14 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) char input[80]; int ch; int version = SERVER_DEFAULT_VERSION; +#ifndef WOLFSSL_NO_CLIENT_AUTH int doCliCertCheck = 1; +#else + int doCliCertCheck = 0; +#endif +#ifdef HAVE_CRL + int disableCRL = 0; +#endif int useAnyAddr = 0; word16 port = wolfSSLPort; int usePsk = 0; @@ -601,7 +611,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) /* Not Used: h, m, z, F, M, T, V, W, X */ while ((ch = mygetopt(argc, argv, "?" "abc:defgijk:l:nop:q:rstuv:wxy" - "A:B:C:D:E:GH:IJKL:NO:PQR:S:TUYZ:" + "A:B:C:D:E:GH:IJKL:NO:PQR:S:TUVYZ:" "03:")) != -1) { switch (ch) { case '?' : @@ -616,6 +626,12 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) doCliCertCheck = 0; break; + case 'V' : + #ifdef HAVE_CRL + disableCRL = 1; + #endif + break; + case 'b' : useAnyAddr = 1; break; @@ -1286,6 +1302,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL); #endif #ifdef HAVE_CRL + if (!disableCRL) { #ifdef HAVE_CRL_MONITOR crlFlags = CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON; #endif @@ -1296,6 +1313,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) err_sys_ex(runWithErrors, "unable to load CRL"); if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != WOLFSSL_SUCCESS) err_sys_ex(runWithErrors, "unable to set CRL callback url"); + } #endif #ifdef HAVE_OCSP if (useOcsp) { @@ -1567,17 +1585,19 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) if (postHandAuth) { SSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER | - ((usePskPlus)? WOLFSSL_VERIFY_FAIL_EXCEPT_PSK : - WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT),0); + ((usePskPlus) ? WOLFSSL_VERIFY_FAIL_EXCEPT_PSK : + WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT), 0); if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) - != WOLFSSL_SUCCESS) { - err_sys_ex(runWithErrors, "can't load ca file, Please run from wolfSSL home dir"); + != WOLFSSL_SUCCESS) { + err_sys_ex(runWithErrors, "can't load ca file, Please run from " + "wolfSSL home dir"); } #ifdef WOLFSSL_TRUST_PEER_CERT if (trustCert) { if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert, - WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { - err_sys_ex(runWithErrors, "can't load trusted peer cert file"); + WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + err_sys_ex(runWithErrors, "can't load trusted peer cert " + "file"); } } #endif /* WOLFSSL_TRUST_PEER_CERT */ diff --git a/src/internal.c b/src/internal.c index 2f56002d7..6df5dd578 100644 --- a/src/internal.c +++ b/src/internal.c @@ -103,7 +103,8 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS #ifndef NO_WOLFSSL_SERVER static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32*, word32); - #if !defined(NO_RSA) || defined(HAVE_ECC) + #if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)) && \ + !defined(WOLFSSL_NO_CLIENT_AUTH) static int DoCertificateVerify(WOLFSSL* ssl, byte*, word32*, word32); #endif #ifdef WOLFSSL_DTLS @@ -2692,7 +2693,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, * * input The encoded signature algorithm. * hashalgo The hash algorithm. - * hsType The signature type. + * hsType The signature type. */ static INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) { @@ -2888,35 +2889,37 @@ static INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) (void)output; } +#if !defined(WOLFSSL_NO_CLIENT_AUTH) static void SetDigest(WOLFSSL* ssl, int hashAlgo) { switch (hashAlgo) { - #ifndef NO_SHA + #ifndef NO_SHA case sha_mac: ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha; ssl->buffers.digest.length = WC_SHA_DIGEST_SIZE; break; - #endif /* !NO_SHA */ - #ifndef NO_SHA256 + #endif /* !NO_SHA */ + #ifndef NO_SHA256 case sha256_mac: ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha256; ssl->buffers.digest.length = WC_SHA256_DIGEST_SIZE; break; - #endif /* !NO_SHA256 */ - #ifdef WOLFSSL_SHA384 + #endif /* !NO_SHA256 */ + #ifdef WOLFSSL_SHA384 case sha384_mac: ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha384; ssl->buffers.digest.length = WC_SHA384_DIGEST_SIZE; break; - #endif /* WOLFSSL_SHA384 */ - #ifdef WOLFSSL_SHA512 + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 case sha512_mac: ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha512; ssl->buffers.digest.length = WC_SHA512_DIGEST_SIZE; break; - #endif /* WOLFSSL_SHA512 */ + #endif /* WOLFSSL_SHA512 */ } /* switch */ } +#endif /* !WOLFSSL_NO_CLIENT_AUTH */ #endif /* !NO_CERTS */ #ifndef NO_RSA @@ -3632,6 +3635,43 @@ int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer) #endif /* HAVE_ECC */ #ifdef HAVE_ED25519 +/* Check whether the key contains a public key. + * If not then pull it out of the leaf certificate. + * + * ssl SSL/TLS object. + * returns MEMORY_E when unable to allocate memory, a parsing error, otherwise + * 0 on success. + */ +int Ed25519CheckPubKey(WOLFSSL* ssl) +{ + ed25519_key* key = (ed25519_key*)ssl->hsKey; + int ret = 0; + + /* Public key required for signing. */ + if (!key->pubKeySet) { + DerBuffer* leaf = ssl->buffers.certificate; + DecodedCert* cert = (DecodedCert*)XMALLOC(sizeof(*cert), + ssl->heap, DYNAMIC_TYPE_DCERT); + if (cert == NULL) + ret = MEMORY_E; + + if (ret == 0) { + InitDecodedCert(cert, leaf->buffer, leaf->length, ssl->heap); + ret = DecodeToKey(cert, 0); + } + if (ret == 0) { + ret = wc_ed25519_import_public(cert->publicKey, cert->pubKeySize, + key); + } + if (cert != NULL) { + FreeDecodedCert(cert); + XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT); + } + } + + return ret; +} + /* Sign the data using EdDSA and key using X25519. * * ssl SSL object. @@ -4138,6 +4178,12 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->buffers.keyType = ctx->privateKeyType; ssl->buffers.keySz = ctx->privateKeySz; #endif +#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ + !defined(NO_ED25519_CLIENT_AUTH) + ssl->options.cacheMessages = ssl->options.side == WOLFSSL_SERVER_END || + ssl->buffers.keyType == ed25519_sa_algo; +#endif + #ifdef WOLFSSL_ASYNC_CRYPT ssl->devId = ctx->devId; @@ -4287,6 +4333,12 @@ void FreeHandshakeHashes(WOLFSSL* ssl) #ifdef WOLFSSL_SHA512 wc_Sha512Free(&ssl->hsHashes->hashSha512); #endif + #if defined(HAVE_ED25519) && !defined(WOLFSSL_NO_CLIENT_AUTH) + if (ssl->hsHashes->messages != NULL) { + XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES); + ssl->hsHashes->messages = NULL; + } + #endif XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES); ssl->hsHashes = NULL; @@ -5994,7 +6046,37 @@ ProtocolVersion MakeDTLSv1_2(void) return (word32)XTIME(0); } #endif +#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ + !defined(NO_ED25519_CLIENT_AUTH) +/* Store the message for use with CertificateVerify using Ed25519. + * + * ssl SSL/TLS object. + * data Message to store. + * sz Size of message to store. + * returns MEMORY_E if not able to reallocate, otherwise 0. + */ +static int Ed25519Update(WOLFSSL* ssl, const byte* data, int sz) +{ + int ret = 0; + byte* msgs; + if (ssl->options.cacheMessages) { + msgs = (byte*)XREALLOC(ssl->hsHashes->messages, + ssl->hsHashes->length + sz, + ssl->heap, DYNAMIC_TYPE_HASHES); + if (msgs == NULL) + ret = MEMORY_E; + if (ret == 0) { + ssl->hsHashes->messages = msgs; + XMEMCPY(msgs + ssl->hsHashes->length, data, sz); + ssl->hsHashes->prevLen = ssl->hsHashes->length; + ssl->hsHashes->length += sz; + } + } + + return ret; +} +#endif /* HAVE_ED25519 && !WOLFSSL_NO_CLIENT_AUTH */ #ifndef NO_CERTS int HashOutputRaw(WOLFSSL* ssl, const byte* output, int sz) @@ -6012,30 +6094,36 @@ int HashOutputRaw(WOLFSSL* ssl, const byte* output, int sz) ssl->fuzzerCb(ssl, output, sz, FUZZ_HASH, ssl->fuzzerCtx); #endif #ifndef NO_OLD_TLS -#ifndef NO_SHA - wc_ShaUpdate(&ssl->hsHashes->hashSha, output, sz); -#endif -#ifndef NO_MD5 - wc_Md5Update(&ssl->hsHashes->hashMd5, output, sz); -#endif + #ifndef NO_SHA + wc_ShaUpdate(&ssl->hsHashes->hashSha, output, sz); + #endif + #ifndef NO_MD5 + wc_Md5Update(&ssl->hsHashes->hashMd5, output, sz); + #endif #endif /* NO_OLD_TLS */ if (IsAtLeastTLSv1_2(ssl)) { -#ifndef NO_SHA256 + #ifndef NO_SHA256 ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, output, sz); if (ret != 0) return ret; -#endif -#ifdef WOLFSSL_SHA384 + #endif + #ifdef WOLFSSL_SHA384 ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, output, sz); if (ret != 0) return ret; -#endif -#ifdef WOLFSSL_SHA512 + #endif + #ifdef WOLFSSL_SHA512 ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, output, sz); if (ret != 0) return ret; -#endif + #endif + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ + !defined(NO_ED25519_CLIENT_AUTH) + ret = Ed25519Update(ssl, output, sz); + if (ret != 0) + return ret; + #endif } return ret; @@ -6063,30 +6151,36 @@ int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz) } #endif #ifndef NO_OLD_TLS -#ifndef NO_SHA - wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz); -#endif -#ifndef NO_MD5 - wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz); -#endif + #ifndef NO_SHA + wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz); + #endif + #ifndef NO_MD5 + wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz); + #endif #endif if (IsAtLeastTLSv1_2(ssl)) { -#ifndef NO_SHA256 + #ifndef NO_SHA256 ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz); if (ret != 0) return ret; -#endif -#ifdef WOLFSSL_SHA384 + #endif + #ifdef WOLFSSL_SHA384 ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz); if (ret != 0) return ret; -#endif -#ifdef WOLFSSL_SHA512 + #endif + #ifdef WOLFSSL_SHA512 ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz); if (ret != 0) return ret; -#endif + #endif + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ + !defined(NO_ED25519_CLIENT_AUTH) + ret = Ed25519Update(ssl, adj, sz); + if (ret != 0) + return ret; + #endif } return ret; @@ -6116,30 +6210,36 @@ int HashInput(WOLFSSL* ssl, const byte* input, int sz) } #ifndef NO_OLD_TLS -#ifndef NO_SHA - wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz); -#endif -#ifndef NO_MD5 - wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz); -#endif + #ifndef NO_SHA + wc_ShaUpdate(&ssl->hsHashes->hashSha, adj, sz); + #endif + #ifndef NO_MD5 + wc_Md5Update(&ssl->hsHashes->hashMd5, adj, sz); + #endif #endif if (IsAtLeastTLSv1_2(ssl)) { -#ifndef NO_SHA256 + #ifndef NO_SHA256 ret = wc_Sha256Update(&ssl->hsHashes->hashSha256, adj, sz); if (ret != 0) return ret; -#endif -#ifdef WOLFSSL_SHA384 + #endif + #ifdef WOLFSSL_SHA384 ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz); if (ret != 0) return ret; -#endif -#ifdef WOLFSSL_SHA512 + #endif + #ifdef WOLFSSL_SHA512 ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz); if (ret != 0) return ret; -#endif + #endif + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ + !defined(NO_ED25519_CLIENT_AUTH) + ret = Ed25519Update(ssl, adj, sz); + if (ret != 0) + return ret; + #endif } return ret; @@ -9185,7 +9285,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, } break; } - #endif /* HAVE_ECC */ + #endif /* HAVE_ED25519 */ default: break; } @@ -9408,7 +9508,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, int ret; WOLFSSL_START(WC_FUNC_CERTIFICATE_DO); - WOLFSSL_ENTER("DoCertificateVerify"); + WOLFSSL_ENTER("DoCertificate"); ret = ProcessPeerCerts(ssl, input, inOutIdx, size); @@ -9416,7 +9516,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, ssl->options.serverState = SERVER_CERT_COMPLETE; #endif - WOLFSSL_LEAVE("DoCertificateVerify", ret); + WOLFSSL_LEAVE("DoCertificate", ret); WOLFSSL_END(WC_FUNC_CERTIFICATE_DO); return ret; @@ -10163,6 +10263,13 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, case server_hello: WOLFSSL_MSG("processing server hello"); ret = DoServerHello(ssl, input, inOutIdx, size); + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ + !defined(NO_ED25519_CLIENT_AUTH) + if (ssl->options.resuming || !IsAtLeastTLSv1_2(ssl) || + IsAtLeastTLSv1_3(ssl->version)) { + ssl->options.cacheMessages = 0; + } + #endif break; #ifndef NO_CERTS @@ -10224,6 +10331,13 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, case client_hello: WOLFSSL_MSG("processing client hello"); ret = DoClientHello(ssl, input, inOutIdx, size); + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ + !defined(NO_ED25519_CLIENT_AUTH) + if (ssl->options.resuming || !ssl->options.verifyPeer || \ + !IsAtLeastTLSv1_2(ssl) || IsAtLeastTLSv1_3(ssl->version)) { + ssl->options.cacheMessages = 0; + } + #endif break; case client_key_exchange: @@ -10231,12 +10345,13 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = DoClientKeyExchange(ssl, input, inOutIdx, size); break; -#if !defined(NO_RSA) || defined(HAVE_ECC) +#if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)) && \ + !defined(WOLFSSL_NO_CLIENT_AUTH) case certificate_verify: WOLFSSL_MSG("processing certificate verify"); ret = DoCertificateVerify(ssl, input, inOutIdx, size); break; -#endif /* !NO_RSA || HAVE_ECC */ +#endif /* (!NO_RSA || HAVE_ECC || HAVE_ED25519) && !WOLFSSL_NO_CLIENT_AUTH */ #endif /* !NO_WOLFSSL_SERVER */ @@ -13582,6 +13697,7 @@ int SendFinished(WOLFSSL* ssl) #ifndef NO_CERTS +#if !defined(NO_WOLFSSL_SERVER) || !defined(WOLFSSL_NO_CLIENT_AUTH) /* handle generation of certificate (11) */ int SendCertificate(WOLFSSL* ssl) { @@ -13845,6 +13961,7 @@ int SendCertificate(WOLFSSL* ssl) return ret; } +#endif /* !NO_WOLFSSL_SERVER || !WOLFSSL_NO_CLIENT_AUTH */ /* handle generation of certificate_request (13) */ int SendCertificateRequest(WOLFSSL* ssl) @@ -17743,7 +17860,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, break; } #endif /* HAVE_ECC */ - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) case ed25519_sa_algo: { if (!ssl->peerEd25519KeyPresent) { @@ -17751,7 +17868,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, } break; } - #endif /* HAVE_ECC */ + #endif /* HAVE_ED25519 */ default: ret = ALGO_ID_E; @@ -17853,7 +17970,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, break; } #endif /* HAVE_ECC */ - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) case ed25519_sa_algo: { ret = Ed25519Verify(ssl, @@ -17871,7 +17988,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, break; } - #endif /* HAVE_ECC */ + #endif /* HAVE_ED25519 */ default: ret = ALGO_ID_E; @@ -17981,11 +18098,11 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, /* Nothing to do in this algo */ break; #endif /* HAVE_ECC */ - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) case ed25519_sa_algo: /* Nothing to do in this algo */ break; - #endif /* HAVE_ECC */ + #endif /* HAVE_ED25519 */ default: ret = ALGO_ID_E; } /* switch (sigAlgo) */ @@ -19627,9 +19744,9 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } #endif #ifdef HAVE_ED25519 -#if !defined(NO_RSA) || defined(HAVE_ECC) - FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey); -#endif + #if !defined(NO_RSA) || defined(HAVE_ECC) + FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey); + #endif ssl->hsType = DYNAMIC_TYPE_ED25519; ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); @@ -19637,13 +19754,13 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) goto exit_dpk; } -#ifdef HAVE_ECC - WOLFSSL_MSG("Trying ED25519 private key, ECC didn't work"); -#elif !defined(NO_RSA) - WOLFSSL_MSG("Trying ED25519 private key, RSA didn't work"); -#else - WOLFSSL_MSG("Trying ED25519 private key"); -#endif + #ifdef HAVE_ECC + WOLFSSL_MSG("Trying ED25519 private key, ECC didn't work"); + #elif !defined(NO_RSA) + WOLFSSL_MSG("Trying ED25519 private key, RSA didn't work"); + #else + WOLFSSL_MSG("Trying ED25519 private key"); + #endif /* Set start of data to beginning of buffer. */ idx = 0; @@ -19665,7 +19782,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) goto exit_dpk; } -#endif +#endif /* HAVE_ED25519 */ (void)idx; (void)keySz; @@ -19675,6 +19792,7 @@ exit_dpk: } +#ifndef WOLFSSL_NO_CLIENT_AUTH typedef struct ScvArgs { byte* output; /* not allocated */ #ifndef NO_RSA @@ -19883,6 +20001,13 @@ int SendCertificateVerify(WOLFSSL* ssl) c16toa(args->length, args->verify + args->extraSz); } #endif /* !NO_RSA */ + #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) + if (args->sigAlgo == ed25519_sa_algo) { + ret = Ed25519CheckPubKey(ssl); + if (ret != 0) + goto exit_scv; + } + #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; @@ -19908,12 +20033,12 @@ int SendCertificateVerify(WOLFSSL* ssl) ); } #endif /* HAVE_ECC */ - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) if (ssl->hsType == DYNAMIC_TYPE_ED25519) { ed25519_key* key = (ed25519_key*)ssl->hsKey; ret = Ed25519Sign(ssl, - ssl->buffers.digest.buffer, ssl->buffers.digest.length, + ssl->hsHashes->messages, ssl->hsHashes->length, ssl->buffers.sig.buffer, &ssl->buffers.sig.length, key, #ifdef HAVE_PK_CALLBACKS @@ -19924,7 +20049,7 @@ int SendCertificateVerify(WOLFSSL* ssl) #endif ); } - #endif /* HAVE_ECC */ + #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ #ifndef NO_RSA if (ssl->hsType == DYNAMIC_TYPE_RSA) { RsaKey* key = (RsaKey*)ssl->hsKey; @@ -20133,6 +20258,7 @@ exit_scv: return ret; } +#endif /* WOLFSSL_NO_CLIENT_AUTH */ #endif /* NO_CERTS */ @@ -21330,13 +21456,17 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; #endif #endif /* !NO_RSA */ - #ifdef HAVE_ED25519 - case ed25519_sa_algo: - #endif case ecc_dsa_sa_algo: { break; } + #ifdef HAVE_ED25519 + case ed25519_sa_algo: + ret = Ed25519CheckPubKey(ssl); + if (ret != 0) + goto exit_sske; + break; + #endif /* HAVE_ED25519 */ } /* switch(ssl->specs.sig_algo) */ break; } @@ -21796,18 +21926,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif case ecc_dsa_sa_algo: - { - /* Now that we know the real sig size, write it. */ - c16toa((word16)args->sigSz, - args->output + args->idx); - - /* And adjust length and sendSz from estimates */ - args->length += args->sigSz - args->tmpSigSz; - args->sendSz += args->sigSz - args->tmpSigSz; - break; - } #ifdef HAVE_ED25519 case ed25519_sa_algo: + #endif { /* Now that we know the real sig size, write it. */ c16toa((word16)args->sigSz, @@ -21818,7 +21939,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, args->sendSz += args->sigSz - args->tmpSigSz; break; } - #endif default: ERROR_OUT(ALGO_ID_E, exit_sske); /* unsupported type */ } /* switch(ssl->specs.sig_algo) */ @@ -22977,7 +23097,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } -#if !defined(NO_RSA) || defined(HAVE_ECC) +#if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)) && \ + !defined(WOLFSSL_NO_CLIENT_AUTH) typedef struct DcvArgs { byte* output; /* not allocated */ @@ -23072,10 +23193,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, else if (ssl->peerEccDsaKeyPresent) args->sigAlgo = ecc_dsa_sa_algo; #endif - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) else if (ssl->peerEd25519KeyPresent) args->sigAlgo = ed25519_sa_algo; - #endif + #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ if ((args->idx - args->begin) + OPAQUE16_LEN > size) { ERROR_OUT(BUFFER_ERROR, exit_dcv); @@ -23116,7 +23237,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } } #endif /* HAVE_ECC */ - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) if (ssl->peerEd25519KeyPresent) { WOLFSSL_MSG("Doing ED25519 peer cert verify"); if (IsAtLeastTLSv1_2(ssl) && @@ -23125,7 +23246,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, "Oops, peer sent ED25519 key but not in verify"); } } - #endif /* HAVE_ED25519 */ + #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; @@ -23179,6 +23300,23 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ); } #endif /* HAVE_ECC */ + #if defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH) + if (ssl->peerEd25519KeyPresent) { + WOLFSSL_MSG("Doing Ed25519 peer cert verify"); + + ret = Ed25519Verify(ssl, + input + args->idx, args->sz, + ssl->hsHashes->messages, ssl->hsHashes->prevLen, + ssl->peerEd25519Key, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEd25519Key, + ssl->Ed25519VerifyCtx + #else + NULL, NULL + #endif + ); + } + #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ /* Check for error */ if (ret != 0) { @@ -23311,7 +23449,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return ret; } -#endif /* !NO_RSA || HAVE_ECC */ +#endif /* (!NO_RSA || HAVE_ECC || HAVE_ED25519) && !WOLFSSL_NO_CLIENT_AUTH */ /* handle generation of server_hello_done (14) */ int SendServerHelloDone(WOLFSSL* ssl) diff --git a/src/ssl.c b/src/ssl.c index 4f9cf42f8..5c7ba8b8f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8678,11 +8678,11 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, FALL_THROUGH; case FIRST_REPLY_DONE : - #ifdef WOLFSSL_TLS13 - if (ssl->options.tls1_3) - return wolfSSL_connect_TLSv13(ssl); - #endif - #ifndef NO_CERTS + #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH) + #ifdef WOLFSSL_TLS13 + if (ssl->options.tls1_3) + return wolfSSL_connect_TLSv13(ssl); + #endif if (ssl->options.sendVerify) { if ( (ssl->error = SendCertificate(ssl)) != 0) { WOLFSSL_ERROR(ssl->error); @@ -8714,7 +8714,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, FALL_THROUGH; case FIRST_REPLY_SECOND : - #ifndef NO_CERTS + #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH) if (ssl->options.sendVerify) { if ( (ssl->error = SendCertificateVerify(ssl)) != 0) { WOLFSSL_ERROR(ssl->error); @@ -8722,7 +8722,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } WOLFSSL_MSG("sent: certificate verify"); } - #endif + #endif /* !NO_CERTS && !WOLFSSL_NO_CLIENT_AUTH */ ssl->options.connectState = FIRST_REPLY_THIRD; WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD"); FALL_THROUGH; diff --git a/src/tls13.c b/src/tls13.c index 35a371845..ce444ea47 100755 --- a/src/tls13.c +++ b/src/tls13.c @@ -5252,7 +5252,10 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) #endif /* HAVE_ECC */ #ifdef HAVE_ED25519 if (ssl->hsType == DYNAMIC_TYPE_ED25519) { - /* Nothing to do */ + ret = Ed25519CheckPubKey(ssl); + if (ret < 0) { + ERROR_OUT(ret, exit_scv); + } sig->length = ED25519_SIG_SIZE; } #endif /* HAVE_ECC */ diff --git a/tests/test-ed25519.conf b/tests/test-ed25519.conf index cc68ba2d7..e13c67b18 100644 --- a/tests/test-ed25519.conf +++ b/tests/test-ed25519.conf @@ -10,21 +10,22 @@ -A ./certs/ed25519/root-ed25519.pem -C -# Enable when CRL for ED25519 certificates available. # server TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 -#-v 3 -#-l ECDHE-ECDSA-AES128-GCM-SHA256 -#-c ./certs/ed25519/server-ed25519.pem -#-k ./certs/ed25519/server-ed25519-key.pem -#-A ./certs/ed25519/client-ed25519.pem +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/ed25519/server-ed25519.pem +-k ./certs/ed25519/server-ed25519-key.pem +-A ./certs/ed25519/client-ed25519.pem +-V +# Remove -V when CRL for ED25519 certificates available. # client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 -#-v 3 -#-l ECDHE-ECDSA-AES128-GCM-SHA256 -#-c ./certs/ed25519/client-ed25519.pem -#-k ./certs/ed25519/client-ed25519-key.pem -#-A ./certs/ed25519/root-ed25519.pem -#-C +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/ed25519/client-ed25519.pem +-k ./certs/ed25519/client-ed25519-key.pem +-A ./certs/ed25519/root-ed25519.pem +-C # server TLSv1.3 TLS13-AES128-GCM-SHA256 -v 4 @@ -40,16 +41,19 @@ # Enable when CRL for ED25519 certificates available. # server TLSv1.3 TLS13-AES128-GCM-SHA256 -#-v 4 -#-l TLS13-AES128-GCM-SHA256 -#-c ./certs/ed25519/server-ed25519.pem -#-k ./certs/ed25519/server-ed25519-key.pem -#-A ./certs/ed25519/client-ed25519.pem +-v 4 +-l TLS13-AES128-GCM-SHA256 +-c ./certs/ed25519/server-ed25519.pem +-k ./certs/ed25519/server-ed25519-key.pem +-A ./certs/ed25519/client-ed25519.pem +-V +# Remove -V when CRL for ED25519 certificates available. # client TLSv1.3 TLS13-AES128-GCM-SHA256 -#-v 4 -#-l TLS13-AES128-GCM-SHA256 -#-c ./certs/ed25519/client-ed25519.pem -#-k ./certs/ed25519/client-ed25519-key.pem -#-A ./certs/ed25519/root-ed25519.pem -#-C +-v 4 +-l TLS13-AES128-GCM-SHA256 +-c ./certs/ed25519/client-ed25519.pem +-k ./certs/ed25519/client-ed25519-key.pem +-A ./certs/ed25519/root-ed25519.pem +-C + diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 05802c3e0..58cbcdf68 100755 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -12296,29 +12296,38 @@ int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx, if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) return BAD_FUNC_ARG; - if (GetSequence(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - endKeyIdx = *inOutIdx + length; + if (GetSequence(input, inOutIdx, &length, inSz) >= 0) { + endKeyIdx = *inOutIdx + length; - if (GetMyVersion(input, inOutIdx, &version, inSz) < 0) - return ASN_PARSE_E; - if (version != 0) { - WOLFSSL_MSG("Unrecognized version of ED25519 private key"); - return ASN_PARSE_E; + if (GetMyVersion(input, inOutIdx, &version, inSz) < 0) + return ASN_PARSE_E; + if (version != 0) { + WOLFSSL_MSG("Unrecognized version of ED25519 private key"); + return ASN_PARSE_E; + } + + if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0) + return ASN_PARSE_E; + if (oid != ED25519k) + return ASN_PARSE_E; + + if (GetOctetString(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) + return ASN_PARSE_E; + + priv = input + *inOutIdx; + *inOutIdx += privSz; } + else { + if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) + return ASN_PARSE_E; - if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0) - return ASN_PARSE_E; - if (oid != ED25519k) - return ASN_PARSE_E; - - if (GetOctetString(input, inOutIdx, &length, inSz) < 0) - return ASN_PARSE_E; - - if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) - return ASN_PARSE_E; - priv = input + *inOutIdx; - *inOutIdx += privSz; + priv = input + *inOutIdx; + *inOutIdx += privSz; + endKeyIdx = *inOutIdx; + } if (endKeyIdx == (int)*inOutIdx) { ret = wc_ed25519_import_private_only(priv, privSz, key); diff --git a/wolfcrypt/src/ed25519.c b/wolfcrypt/src/ed25519.c index 633eb5c07..12d784347 100644 --- a/wolfcrypt/src/ed25519.c +++ b/wolfcrypt/src/ed25519.c @@ -90,6 +90,8 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key) /* put public key after private key, on the same buffer */ XMEMMOVE(key->k + ED25519_KEY_SIZE, key->p, ED25519_PUB_KEY_SIZE); + key->pubKeySet = 1; + return ret; } @@ -121,6 +123,8 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out, /* sanity check on arguments */ if (in == NULL || out == NULL || outLen == NULL || key == NULL) return BAD_FUNC_ARG; + if (!key->pubKeySet) + return BAD_FUNC_ARG; /* check and set up out length */ if (*outLen < ED25519_SIG_SIZE) { @@ -370,6 +374,7 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key) pubKey.Y = key->pointY; LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey); #endif + key->pubKeySet = 1; return 0; } @@ -389,6 +394,8 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key) ret = ge_compress_key(key->p, in+1, in+1+ED25519_PUB_KEY_SIZE, ED25519_PUB_KEY_SIZE); #endif /* FREESCALE_LTC_ECC */ + if (ret == 0) + key->pubKeySet = 1; return ret; } @@ -403,6 +410,7 @@ int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key) pubKey.Y = key->pointY; LTC_PKHA_Ed25519_PointDecompress(key->p, ED25519_PUB_KEY_SIZE, &pubKey); #endif + key->pubKeySet = 1; return 0; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 30deba40a..df451da0f 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -17115,6 +17115,38 @@ int ed25519_test(void) 0 /*sizeof(msg1)*/, sizeof(msg4) }; + static byte privateEd25519[] = { + 0x30,0x2e,0x02,0x01,0x00,0x30,0x05,0x06, + 0x03,0x2b,0x65,0x70,0x04,0x22,0x04,0x20, + 0x9d,0x61,0xb1,0x9d,0xef,0xfd,0x5a,0x60, + 0xba,0x84,0x4a,0xf4,0x92,0xec,0x2c,0xc4, + 0x44,0x49,0xc5,0x69,0x7b,0x32,0x69,0x19, + 0x70,0x3b,0xac,0x03,0x1c,0xae,0x7f,0x60 + }; + static byte publicEd25519[] = { + 0x30,0x2a,0x30,0x05,0x06,0x03,0x2b,0x65, + 0x70,0x03,0x21,0x00,0xd7,0x5a,0x98,0x01, + 0x82,0xb1,0x0a,0xb7,0xd5,0x4b,0xfe,0xd3, + 0xc9,0x64,0x07,0x3a,0x0e,0xe1,0x72,0xf3, + 0xda,0xa6,0x23,0x25,0xaf,0x02,0x1a,0x68, + 0xf7,0x07,0x51,0x1a + }; + static byte privPubEd25519[] = { + 0x30,0x52,0x02,0x01,0x00,0x30,0x05,0x06, + 0x03,0x2b,0x65,0x70,0x04,0x22,0x04,0x20, + 0x9d,0x61,0xb1,0x9d,0xef,0xfd,0x5a,0x60, + 0xba,0x84,0x4a,0xf4,0x92,0xec,0x2c,0xc4, + 0x44,0x49,0xc5,0x69,0x7b,0x32,0x69,0x19, + 0x70,0x3b,0xac,0x03,0x1c,0xae,0x7f,0x60, + 0xa1,0x22,0x04,0x20,0xd7,0x5a,0x98,0x01, + 0x82,0xb1,0x0a,0xb7,0xd5,0x4b,0xfe,0xd3, + 0xc9,0x64,0x07,0x3a,0x0e,0xe1,0x72,0xf3, + 0xda,0xa6,0x23,0x25,0xaf,0x02,0x1a,0x68, + 0xf7,0x07,0x51,0x1a + }; + word32 idx; + ed25519_key key3; + #endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_EXPORT && HAVE_ED25519_KEY_IMPORT */ /* create ed25519 keys */ @@ -17128,6 +17160,7 @@ int ed25519_test(void) wc_ed25519_init(&key); wc_ed25519_init(&key2); + wc_ed25519_init(&key3); wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key); wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key2); @@ -17145,8 +17178,7 @@ int ed25519_test(void) pKeySz[i], &key) != 0) return -8901 - i; - if (wc_ed25519_sign_msg(msgs[i], msgSz[i], out, &outlen, &key) - != 0) + if (wc_ed25519_sign_msg(msgs[i], msgSz[i], out, &outlen, &key) != 0) return -8911 - i; if (XMEMCMP(out, sigs[i], 64)) @@ -17196,6 +17228,50 @@ int ed25519_test(void) return -9011 - i; #endif /* HAVE_ED25519_VERIFY */ } + + /* Try ASN.1 encoded private-only key and public key. */ + idx = 0; + if (wc_Ed25519PrivateKeyDecode(privateEd25519, &idx, &key3, + sizeof(privateEd25519)) != 0) + return -7230 - i; + + if (wc_ed25519_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3) + != BAD_FUNC_ARG) + return -7231 - i; + + idx = 0; + if (wc_Ed25519PublicKeyDecode(publicEd25519, &idx, &key3, + sizeof(publicEd25519)) != 0) + return -7232 - i; + + if (wc_ed25519_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3) != 0) + return -7233 - i; + + if (XMEMCMP(out, sigs[0], 64)) + return -7234 - i; + +#if defined(HAVE_ED25519_VERIFY) + /* test verify on good msg */ + if (wc_ed25519_verify_msg(out, outlen, msgs[0], msgSz[0], &verify, &key3) + != 0 || verify != 1) + return -7233 - i; +#endif /* HAVE_ED25519_VERIFY */ + + wc_ed25519_free(&key3); + wc_ed25519_init(&key3); + + idx = 0; + if (wc_Ed25519PrivateKeyDecode(privPubEd25519, &idx, &key3, + sizeof(privPubEd25519)) != 0) + return -7230 - i; + + if (wc_ed25519_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3) != 0) + return -7233 - i; + + if (XMEMCMP(out, sigs[0], 64)) + return -7234 - i; + + wc_ed25519_free(&key3); #endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_EXPORT && HAVE_ED25519_KEY_IMPORT */ /* clean up keys when done */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 9976a6211..c9ef6413d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3075,6 +3075,10 @@ typedef struct Options { #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT) word16 sentChangeCipher:1; /* Change Cipher Spec sent */ #endif +#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ + !defined(NO_ED25519_CLIENT_AUTH) + word16 cacheMessages:1; /* Cache messages for sign/verify */ +#endif /* need full byte values for this section */ byte processReply; /* nonblocking resume */ @@ -3369,6 +3373,11 @@ typedef struct HS_Hashes { #ifdef WOLFSSL_SHA512 wc_Sha512 hashSha512; /* sha512 hash of handshake msgs */ #endif +#if defined(HAVE_ED25519) && !defined(WOLFSSL_NO_CLIENT_AUTH) + byte* messages; /* handshake messages */ + int length; /* length of handhsake messages' data */ + int prevLen; /* length of messages but last */ +#endif } HS_Hashes; @@ -3895,6 +3904,7 @@ WOLFSSL_LOCAL int wolfSSL_GetMaxRecordSize(WOLFSSL* ssl, int maxFragment); word32* outlen, int side, void* ctx); #endif /* HAVE_ECC */ #ifdef HAVE_ED25519 + WOLFSSL_LOCAL int Ed25519CheckPubKey(WOLFSSL* ssl); WOLFSSL_LOCAL int Ed25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, word32* outSz, ed25519_key* key, DerBuffer* keyBufInfo, void* ctx); diff --git a/wolfssl/wolfcrypt/ed25519.h b/wolfssl/wolfcrypt/ed25519.h index 82aa41062..e3950c3ea 100644 --- a/wolfssl/wolfcrypt/ed25519.h +++ b/wolfssl/wolfcrypt/ed25519.h @@ -77,6 +77,7 @@ struct ed25519_key { byte pointX[ED25519_KEY_SIZE]; /* recovered X coordinate */ byte pointY[ED25519_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */ #endif + int pubKeySet:1; #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif