cjson
fuzzing
inputs
test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9library_config
cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmaketests
inputs
test1 test1.expected test10 test10.expected test11 test11.expected test2 test2.expected test3 test3.expected test4 test4.expected test5 test5.expected test6 test7 test7.expected test8 test8.expected test9 test9.expectedjson-patch-tests
.editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.jsonunity
auto
colour_prompt.rb colour_reporter.rb generate_config.yml generate_module.rb generate_test_runner.rb parse_output.rb stylize_as_junit.rb test_file_filter.rb type_sanitizer.rb unity_test_summary.py unity_test_summary.rb unity_to_junit.pydocs
ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txtexamples
unity_config.hcurl
.github
scripts
cleancmd.pl cmp-config.pl cmp-pkg-config.sh codespell-ignore.words codespell.sh distfiles.sh pyspelling.words pyspelling.yaml randcurl.pl requirements-docs.txt requirements-proselint.txt requirements.txt shellcheck-ci.sh shellcheck.sh spellcheck.curl trimmarkdownheader.pl typos.sh typos.toml verify-examples.pl verify-synopsis.pl yamlcheck.sh yamlcheck.yamlworkflows
appveyor-status.yml checkdocs.yml checksrc.yml checkurls.yml codeql.yml configure-vs-cmake.yml curl-for-win.yml distcheck.yml fuzz.yml http3-linux.yml label.yml linux-old.yml linux.yml macos.yml non-native.yml windows.ymlCMake
CurlSymbolHiding.cmake CurlTests.c FindBrotli.cmake FindCares.cmake FindGSS.cmake FindGnuTLS.cmake FindLDAP.cmake FindLibbacktrace.cmake FindLibgsasl.cmake FindLibidn2.cmake FindLibpsl.cmake FindLibssh.cmake FindLibssh2.cmake FindLibuv.cmake FindMbedTLS.cmake FindNGHTTP2.cmake FindNGHTTP3.cmake FindNGTCP2.cmake FindNettle.cmake FindQuiche.cmake FindRustls.cmake FindWolfSSL.cmake FindZstd.cmake Macros.cmake OtherTests.cmake PickyWarnings.cmake Utilities.cmake cmake_uninstall.in.cmake curl-config.in.cmake unix-cache.cmake win32-cache.cmakedocs
cmdline-opts
.gitignore CMakeLists.txt MANPAGE.md Makefile.am Makefile.inc _AUTHORS.md _BUGS.md _DESCRIPTION.md _ENVIRONMENT.md _EXITCODES.md _FILES.md _GLOBBING.md _NAME.md _OPTIONS.md _OUTPUT.md _PROGRESS.md _PROTOCOLS.md _PROXYPREFIX.md _SEEALSO.md _SYNOPSIS.md _URL.md _VARIABLES.md _VERSION.md _WWW.md abstract-unix-socket.md alt-svc.md anyauth.md append.md aws-sigv4.md basic.md ca-native.md cacert.md capath.md cert-status.md cert-type.md cert.md ciphers.md compressed-ssh.md compressed.md config.md connect-timeout.md connect-to.md continue-at.md cookie-jar.md cookie.md create-dirs.md create-file-mode.md crlf.md crlfile.md curves.md data-ascii.md data-binary.md data-raw.md data-urlencode.md data.md delegation.md digest.md disable-eprt.md disable-epsv.md disable.md disallow-username-in-url.md dns-interface.md dns-ipv4-addr.md dns-ipv6-addr.md dns-servers.md doh-cert-status.md doh-insecure.md doh-url.md dump-ca-embed.md dump-header.md ech.md egd-file.md engine.md etag-compare.md etag-save.md expect100-timeout.md fail-early.md fail-with-body.md fail.md false-start.md follow.md form-escape.md form-string.md form.md ftp-account.md ftp-alternative-to-user.md ftp-create-dirs.md ftp-method.md ftp-pasv.md ftp-port.md ftp-pret.md ftp-skip-pasv-ip.md ftp-ssl-ccc-mode.md ftp-ssl-ccc.md ftp-ssl-control.md get.md globoff.md happy-eyeballs-timeout-ms.md haproxy-clientip.md haproxy-protocol.md head.md header.md help.md hostpubmd5.md hostpubsha256.md hsts.md http0.9.md http1.0.md http1.1.md http2-prior-knowledge.md http2.md http3-only.md http3.md ignore-content-length.md insecure.md interface.md ip-tos.md ipfs-gateway.md ipv4.md ipv6.md json.md junk-session-cookies.md keepalive-cnt.md keepalive-time.md key-type.md key.md knownhosts.md krb.md libcurl.md limit-rate.md list-only.md local-port.md location-trusted.md location.md login-options.md mail-auth.md mail-from.md mail-rcpt-allowfails.md mail-rcpt.md mainpage.idx manual.md max-filesize.md max-redirs.md max-time.md metalink.md mptcp.md negotiate.md netrc-file.md netrc-optional.md netrc.md next.md no-alpn.md no-buffer.md no-clobber.md no-keepalive.md no-npn.md no-progress-meter.md no-sessionid.md noproxy.md ntlm-wb.md ntlm.md oauth2-bearer.md out-null.md output-dir.md output.md parallel-immediate.md parallel-max-host.md parallel-max.md parallel.md pass.md path-as-is.md pinnedpubkey.md post301.md post302.md post303.md preproxy.md progress-bar.md proto-default.md proto-redir.md proto.md proxy-anyauth.md proxy-basic.md proxy-ca-native.md proxy-cacert.md proxy-capath.md proxy-cert-type.md proxy-cert.md proxy-ciphers.md proxy-crlfile.md proxy-digest.md proxy-header.md proxy-http2.md proxy-insecure.md proxy-key-type.md proxy-key.md proxy-negotiate.md proxy-ntlm.md proxy-pass.md proxy-pinnedpubkey.md proxy-service-name.md proxy-ssl-allow-beast.md proxy-ssl-auto-client-cert.md proxy-tls13-ciphers.md proxy-tlsauthtype.md proxy-tlspassword.md proxy-tlsuser.md proxy-tlsv1.md proxy-user.md proxy.md proxy1.0.md proxytunnel.md pubkey.md quote.md random-file.md range.md rate.md raw.md referer.md remote-header-name.md remote-name-all.md remote-name.md remote-time.md remove-on-error.md request-target.md request.md resolve.md retry-all-errors.md retry-connrefused.md retry-delay.md retry-max-time.md retry.md sasl-authzid.md sasl-ir.md service-name.md show-error.md show-headers.md sigalgs.md silent.md skip-existing.md socks4.md socks4a.md socks5-basic.md socks5-gssapi-nec.md socks5-gssapi-service.md socks5-gssapi.md socks5-hostname.md socks5.md speed-limit.md speed-time.md ssl-allow-beast.md ssl-auto-client-cert.md ssl-no-revoke.md ssl-reqd.md ssl-revoke-best-effort.md ssl-sessions.md ssl.md sslv2.md sslv3.md stderr.md styled-output.md suppress-connect-headers.md tcp-fastopen.md tcp-nodelay.md telnet-option.md tftp-blksize.md tftp-no-options.md time-cond.md tls-earlydata.md tls-max.md tls13-ciphers.md tlsauthtype.md tlspassword.md tlsuser.md tlsv1.0.md tlsv1.1.md tlsv1.2.md tlsv1.3.md tlsv1.md tr-encoding.md trace-ascii.md trace-config.md trace-ids.md trace-time.md trace.md unix-socket.md upload-file.md upload-flags.md url-query.md url.md use-ascii.md user-agent.md user.md variable.md verbose.md version.md vlan-priority.md write-out.md xattr.mdexamples
.checksrc .gitignore 10-at-a-time.c CMakeLists.txt Makefile.am Makefile.example Makefile.inc README.md adddocsref.pl address-scope.c altsvc.c anyauthput.c block_ip.c cacertinmem.c certinfo.c chkspeed.c connect-to.c cookie_interface.c crawler.c debug.c default-scheme.c ephiperfifo.c evhiperfifo.c externalsocket.c fileupload.c ftp-delete.c ftp-wildcard.c ftpget.c ftpgetinfo.c ftpgetresp.c ftpsget.c ftpupload.c ftpuploadfrommem.c ftpuploadresume.c getinfo.c getinmemory.c getredirect.c getreferrer.c ghiper.c headerapi.c hiperfifo.c hsts-preload.c htmltidy.c htmltitle.cpp http-options.c http-post.c http2-download.c http2-pushinmemory.c http2-serverpush.c http2-upload.c http3-present.c http3.c httpcustomheader.c httpput-postfields.c httpput.c https.c imap-append.c imap-authzid.c imap-copy.c imap-create.c imap-delete.c imap-examine.c imap-fetch.c imap-list.c imap-lsub.c imap-multi.c imap-noop.c imap-search.c imap-ssl.c imap-store.c imap-tls.c interface.c ipv6.c keepalive.c localport.c log_failed_transfers.c maxconnects.c multi-app.c multi-debugcallback.c multi-double.c multi-event.c multi-formadd.c multi-legacy.c multi-post.c multi-single.c multi-uv.c netrc.c parseurl.c persistent.c pop3-authzid.c pop3-dele.c pop3-list.c pop3-multi.c pop3-noop.c pop3-retr.c pop3-ssl.c pop3-stat.c pop3-tls.c pop3-top.c pop3-uidl.c post-callback.c postinmemory.c postit2-formadd.c postit2.c progressfunc.c protofeats.c range.c resolve.c rtsp-options.c sendrecv.c sepheaders.c sessioninfo.c sftpget.c sftpuploadresume.c shared-connection-cache.c simple.c simplepost.c simplessl.c smooth-gtk-thread.c smtp-authzid.c smtp-expn.c smtp-mail.c smtp-mime.c smtp-multi.c smtp-ssl.c smtp-tls.c smtp-vrfy.c sslbackend.c synctime.c threaded.c unixsocket.c url2file.c urlapi.c usercertinmem.c version-check.pl websocket-cb.c websocket-updown.c websocket.c xmlstream.cinternals
BUFQ.md BUFREF.md CHECKSRC.md CLIENT-READERS.md CLIENT-WRITERS.md CODE_STYLE.md CONNECTION-FILTERS.md CREDENTIALS.md CURLX.md DYNBUF.md HASH.md LLIST.md MID.md MQTT.md MULTI-EV.md NEW-PROTOCOL.md PEERS.md PORTING.md RATELIMITS.md README.md SCORECARD.md SPLAY.md STRPARSE.md THRDPOOL-AND-QUEUE.md TIME-KEEPING.md TLS-SESSIONS.md UINT_SETS.md WEBSOCKET.mdlibcurl
opts
CMakeLists.txt CURLINFO_ACTIVESOCKET.md CURLINFO_APPCONNECT_TIME.md CURLINFO_APPCONNECT_TIME_T.md CURLINFO_CAINFO.md CURLINFO_CAPATH.md CURLINFO_CERTINFO.md CURLINFO_CONDITION_UNMET.md CURLINFO_CONNECT_TIME.md CURLINFO_CONNECT_TIME_T.md CURLINFO_CONN_ID.md CURLINFO_CONTENT_LENGTH_DOWNLOAD.md CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md CURLINFO_CONTENT_LENGTH_UPLOAD.md CURLINFO_CONTENT_LENGTH_UPLOAD_T.md CURLINFO_CONTENT_TYPE.md CURLINFO_COOKIELIST.md CURLINFO_EARLYDATA_SENT_T.md CURLINFO_EFFECTIVE_METHOD.md CURLINFO_EFFECTIVE_URL.md CURLINFO_FILETIME.md CURLINFO_FILETIME_T.md CURLINFO_FTP_ENTRY_PATH.md CURLINFO_HEADER_SIZE.md CURLINFO_HTTPAUTH_AVAIL.md CURLINFO_HTTPAUTH_USED.md CURLINFO_HTTP_CONNECTCODE.md CURLINFO_HTTP_VERSION.md CURLINFO_LASTSOCKET.md CURLINFO_LOCAL_IP.md CURLINFO_LOCAL_PORT.md CURLINFO_NAMELOOKUP_TIME.md CURLINFO_NAMELOOKUP_TIME_T.md CURLINFO_NUM_CONNECTS.md CURLINFO_OS_ERRNO.md CURLINFO_POSTTRANSFER_TIME_T.md CURLINFO_PRETRANSFER_TIME.md CURLINFO_PRETRANSFER_TIME_T.md CURLINFO_PRIMARY_IP.md CURLINFO_PRIMARY_PORT.md CURLINFO_PRIVATE.md CURLINFO_PROTOCOL.md CURLINFO_PROXYAUTH_AVAIL.md CURLINFO_PROXYAUTH_USED.md CURLINFO_PROXY_ERROR.md CURLINFO_PROXY_SSL_VERIFYRESULT.md CURLINFO_QUEUE_TIME_T.md CURLINFO_REDIRECT_COUNT.md CURLINFO_REDIRECT_TIME.md CURLINFO_REDIRECT_TIME_T.md CURLINFO_REDIRECT_URL.md CURLINFO_REFERER.md CURLINFO_REQUEST_SIZE.md CURLINFO_RESPONSE_CODE.md CURLINFO_RETRY_AFTER.md CURLINFO_RTSP_CLIENT_CSEQ.md CURLINFO_RTSP_CSEQ_RECV.md CURLINFO_RTSP_SERVER_CSEQ.md CURLINFO_RTSP_SESSION_ID.md CURLINFO_SCHEME.md CURLINFO_SIZE_DELIVERED.md CURLINFO_SIZE_DOWNLOAD.md CURLINFO_SIZE_DOWNLOAD_T.md CURLINFO_SIZE_UPLOAD.md CURLINFO_SIZE_UPLOAD_T.md CURLINFO_SPEED_DOWNLOAD.md CURLINFO_SPEED_DOWNLOAD_T.md CURLINFO_SPEED_UPLOAD.md CURLINFO_SPEED_UPLOAD_T.md CURLINFO_SSL_ENGINES.md CURLINFO_SSL_VERIFYRESULT.md CURLINFO_STARTTRANSFER_TIME.md CURLINFO_STARTTRANSFER_TIME_T.md CURLINFO_TLS_SESSION.md CURLINFO_TLS_SSL_PTR.md CURLINFO_TOTAL_TIME.md CURLINFO_TOTAL_TIME_T.md CURLINFO_USED_PROXY.md CURLINFO_XFER_ID.md CURLMINFO_XFERS_ADDED.md CURLMINFO_XFERS_CURRENT.md CURLMINFO_XFERS_DONE.md CURLMINFO_XFERS_PENDING.md CURLMINFO_XFERS_RUNNING.md CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.md CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.md CURLMOPT_MAXCONNECTS.md CURLMOPT_MAX_CONCURRENT_STREAMS.md CURLMOPT_MAX_HOST_CONNECTIONS.md CURLMOPT_MAX_PIPELINE_LENGTH.md CURLMOPT_MAX_TOTAL_CONNECTIONS.md CURLMOPT_NETWORK_CHANGED.md CURLMOPT_NOTIFYDATA.md CURLMOPT_NOTIFYFUNCTION.md CURLMOPT_PIPELINING.md CURLMOPT_PIPELINING_SERVER_BL.md CURLMOPT_PIPELINING_SITE_BL.md CURLMOPT_PUSHDATA.md CURLMOPT_PUSHFUNCTION.md CURLMOPT_QUICK_EXIT.md CURLMOPT_RESOLVE_THREADS_MAX.md CURLMOPT_SOCKETDATA.md CURLMOPT_SOCKETFUNCTION.md CURLMOPT_TIMERDATA.md CURLMOPT_TIMERFUNCTION.md CURLOPT_ABSTRACT_UNIX_SOCKET.md CURLOPT_ACCEPTTIMEOUT_MS.md CURLOPT_ACCEPT_ENCODING.md CURLOPT_ADDRESS_SCOPE.md CURLOPT_ALTSVC.md CURLOPT_ALTSVC_CTRL.md CURLOPT_APPEND.md CURLOPT_AUTOREFERER.md CURLOPT_AWS_SIGV4.md CURLOPT_BUFFERSIZE.md CURLOPT_CAINFO.md CURLOPT_CAINFO_BLOB.md CURLOPT_CAPATH.md CURLOPT_CA_CACHE_TIMEOUT.md CURLOPT_CERTINFO.md CURLOPT_CHUNK_BGN_FUNCTION.md CURLOPT_CHUNK_DATA.md CURLOPT_CHUNK_END_FUNCTION.md CURLOPT_CLOSESOCKETDATA.md CURLOPT_CLOSESOCKETFUNCTION.md CURLOPT_CONNECTTIMEOUT.md CURLOPT_CONNECTTIMEOUT_MS.md CURLOPT_CONNECT_ONLY.md CURLOPT_CONNECT_TO.md CURLOPT_CONV_FROM_NETWORK_FUNCTION.md CURLOPT_CONV_FROM_UTF8_FUNCTION.md CURLOPT_CONV_TO_NETWORK_FUNCTION.md CURLOPT_COOKIE.md CURLOPT_COOKIEFILE.md CURLOPT_COOKIEJAR.md CURLOPT_COOKIELIST.md CURLOPT_COOKIESESSION.md CURLOPT_COPYPOSTFIELDS.md CURLOPT_CRLF.md CURLOPT_CRLFILE.md CURLOPT_CURLU.md CURLOPT_CUSTOMREQUEST.md CURLOPT_DEBUGDATA.md CURLOPT_DEBUGFUNCTION.md CURLOPT_DEFAULT_PROTOCOL.md CURLOPT_DIRLISTONLY.md CURLOPT_DISALLOW_USERNAME_IN_URL.md CURLOPT_DNS_CACHE_TIMEOUT.md CURLOPT_DNS_INTERFACE.md CURLOPT_DNS_LOCAL_IP4.md CURLOPT_DNS_LOCAL_IP6.md CURLOPT_DNS_SERVERS.md CURLOPT_DNS_SHUFFLE_ADDRESSES.md CURLOPT_DNS_USE_GLOBAL_CACHE.md CURLOPT_DOH_SSL_VERIFYHOST.md CURLOPT_DOH_SSL_VERIFYPEER.md CURLOPT_DOH_SSL_VERIFYSTATUS.md CURLOPT_DOH_URL.md CURLOPT_ECH.md CURLOPT_EGDSOCKET.md CURLOPT_ERRORBUFFER.md CURLOPT_EXPECT_100_TIMEOUT_MS.md CURLOPT_FAILONERROR.md CURLOPT_FILETIME.md CURLOPT_FNMATCH_DATA.md CURLOPT_FNMATCH_FUNCTION.md CURLOPT_FOLLOWLOCATION.md CURLOPT_FORBID_REUSE.md CURLOPT_FRESH_CONNECT.md CURLOPT_FTPPORT.md CURLOPT_FTPSSLAUTH.md CURLOPT_FTP_ACCOUNT.md CURLOPT_FTP_ALTERNATIVE_TO_USER.md CURLOPT_FTP_CREATE_MISSING_DIRS.md CURLOPT_FTP_FILEMETHOD.md CURLOPT_FTP_SKIP_PASV_IP.md CURLOPT_FTP_SSL_CCC.md CURLOPT_FTP_USE_EPRT.md CURLOPT_FTP_USE_EPSV.md CURLOPT_FTP_USE_PRET.md CURLOPT_GSSAPI_DELEGATION.md CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.md CURLOPT_HAPROXYPROTOCOL.md CURLOPT_HAPROXY_CLIENT_IP.md CURLOPT_HEADER.md CURLOPT_HEADERDATA.md CURLOPT_HEADERFUNCTION.md CURLOPT_HEADEROPT.md CURLOPT_HSTS.md CURLOPT_HSTSREADDATA.md CURLOPT_HSTSREADFUNCTION.md CURLOPT_HSTSWRITEDATA.md CURLOPT_HSTSWRITEFUNCTION.md CURLOPT_HSTS_CTRL.md CURLOPT_HTTP09_ALLOWED.md CURLOPT_HTTP200ALIASES.md CURLOPT_HTTPAUTH.md CURLOPT_HTTPGET.md CURLOPT_HTTPHEADER.md CURLOPT_HTTPPOST.md CURLOPT_HTTPPROXYTUNNEL.md CURLOPT_HTTP_CONTENT_DECODING.md CURLOPT_HTTP_TRANSFER_DECODING.md CURLOPT_HTTP_VERSION.md CURLOPT_IGNORE_CONTENT_LENGTH.md CURLOPT_INFILESIZE.md CURLOPT_INFILESIZE_LARGE.md CURLOPT_INTERFACE.md CURLOPT_INTERLEAVEDATA.md CURLOPT_INTERLEAVEFUNCTION.md CURLOPT_IOCTLDATA.md CURLOPT_IOCTLFUNCTION.md CURLOPT_IPRESOLVE.md CURLOPT_ISSUERCERT.md CURLOPT_ISSUERCERT_BLOB.md CURLOPT_KEEP_SENDING_ON_ERROR.md CURLOPT_KEYPASSWD.md CURLOPT_KRBLEVEL.md CURLOPT_LOCALPORT.md CURLOPT_LOCALPORTRANGE.md CURLOPT_LOGIN_OPTIONS.md CURLOPT_LOW_SPEED_LIMIT.md CURLOPT_LOW_SPEED_TIME.md CURLOPT_MAIL_AUTH.md CURLOPT_MAIL_FROM.md CURLOPT_MAIL_RCPT.md CURLOPT_MAIL_RCPT_ALLOWFAILS.md CURLOPT_MAXAGE_CONN.md CURLOPT_MAXCONNECTS.md CURLOPT_MAXFILESIZE.md CURLOPT_MAXFILESIZE_LARGE.md CURLOPT_MAXLIFETIME_CONN.md CURLOPT_MAXREDIRS.md CURLOPT_MAX_RECV_SPEED_LARGE.md CURLOPT_MAX_SEND_SPEED_LARGE.md CURLOPT_MIMEPOST.md CURLOPT_MIME_OPTIONS.md CURLOPT_NETRC.md CURLOPT_NETRC_FILE.md CURLOPT_NEW_DIRECTORY_PERMS.md CURLOPT_NEW_FILE_PERMS.md CURLOPT_NOBODY.md CURLOPT_NOPROGRESS.md CURLOPT_NOPROXY.md CURLOPT_NOSIGNAL.md CURLOPT_OPENSOCKETDATA.md CURLOPT_OPENSOCKETFUNCTION.md CURLOPT_PASSWORD.md CURLOPT_PATH_AS_IS.md CURLOPT_PINNEDPUBLICKEY.md CURLOPT_PIPEWAIT.md CURLOPT_PORT.md CURLOPT_POST.md CURLOPT_POSTFIELDS.md CURLOPT_POSTFIELDSIZE.md CURLOPT_POSTFIELDSIZE_LARGE.md CURLOPT_POSTQUOTE.md CURLOPT_POSTREDIR.md CURLOPT_PREQUOTE.md CURLOPT_PREREQDATA.md CURLOPT_PREREQFUNCTION.md CURLOPT_PRE_PROXY.md CURLOPT_PRIVATE.md CURLOPT_PROGRESSDATA.md CURLOPT_PROGRESSFUNCTION.md CURLOPT_PROTOCOLS.md CURLOPT_PROTOCOLS_STR.md CURLOPT_PROXY.md CURLOPT_PROXYAUTH.md CURLOPT_PROXYHEADER.md CURLOPT_PROXYPASSWORD.md CURLOPT_PROXYPORT.md CURLOPT_PROXYTYPE.md CURLOPT_PROXYUSERNAME.md CURLOPT_PROXYUSERPWD.md CURLOPT_PROXY_CAINFO.md CURLOPT_PROXY_CAINFO_BLOB.md CURLOPT_PROXY_CAPATH.md CURLOPT_PROXY_CRLFILE.md CURLOPT_PROXY_ISSUERCERT.md CURLOPT_PROXY_ISSUERCERT_BLOB.md CURLOPT_PROXY_KEYPASSWD.md CURLOPT_PROXY_PINNEDPUBLICKEY.md CURLOPT_PROXY_SERVICE_NAME.md CURLOPT_PROXY_SSLCERT.md CURLOPT_PROXY_SSLCERTTYPE.md CURLOPT_PROXY_SSLCERT_BLOB.md CURLOPT_PROXY_SSLKEY.md CURLOPT_PROXY_SSLKEYTYPE.md CURLOPT_PROXY_SSLKEY_BLOB.md CURLOPT_PROXY_SSLVERSION.md CURLOPT_PROXY_SSL_CIPHER_LIST.md CURLOPT_PROXY_SSL_OPTIONS.md CURLOPT_PROXY_SSL_VERIFYHOST.md CURLOPT_PROXY_SSL_VERIFYPEER.md CURLOPT_PROXY_TLS13_CIPHERS.md CURLOPT_PROXY_TLSAUTH_PASSWORD.md CURLOPT_PROXY_TLSAUTH_TYPE.md CURLOPT_PROXY_TLSAUTH_USERNAME.md CURLOPT_PROXY_TRANSFER_MODE.md CURLOPT_PUT.md CURLOPT_QUICK_EXIT.md CURLOPT_QUOTE.md CURLOPT_RANDOM_FILE.md CURLOPT_RANGE.md CURLOPT_READDATA.md CURLOPT_READFUNCTION.md CURLOPT_REDIR_PROTOCOLS.md CURLOPT_REDIR_PROTOCOLS_STR.md CURLOPT_REFERER.md CURLOPT_REQUEST_TARGET.md CURLOPT_RESOLVE.md CURLOPT_RESOLVER_START_DATA.md CURLOPT_RESOLVER_START_FUNCTION.md CURLOPT_RESUME_FROM.md CURLOPT_RESUME_FROM_LARGE.md CURLOPT_RTSP_CLIENT_CSEQ.md CURLOPT_RTSP_REQUEST.md CURLOPT_RTSP_SERVER_CSEQ.md CURLOPT_RTSP_SESSION_ID.md CURLOPT_RTSP_STREAM_URI.md CURLOPT_RTSP_TRANSPORT.md CURLOPT_SASL_AUTHZID.md CURLOPT_SASL_IR.md CURLOPT_SEEKDATA.md CURLOPT_SEEKFUNCTION.md CURLOPT_SERVER_RESPONSE_TIMEOUT.md CURLOPT_SERVER_RESPONSE_TIMEOUT_MS.md CURLOPT_SERVICE_NAME.md CURLOPT_SHARE.md CURLOPT_SOCKOPTDATA.md CURLOPT_SOCKOPTFUNCTION.md CURLOPT_SOCKS5_AUTH.md CURLOPT_SOCKS5_GSSAPI_NEC.md CURLOPT_SOCKS5_GSSAPI_SERVICE.md CURLOPT_SSH_AUTH_TYPES.md CURLOPT_SSH_COMPRESSION.md CURLOPT_SSH_HOSTKEYDATA.md CURLOPT_SSH_HOSTKEYFUNCTION.md CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md CURLOPT_SSH_KEYDATA.md CURLOPT_SSH_KEYFUNCTION.md CURLOPT_SSH_KNOWNHOSTS.md CURLOPT_SSH_PRIVATE_KEYFILE.md CURLOPT_SSH_PUBLIC_KEYFILE.md CURLOPT_SSLCERT.md CURLOPT_SSLCERTTYPE.md CURLOPT_SSLCERT_BLOB.md CURLOPT_SSLENGINE.md CURLOPT_SSLENGINE_DEFAULT.md CURLOPT_SSLKEY.md CURLOPT_SSLKEYTYPE.md CURLOPT_SSLKEY_BLOB.md CURLOPT_SSLVERSION.md CURLOPT_SSL_CIPHER_LIST.md CURLOPT_SSL_CTX_DATA.md CURLOPT_SSL_CTX_FUNCTION.md CURLOPT_SSL_EC_CURVES.md CURLOPT_SSL_ENABLE_ALPN.md CURLOPT_SSL_ENABLE_NPN.md CURLOPT_SSL_FALSESTART.md CURLOPT_SSL_OPTIONS.md CURLOPT_SSL_SESSIONID_CACHE.md CURLOPT_SSL_SIGNATURE_ALGORITHMS.md CURLOPT_SSL_VERIFYHOST.md CURLOPT_SSL_VERIFYPEER.md CURLOPT_SSL_VERIFYSTATUS.md CURLOPT_STDERR.md CURLOPT_STREAM_DEPENDS.md CURLOPT_STREAM_DEPENDS_E.md CURLOPT_STREAM_WEIGHT.md CURLOPT_SUPPRESS_CONNECT_HEADERS.md CURLOPT_TCP_FASTOPEN.md CURLOPT_TCP_KEEPALIVE.md CURLOPT_TCP_KEEPCNT.md CURLOPT_TCP_KEEPIDLE.md CURLOPT_TCP_KEEPINTVL.md CURLOPT_TCP_NODELAY.md CURLOPT_TELNETOPTIONS.md CURLOPT_TFTP_BLKSIZE.md CURLOPT_TFTP_NO_OPTIONS.md CURLOPT_TIMECONDITION.md CURLOPT_TIMEOUT.md CURLOPT_TIMEOUT_MS.md CURLOPT_TIMEVALUE.md CURLOPT_TIMEVALUE_LARGE.md CURLOPT_TLS13_CIPHERS.md CURLOPT_TLSAUTH_PASSWORD.md CURLOPT_TLSAUTH_TYPE.md CURLOPT_TLSAUTH_USERNAME.md CURLOPT_TRAILERDATA.md CURLOPT_TRAILERFUNCTION.md CURLOPT_TRANSFERTEXT.md CURLOPT_TRANSFER_ENCODING.md CURLOPT_UNIX_SOCKET_PATH.md CURLOPT_UNRESTRICTED_AUTH.md CURLOPT_UPKEEP_INTERVAL_MS.md CURLOPT_UPLOAD.md CURLOPT_UPLOAD_BUFFERSIZE.md CURLOPT_UPLOAD_FLAGS.md CURLOPT_URL.md CURLOPT_USERAGENT.md CURLOPT_USERNAME.md CURLOPT_USERPWD.md CURLOPT_USE_SSL.md CURLOPT_VERBOSE.md CURLOPT_WILDCARDMATCH.md CURLOPT_WRITEDATA.md CURLOPT_WRITEFUNCTION.md CURLOPT_WS_OPTIONS.md CURLOPT_XFERINFODATA.md CURLOPT_XFERINFOFUNCTION.md CURLOPT_XOAUTH2_BEARER.md CURLSHOPT_LOCKFUNC.md CURLSHOPT_SHARE.md CURLSHOPT_UNLOCKFUNC.md CURLSHOPT_UNSHARE.md CURLSHOPT_USERDATA.md Makefile.am Makefile.incinclude
curl
Makefile.am curl.h curlver.h easy.h header.h mprintf.h multi.h options.h stdcheaders.h system.h typecheck-gcc.h urlapi.h websockets.hlib
curlx
base64.c base64.h basename.c basename.h dynbuf.c dynbuf.h fopen.c fopen.h inet_ntop.c inet_ntop.h inet_pton.c inet_pton.h multibyte.c multibyte.h nonblock.c nonblock.h snprintf.c snprintf.h strcopy.c strcopy.h strdup.c strdup.h strerr.c strerr.h strparse.c strparse.h timediff.c timediff.h timeval.c timeval.h version_win32.c version_win32.h wait.c wait.h warnless.c warnless.h winapi.c winapi.hvauth
cleartext.c cram.c digest.c digest.h digest_sspi.c gsasl.c krb5_gssapi.c krb5_sspi.c ntlm.c ntlm_sspi.c oauth2.c spnego_gssapi.c spnego_sspi.c vauth.c vauth.hvquic
curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.hvtls
apple.c apple.h cipher_suite.c cipher_suite.h gtls.c gtls.h hostcheck.c hostcheck.h keylog.c keylog.h mbedtls.c mbedtls.h openssl.c openssl.h rustls.c rustls.h schannel.c schannel.h schannel_int.h schannel_verify.c vtls.c vtls.h vtls_int.h vtls_scache.c vtls_scache.h vtls_spack.c vtls_spack.h wolfssl.c wolfssl.h x509asn1.c x509asn1.hm4
.gitignore curl-amissl.m4 curl-apple-sectrust.m4 curl-compilers.m4 curl-confopts.m4 curl-functions.m4 curl-gnutls.m4 curl-mbedtls.m4 curl-openssl.m4 curl-override.m4 curl-reentrant.m4 curl-rustls.m4 curl-schannel.m4 curl-sysconfig.m4 curl-wolfssl.m4 xc-am-iface.m4 xc-cc-check.m4 xc-lt-iface.m4 xc-val-flgs.m4 zz40-xc-ovr.m4 zz50-xc-ovr.m4projects
OS400
.checksrc README.OS400 ccsidcurl.c ccsidcurl.h config400.default curl.cmd curl.inc.in curlcl.c curlmain.c initscript.sh make-docs.sh make-include.sh make-lib.sh make-src.sh make-tests.sh makefile.sh os400sys.c os400sys.hWindows
tmpl
.gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filtersvms
Makefile.am backup_gnv_curl_src.com build_curl-config_script.com build_gnv_curl.com build_gnv_curl_pcsi_desc.com build_gnv_curl_pcsi_text.com build_gnv_curl_release_notes.com build_libcurl_pc.com build_vms.com clean_gnv_curl.com compare_curl_source.com config_h.com curl_crtl_init.c curl_gnv_build_steps.txt curl_release_note_start.txt curl_startup.com curlmsg.h curlmsg.msg curlmsg.sdl curlmsg_vms.h generate_config_vms_h_curl.com generate_vax_transfer.com gnv_conftest.c_first gnv_curl_configure.sh gnv_libcurl_symbols.opt gnv_link_curl.com macro32_exactcase.patch make_gnv_curl_install.sh make_pcsi_curl_kit_name.com pcsi_gnv_curl_file_list.txt pcsi_product_gnv_curl.com readme report_openssl_version.c setup_gnv_curl_build.com stage_curl_install.com vms_eco_level.hscripts
.checksrc CMakeLists.txt Makefile.am badwords badwords-all badwords.txt cd2cd cd2nroff cdall checksrc-all.pl checksrc.pl cmakelint.sh completion.pl contributors.sh contrithanks.sh coverage.sh delta dmaketgz extract-unit-protos firefox-db2pem.sh installcheck.sh maketgz managen mdlinkcheck mk-ca-bundle.pl mk-unity.pl nroff2cd perlcheck.sh pythonlint.sh randdisable release-notes.pl release-tools.sh schemetable.c singleuse.pl spacecheck.pl top-complexity top-length verify-release wcurlsrc
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc config2setopts.c config2setopts.h curl.rc curlinfo.c mk-file-embed.pl mkhelp.pl slist_wc.c slist_wc.h terminal.c terminal.h tool_cb_dbg.c tool_cb_dbg.h tool_cb_hdr.c tool_cb_hdr.h tool_cb_prg.c tool_cb_prg.h tool_cb_rea.c tool_cb_rea.h tool_cb_see.c tool_cb_see.h tool_cb_soc.c tool_cb_soc.h tool_cb_wrt.c tool_cb_wrt.h tool_cfgable.c tool_cfgable.h tool_dirhie.c tool_dirhie.h tool_doswin.c tool_doswin.h tool_easysrc.c tool_easysrc.h tool_filetime.c tool_filetime.h tool_findfile.c tool_findfile.h tool_formparse.c tool_formparse.h tool_getparam.c tool_getparam.h tool_getpass.c tool_getpass.h tool_help.c tool_help.h tool_helpers.c tool_helpers.h tool_hugehelp.h tool_ipfs.c tool_ipfs.h tool_libinfo.c tool_libinfo.h tool_listhelp.c tool_main.c tool_main.h tool_msgs.c tool_msgs.h tool_operate.c tool_operate.h tool_operhlp.c tool_operhlp.h tool_paramhlp.c tool_paramhlp.h tool_parsecfg.c tool_parsecfg.h tool_progress.c tool_progress.h tool_sdecls.h tool_setopt.c tool_setopt.h tool_setup.h tool_ssls.c tool_ssls.h tool_stderr.c tool_stderr.h tool_urlglob.c tool_urlglob.h tool_util.c tool_util.h tool_version.h tool_vms.c tool_vms.h tool_writeout.c tool_writeout.h tool_writeout_json.c tool_writeout_json.h tool_xattr.c tool_xattr.h var.c var.htests
certs
.gitignore CMakeLists.txt Makefile.am Makefile.inc genserv.pl srp-verifier-conf srp-verifier-db test-ca.cnf test-ca.prm test-client-cert.prm test-client-eku-only.prm test-localhost-san-first.prm test-localhost-san-last.prm test-localhost.nn.prm test-localhost.prm test-localhost0h.prmdata
.gitignore DISABLED Makefile.am data-xml1 data1400.c data1401.c data1402.c data1403.c data1404.c data1405.c data1406.c data1407.c data1420.c data1461.txt data1463.txt data1465.c data1481.c data1705-1.md data1705-2.md data1705-3.md data1705-4.md data1705-stdout.1 data1706-1.md data1706-2.md data1706-3.md data1706-4.md data1706-stdout.txt data320.html test1 test10 test100 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 test1008 test1009 test101 test1010 test1011 test1012 test1013 test1014 test1015 test1016 test1017 test1018 test1019 test102 test1020 test1021 test1022 test1023 test1024 test1025 test1026 test1027 test1028 test1029 test103 test1030 test1031 test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 test104 test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 test1048 test1049 test105 test1050 test1051 test1052 test1053 test1054 test1055 test1056 test1057 test1058 test1059 test106 test1060 test1061 test1062 test1063 test1064 test1065 test1066 test1067 test1068 test1069 test107 test1070 test1071 test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 test108 test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 test1088 test1089 test109 test1090 test1091 test1092 test1093 test1094 test1095 test1096 test1097 test1098 test1099 test11 test110 test1100 test1101 test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 test111 test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 test112 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 test1128 test1129 test113 test1130 test1131 test1132 test1133 test1134 test1135 test1136 test1137 test1138 test1139 test114 test1140 test1141 test1142 test1143 test1144 test1145 test1146 test1147 test1148 test1149 test115 test1150 test1151 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 test116 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 test1168 test1169 test117 test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 test1178 test1179 test118 test1180 test1181 test1182 test1183 test1184 test1185 test1186 test1187 test1188 test1189 test119 test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 test1199 test12 test120 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 test1208 test1209 test121 test1210 test1211 test1212 test1213 test1214 test1215 test1216 test1217 test1218 test1219 test122 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 test1228 test1229 test123 test1230 test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 test124 test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 test1248 test1249 test125 test1250 test1251 test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 test126 test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 test1268 test1269 test127 test1270 test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 test1279 test128 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 test1288 test1289 test129 test1290 test1291 test1292 test1293 test1294 test1295 test1296 test1297 test1298 test1299 test13 test130 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 test1309 test131 test1310 test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 test132 test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 test133 test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 test134 test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 test1348 test1349 test135 test1350 test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 test136 test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 test137 test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 test138 test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 test1388 test1389 test139 test1390 test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 test14 test140 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 test141 test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 test1418 test1419 test142 test1420 test1421 test1422 test1423 test1424 test1425 test1426 test1427 test1428 test1429 test143 test1430 test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 test144 test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 test145 test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 test146 test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 test1468 test1469 test147 test1470 test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 test1479 test148 test1480 test1481 test1482 test1483 test1484 test1485 test1486 test1487 test1488 test1489 test149 test1490 test1491 test1492 test1493 test1494 test1495 test1496 test1497 test1498 test1499 test15 test150 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 test1508 test1509 test151 test1510 test1511 test1512 test1513 test1514 test1515 test1516 test1517 test1518 test1519 test152 test1520 test1521 test1522 test1523 test1524 test1525 test1526 test1527 test1528 test1529 test153 test1530 test1531 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 test154 test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 test1548 test1549 test155 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 test1558 test1559 test156 test1560 test1561 test1562 test1563 test1564 test1565 test1566 test1567 test1568 test1569 test157 test1570 test1571 test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 test158 test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 test1589 test159 test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 test1598 test1599 test16 test160 test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 test1608 test1609 test161 test1610 test1611 test1612 test1613 test1614 test1615 test1616 test1617 test1618 test1619 test162 test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 test163 test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 test1638 test1639 test164 test1640 test1641 test1642 test1643 test1644 test1645 test165 test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 test1658 test1659 test166 test1660 test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 test1669 test167 test1670 test1671 test1672 test1673 test1674 test1675 test1676 test168 test1680 test1681 test1682 test1683 test1684 test1685 test169 test17 test170 test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 test1708 test1709 test171 test1710 test1711 test1712 test1713 test1714 test1715 test172 test1720 test1721 test173 test174 test175 test176 test177 test178 test179 test18 test180 test1800 test1801 test1802 test181 test182 test183 test184 test1847 test1848 test1849 test185 test1850 test1851 test186 test187 test188 test189 test19 test190 test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 test1908 test1909 test191 test1910 test1911 test1912 test1913 test1914 test1915 test1916 test1917 test1918 test1919 test192 test1920 test1921 test193 test1933 test1934 test1935 test1936 test1937 test1938 test1939 test194 test1940 test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 test195 test1955 test1956 test1957 test1958 test1959 test196 test1960 test1964 test1965 test1966 test197 test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 test1978 test1979 test198 test1980 test1981 test1982 test1983 test1984 test199 test2 test20 test200 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 test2008 test2009 test201 test2010 test2011 test2012 test2013 test2014 test202 test2023 test2024 test2025 test2026 test2027 test2028 test2029 test203 test2030 test2031 test2032 test2033 test2034 test2035 test2037 test2038 test2039 test204 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 test2048 test2049 test205 test2050 test2051 test2052 test2053 test2054 test2055 test2056 test2057 test2058 test2059 test206 test2060 test2061 test2062 test2063 test2064 test2065 test2066 test2067 test2068 test2069 test207 test2070 test2071 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 test208 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 test2088 test2089 test209 test2090 test2091 test2092 test21 test210 test2100 test2101 test2102 test2103 test2104 test211 test212 test213 test214 test215 test216 test217 test218 test219 test22 test220 test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 test221 test222 test223 test224 test225 test226 test227 test228 test229 test23 test230 test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 test2309 test231 test232 test233 test234 test235 test236 test237 test238 test239 test24 test240 test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 test2408 test2409 test241 test2410 test2411 test242 test243 test244 test245 test246 test247 test248 test249 test25 test250 test2500 test2501 test2502 test2503 test2504 test2505 test2506 test251 test252 test253 test254 test255 test256 test257 test258 test259 test26 test260 test2600 test2601 test2602 test2603 test2604 test2605 test261 test262 test263 test264 test265 test266 test267 test268 test269 test27 test270 test2700 test2701 test2702 test2703 test2704 test2705 test2706 test2707 test2708 test2709 test271 test2710 test2711 test2712 test2713 test2714 test2715 test2716 test2717 test2718 test2719 test272 test2720 test2721 test2722 test2723 test273 test274 test275 test276 test277 test278 test279 test28 test280 test281 test282 test283 test284 test285 test286 test287 test288 test289 test29 test290 test291 test292 test293 test294 test295 test296 test297 test298 test299 test3 test30 test300 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 test3008 test3009 test301 test3010 test3011 test3012 test3013 test3014 test3015 test3016 test3017 test3018 test3019 test302 test3020 test3021 test3022 test3023 test3024 test3025 test3026 test3027 test3028 test3029 test303 test3030 test3031 test3032 test3033 test3034 test3035 test3036 test304 test305 test306 test307 test308 test309 test31 test310 test3100 test3101 test3102 test3103 test3104 test3105 test3106 test311 test312 test313 test314 test315 test316 test317 test318 test319 test32 test320 test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 test3209 test321 test3210 test3211 test3212 test3213 test3214 test3215 test3216 test3217 test3218 test3219 test322 test3220 test323 test324 test325 test326 test327 test328 test329 test33 test330 test3300 test3301 test3302 test331 test332 test333 test334 test335 test336 test337 test338 test339 test34 test340 test341 test342 test343 test344 test345 test346 test347 test348 test349 test35 test350 test351 test352 test353 test354 test355 test356 test357 test358 test359 test36 test360 test361 test362 test363 test364 test365 test366 test367 test368 test369 test37 test370 test371 test372 test373 test374 test375 test376 test378 test379 test38 test380 test381 test383 test384 test385 test386 test387 test388 test389 test39 test390 test391 test392 test393 test394 test395 test396 test397 test398 test399 test4 test40 test400 test4000 test4001 test401 test402 test403 test404 test405 test406 test407 test408 test409 test41 test410 test411 test412 test413 test414 test415 test416 test417 test418 test419 test42 test420 test421 test422 test423 test424 test425 test426 test427 test428 test429 test43 test430 test431 test432 test433 test434 test435 test436 test437 test438 test439 test44 test440 test441 test442 test443 test444 test445 test446 test447 test448 test449 test45 test450 test451 test452 test453 test454 test455 test456 test457 test458 test459 test46 test460 test461 test462 test463 test467 test468 test469 test47 test470 test471 test472 test473 test474 test475 test476 test477 test478 test479 test48 test480 test481 test482 test483 test484 test485 test486 test487 test488 test489 test49 test490 test491 test492 test493 test494 test495 test496 test497 test498 test499 test5 test50 test500 test501 test502 test503 test504 test505 test506 test507 test508 test509 test51 test510 test511 test512 test513 test514 test515 test516 test517 test518 test519 test52 test520 test521 test522 test523 test524 test525 test526 test527 test528 test529 test53 test530 test531 test532 test533 test534 test535 test536 test537 test538 test539 test54 test540 test541 test542 test543 test544 test545 test546 test547 test548 test549 test55 test550 test551 test552 test553 test554 test555 test556 test557 test558 test559 test56 test560 test561 test562 test563 test564 test565 test566 test567 test568 test569 test57 test570 test571 test572 test573 test574 test575 test576 test577 test578 test579 test58 test580 test581 test582 test583 test584 test585 test586 test587 test588 test589 test59 test590 test591 test592 test593 test594 test595 test596 test597 test598 test599 test6 test60 test600 test601 test602 test603 test604 test605 test606 test607 test608 test609 test61 test610 test611 test612 test613 test614 test615 test616 test617 test618 test619 test62 test620 test621 test622 test623 test624 test625 test626 test627 test628 test629 test63 test630 test631 test632 test633 test634 test635 test636 test637 test638 test639 test64 test640 test641 test642 test643 test644 test645 test646 test647 test648 test649 test65 test650 test651 test652 test653 test654 test655 test656 test658 test659 test66 test660 test661 test662 test663 test664 test665 test666 test667 test668 test669 test67 test670 test671 test672 test673 test674 test675 test676 test677 test678 test679 test68 test680 test681 test682 test683 test684 test685 test686 test687 test688 test689 test69 test690 test691 test692 test693 test694 test695 test696 test697 test698 test699 test7 test70 test700 test701 test702 test703 test704 test705 test706 test707 test708 test709 test71 test710 test711 test712 test713 test714 test715 test716 test717 test718 test719 test72 test720 test721 test722 test723 test724 test725 test726 test727 test728 test729 test73 test730 test731 test732 test733 test734 test735 test736 test737 test738 test739 test74 test740 test741 test742 test743 test744 test745 test746 test747 test748 test749 test75 test750 test751 test752 test753 test754 test755 test756 test757 test758 test759 test76 test760 test761 test762 test763 test764 test765 test766 test767 test768 test769 test77 test770 test771 test772 test773 test774 test775 test776 test777 test778 test779 test78 test780 test781 test782 test783 test784 test785 test786 test787 test788 test789 test79 test790 test791 test792 test793 test794 test795 test796 test797 test798 test799 test8 test80 test800 test801 test802 test803 test804 test805 test806 test807 test808 test809 test81 test810 test811 test812 test813 test814 test815 test816 test817 test818 test819 test82 test820 test821 test822 test823 test824 test825 test826 test827 test828 test829 test83 test830 test831 test832 test833 test834 test835 test836 test837 test838 test839 test84 test840 test841 test842 test843 test844 test845 test846 test847 test848 test849 test85 test850 test851 test852 test853 test854 test855 test856 test857 test858 test859 test86 test860 test861 test862 test863 test864 test865 test866 test867 test868 test869 test87 test870 test871 test872 test873 test874 test875 test876 test877 test878 test879 test88 test880 test881 test882 test883 test884 test885 test886 test887 test888 test889 test89 test890 test891 test892 test893 test894 test895 test896 test897 test898 test899 test9 test90 test900 test901 test902 test903 test904 test905 test906 test907 test908 test909 test91 test910 test911 test912 test913 test914 test915 test916 test917 test918 test919 test92 test920 test921 test922 test923 test924 test925 test926 test927 test928 test929 test93 test930 test931 test932 test933 test934 test935 test936 test937 test938 test939 test94 test940 test941 test942 test943 test944 test945 test946 test947 test948 test949 test95 test950 test951 test952 test953 test954 test955 test956 test957 test958 test959 test96 test960 test961 test962 test963 test964 test965 test966 test967 test968 test969 test97 test970 test971 test972 test973 test974 test975 test976 test977 test978 test979 test98 test980 test981 test982 test983 test984 test985 test986 test987 test988 test989 test99 test990 test991 test992 test993 test994 test995 test996 test997 test998 test999http
testenv
__init__.py caddy.py certs.py client.py curl.py dante.py dnsd.py env.py httpd.py nghttpx.py ports.py sshd.py vsftpd.py ws_echo_server.pylibtest
.gitignore CMakeLists.txt Makefile.am Makefile.inc cli_ftp_upload.c cli_h2_pausing.c cli_h2_serverpush.c cli_h2_upgrade_extreme.c cli_hx_download.c cli_hx_upload.c cli_tls_session_reuse.c cli_upload_pausing.c cli_ws_data.c cli_ws_pingpong.c first.c first.h lib1156.c lib1301.c lib1308.c lib1485.c lib1500.c lib1501.c lib1502.c lib1506.c lib1507.c lib1508.c lib1509.c lib1510.c lib1511.c lib1512.c lib1513.c lib1514.c lib1515.c lib1517.c lib1518.c lib1520.c lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c lib1545.c lib1549.c lib1550.c lib1551.c lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c lib1559.c lib1560.c lib1564.c lib1565.c lib1567.c lib1568.c lib1569.c lib1571.c lib1576.c lib1582.c lib1587.c lib1588.c lib1589.c lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c lib1598.c lib1599.c lib1662.c lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c lib1933.c lib1934.c lib1935.c lib1936.c lib1937.c lib1938.c lib1939.c lib1940.c lib1945.c lib1947.c lib1948.c lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c lib1964.c lib1965.c lib1970.c lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c lib2023.c lib2032.c lib2082.c lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c lib2402.c lib2404.c lib2405.c lib2502.c lib2504.c lib2505.c lib2506.c lib2700.c lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c lib3207.c lib3208.c lib500.c lib501.c lib502.c lib503.c lib504.c lib505.c lib506.c lib507.c lib508.c lib509.c lib510.c lib511.c lib512.c lib513.c lib514.c lib515.c lib516.c lib517.c lib518.c lib519.c lib520.c lib521.c lib523.c lib524.c lib525.c lib526.c lib530.c lib533.c lib536.c lib537.c lib539.c lib540.c lib541.c lib542.c lib543.c lib544.c lib547.c lib549.c lib552.c lib553.c lib554.c lib555.c lib556.c lib557.c lib558.c lib559.c lib560.c lib562.c lib564.c lib566.c lib567.c lib568.c lib569.c lib570.c lib571.c lib572.c lib573.c lib574.c lib575.c lib576.c lib578.c lib579.c lib582.c lib583.c lib586.c lib589.c lib590.c lib591.c lib597.c lib598.c lib599.c lib643.c lib650.c lib651.c lib652.c lib653.c lib654.c lib655.c lib658.c lib659.c lib661.c lib666.c lib667.c lib668.c lib670.c lib674.c lib676.c lib677.c lib678.c lib694.c lib695.c lib751.c lib753.c lib757.c lib758.c lib766.c memptr.c mk-lib1521.pl test1013.pl test1022.pl test307.pl test610.pl test613.pl testtrace.c testtrace.h testutil.c testutil.h unitcheck.hserver
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc dnsd.c first.c first.h getpart.c mqttd.c resolve.c rtspd.c sockfilt.c socksd.c sws.c tftpd.c util.ctunit
.gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.cunit
.gitignore CMakeLists.txt Makefile.am Makefile.inc README.md unit1300.c unit1302.c unit1303.c unit1304.c unit1305.c unit1307.c unit1309.c unit1323.c unit1330.c unit1395.c unit1396.c unit1397.c unit1398.c unit1399.c unit1600.c unit1601.c unit1602.c unit1603.c unit1605.c unit1606.c unit1607.c unit1608.c unit1609.c unit1610.c unit1611.c unit1612.c unit1614.c unit1615.c unit1616.c unit1620.c unit1625.c unit1626.c unit1627.c unit1636.c unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c unit1666.c unit1667.c unit1668.c unit1669.c unit1674.c unit1675.c unit1676.c unit1979.c unit1980.c unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c unit3200.c unit3205.c unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c unit3219.c unit3300.c unit3301.c unit3302.cexamples
.env config.ini crypto_test.lua env_test.lua fs_example.lua http_server.lua https_test.lua ini_example.lua json.lua log.lua path_fs_example.lua process_example.lua request_download.lua request_test.lua run_all.lua sqlite_example.lua sqlite_http_template.lua stash_test.lua template_test.lua timer.lua websocket.luainiparser
example
iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.initest
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.hjinjac
libjinjac
src
CMakeLists.txt ast.c ast.h block_statement.c block_statement.h buffer.c buffer.h buildin.c buildin.h common.h convert.c convert.h flex_decl.h jfunction.c jfunction.h jinja_expression.l jinja_expression.y jinjac_parse.c jinjac_parse.h jinjac_stream.c jinjac_stream.h jlist.c jlist.h jobject.c jobject.h parameter.c parameter.h str_obj.c str_obj.h trace.c trace.htest
.gitignore CMakeLists.txt autotest.rb test_01.expected test_01.jinja test_01b.expected test_01b.jinja test_01c.expected test_01c.jinja test_01d.expected test_01d.jinja test_02.expected test_02.jinja test_03.expected test_03.jinja test_04.expected test_04.jinja test_05.expected test_05.jinja test_06.expected test_06.jinja test_07.expected test_07.jinja test_08.expected test_08.jinja test_08b.expected test_08b.jinja test_09.expected test_09.jinja test_10.expected test_10.jinja test_11.expected test_11.jinja test_12.expected test_12.jinja test_13.expected test_13.jinja test_14.expected test_14.jinja test_15.expected test_15.jinja test_16.expected test_16.jinja test_17.expected test_17.jinja test_18.expected test_18.jinja test_18b.expected test_18b.jinja test_18c.expected test_18c.jinja test_19.expected test_19.jinja test_19b.expected test_19b.jinja test_19c.expected test_19c.jinja test_19d.expected test_19d.jinja test_19e.expected test_19e.jinja test_19f.expected test_19f.jinja test_20.expected test_20.jinja test_21.expected test_21.jinja test_22.expected test_22.jinja test_22a.expected test_22a.jinja test_22b.expected test_22b.jinja test_23.expected test_23.jinja test_24.expected test_24.jinjalibev
Changes LICENSE Makefile Makefile.am Makefile.in README Symbols.ev Symbols.event aclocal.m4 autogen.sh compile config.guess config.h config.h.in config.status config.sub configure configure.ac depcomp ev++.h ev.3 ev.c ev.h ev.pod ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_vars.h ev_win32.c ev_wrap.h event.c event.h install-sh libev.m4 libtool ltmain.sh missing mkinstalldirs stamp-h1luajit
doc
bluequad-print.css bluequad.css contact.html ext_buffer.html ext_c_api.html ext_ffi.html ext_ffi_api.html ext_ffi_semantics.html ext_ffi_tutorial.html ext_jit.html ext_profiler.html extensions.html install.html luajit.html running.htmldynasm
dasm_arm.h dasm_arm.lua dasm_arm64.h dasm_arm64.lua dasm_mips.h dasm_mips.lua dasm_mips64.lua dasm_ppc.h dasm_ppc.lua dasm_proto.h dasm_x64.lua dasm_x86.h dasm_x86.lua dynasm.luasrc
host
.gitignore README buildvm.c buildvm.h buildvm_asm.c buildvm_fold.c buildvm_lib.c buildvm_libbc.h buildvm_peobj.c genlibbc.lua genminilua.lua genversion.lua minilua.cjit
.gitignore bc.lua bcsave.lua dis_arm.lua dis_arm64.lua dis_arm64be.lua dis_mips.lua dis_mips64.lua dis_mips64el.lua dis_mips64r6.lua dis_mips64r6el.lua dis_mipsel.lua dis_ppc.lua dis_x64.lua dis_x86.lua dump.lua p.lua v.lua zone.luawolfssl
.github
workflows
ada.yml arduino.yml async-examples.yml async.yml atecc608-sim.yml bind.yml cmake-autoconf.yml cmake.yml codespell.yml coverity-scan-fixes.yml cryptocb-only.yml curl.yml cyrus-sasl.yml disable-pk-algs.yml docker-Espressif.yml docker-OpenWrt.yml emnet-nonblock.yml fil-c.yml freertos-mem-track.yml gencertbuf.yml grpc.yml haproxy.yml hostap-vm.yml intelasm-c-fallback.yml ipmitool.yml jwt-cpp.yml krb5.yml libspdm.yml libssh2.yml libvncserver.yml linuxkm.yml macos-apple-native-cert-validation.yml mbedtls.sh mbedtls.yml membrowse-comment.yml membrowse-onboard.yml membrowse-report.yml memcached.sh memcached.yml mono.yml mosquitto.yml msmtp.yml msys2.yml multi-arch.yml multi-compiler.yml net-snmp.yml nginx.yml no-malloc.yml no-tls.yml nss.sh nss.yml ntp.yml ocsp.yml openldap.yml openssh.yml openssl-ech.yml opensslcoexist.yml openvpn.yml os-check.yml packaging.yml pam-ipmi.yml pq-all.yml pr-commit-check.yml psk.yml puf.yml python.yml rng-tools.yml rust-wrapper.yml se050-sim.yml smallStackSize.yml socat.yml softhsm.yml sssd.yml stm32-sim.yml stsafe-a120-sim.yml stunnel.yml symbol-prefixes.yml threadx.yml tls-anvil.yml trackmemory.yml watcomc.yml win-csharp-test.yml wolfCrypt-Wconversion.yml wolfboot-integration.yml wolfsm.yml xcode.yml zephyr-4.x.yml zephyr.ymlIDE
ARDUINO
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.hECLIPSE
Espressif
ESP-IDF
examples
template
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266wolfssl_benchmark
VisualGDB
wolfssl_benchmark_IDF_v4.4_ESP32.sln wolfssl_benchmark_IDF_v4.4_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32.sln wolfssl_benchmark_IDF_v5_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32C3.sln wolfssl_benchmark_IDF_v5_ESP32C3.vgdbproj wolfssl_benchmark_IDF_v5_ESP32S3.sln wolfssl_benchmark_IDF_v5_ESP32S3.vgdbprojwolfssl_client
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbprojwolfssl_server
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbprojwolfssl_test
VisualGDB
wolfssl_test-IDF_v5_ESP32.sln wolfssl_test-IDF_v5_ESP32.vgdbproj wolfssl_test-IDF_v5_ESP32C3.sln wolfssl_test-IDF_v5_ESP32C3.vgdbproj wolfssl_test-IDF_v5_ESP32C6.sln wolfssl_test-IDF_v5_ESP32C6.vgdbproj wolfssl_test_IDF_v5_ESP32S3.sln wolfssl_test_IDF_v5_ESP32S3.vgdbprojGCC-ARM
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ldIAR-EWARM
embOS
SAMV71_XULT
embOS_SAMV71_XULT_user_settings
user_settings.h user_settings_simple_example.h user_settings_verbose_example.hembOS_wolfcrypt_benchmark_SAMV71_XULT
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewpINTIME-RTOS
Makefile README.md include.am libwolfssl.c libwolfssl.vcxproj user_settings.h wolfExamples.c wolfExamples.h wolfExamples.sln wolfExamples.vcxproj wolfssl-lib.sln wolfssl-lib.vcxprojMQX
Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.hMSVS-2019-AZSPHERE
wolfssl_new_azsphere
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.cNETOS
Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.cPlatformIO
examples
wolfssl_benchmark
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspaceROWLEY-CROSSWORKS-ARM
Kinetis_FlashPlacement.xml README.md arm_startup.c benchmark_main.c hw.h include.am kinetis_hw.c retarget.c test_main.c user_settings.h wolfssl.hzp wolfssl_ltc.hzpRenesas
e2studio
RA6M3
README.md README_APRA6M_en.md README_APRA6M_jp.md include.amRX72N
EnvisionKit
Simple
README_EN.md README_JP.mdwolfssl_demo
key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.cSTM32Cube
README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.hWIN
README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxprojWIN-SRTP-KDF-140-3
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojWIN10
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojXCODE
Benchmark
include.amXilinxSDK
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.capple-universal
wolfssl-multiplatform
iotsafe
Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.hmynewt
README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.shcerts
1024
ca-cert.der ca-cert.pem ca-key.der ca-key.pem client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der dh1024.der dh1024.pem dsa-pub-1024.pem dsa1024.der dsa1024.pem include.am rsa1024.der server-cert.der server-cert.pem server-key.der server-key.pemcrl
extra-crls
ca-int-cert-revoked.pem claim-root.pem crl_critical_entry.pem crlnum_57oct.pem crlnum_64oct.pem general-server-crl.pem large_crlnum.pem large_crlnum2.pemdilithium
bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.amecc
bp256r1-key.der bp256r1-key.pem ca-secp256k1-cert.pem ca-secp256k1-key.pem client-bp256r1-cert.der client-bp256r1-cert.pem client-secp256k1-cert.der client-secp256k1-cert.pem genecc.sh include.am secp256k1-key.der secp256k1-key.pem secp256k1-param.pem secp256k1-privkey.der secp256k1-privkey.pem server-bp256r1-cert.der server-bp256r1-cert.pem server-secp256k1-cert.der server-secp256k1-cert.pem server2-secp256k1-cert.der server2-secp256k1-cert.pem wolfssl.cnf wolfssl_384.cnfed25519
ca-ed25519-key.der ca-ed25519-key.pem ca-ed25519-priv.der ca-ed25519-priv.pem ca-ed25519.der ca-ed25519.pem client-ed25519-key.der client-ed25519-key.pem client-ed25519-priv.der client-ed25519-priv.pem client-ed25519.der client-ed25519.pem eddsa-ed25519.der eddsa-ed25519.pem gen-ed25519-certs.sh gen-ed25519-keys.sh gen-ed25519.sh include.am root-ed25519-key.der root-ed25519-key.pem root-ed25519-priv.der root-ed25519-priv.pem root-ed25519.der root-ed25519.pem server-ed25519-cert.pem server-ed25519-key.der server-ed25519-key.pem server-ed25519-priv.der server-ed25519-priv.pem server-ed25519.der server-ed25519.pemed448
ca-ed448-key.der ca-ed448-key.pem ca-ed448-priv.der ca-ed448-priv.pem ca-ed448.der ca-ed448.pem client-ed448-key.der client-ed448-key.pem client-ed448-priv.der client-ed448-priv.pem client-ed448.der client-ed448.pem gen-ed448-certs.sh gen-ed448-keys.sh include.am root-ed448-key.der root-ed448-key.pem root-ed448-priv.der root-ed448-priv.pem root-ed448.der root-ed448.pem server-ed448-cert.pem server-ed448-key.der server-ed448-key.pem server-ed448-priv.der server-ed448-priv.pem server-ed448.der server-ed448.pemexternal
DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.amintermediate
ca_false_intermediate
gentestcert.sh int_ca.key server.key test_ca.key test_ca.pem test_int_not_cacert.pem test_sign_bynoca_srv.pem wolfssl_base.conf wolfssl_srv.conflms
bc_hss_L2_H5_W8_root.der bc_hss_L3_H5_W4_root.der bc_lms_chain_ca.der bc_lms_chain_leaf.der bc_lms_native_bc_root.der bc_lms_sha256_h10_w8_root.der bc_lms_sha256_h5_w4_root.der include.ammldsa
README.txt include.am mldsa44-cert.der mldsa44-cert.pem mldsa44-key.pem mldsa44_bare-priv.der mldsa44_bare-seed.der mldsa44_oqskeypair.der mldsa44_priv-only.der mldsa44_pub-spki.der mldsa44_seed-only.der mldsa44_seed-priv.der mldsa65-cert.der mldsa65-cert.pem mldsa65-key.pem mldsa65_bare-priv.der mldsa65_bare-seed.der mldsa65_oqskeypair.der mldsa65_priv-only.der mldsa65_pub-spki.der mldsa65_seed-only.der mldsa65_seed-priv.der mldsa87-cert.der mldsa87-cert.pem mldsa87-key.pem mldsa87_bare-priv.der mldsa87_bare-seed.der mldsa87_oqskeypair.der mldsa87_priv-only.der mldsa87_pub-spki.der mldsa87_seed-only.der mldsa87_seed-priv.derocsp
imposter-root-ca-cert.der imposter-root-ca-cert.pem imposter-root-ca-key.der imposter-root-ca-key.pem include.am index-ca-and-intermediate-cas.txt index-ca-and-intermediate-cas.txt.attr index-intermediate1-ca-issued-certs.txt index-intermediate1-ca-issued-certs.txt.attr index-intermediate2-ca-issued-certs.txt index-intermediate2-ca-issued-certs.txt.attr index-intermediate3-ca-issued-certs.txt index-intermediate3-ca-issued-certs.txt.attr intermediate1-ca-cert.der intermediate1-ca-cert.pem intermediate1-ca-key.der intermediate1-ca-key.pem intermediate2-ca-cert.der intermediate2-ca-cert.pem intermediate2-ca-key.der intermediate2-ca-key.pem intermediate3-ca-cert.der intermediate3-ca-cert.pem intermediate3-ca-key.der intermediate3-ca-key.pem ocsp-responder-cert.der ocsp-responder-cert.pem ocsp-responder-key.der ocsp-responder-key.pem openssl.cnf renewcerts-for-test.sh renewcerts.sh root-ca-cert.der root-ca-cert.pem root-ca-crl.pem root-ca-key.der root-ca-key.pem server1-cert.der server1-cert.pem server1-chain-noroot.pem server1-key.der server1-key.pem server2-cert.der server2-cert.pem server2-key.der server2-key.pem server3-cert.der server3-cert.pem server3-key.der server3-key.pem server4-cert.der server4-cert.pem server4-key.der server4-key.pem server5-cert.der server5-cert.pem server5-key.der server5-key.pem test-leaf-response.der test-multi-response.der test-response-nointern.der test-response-rsapss.der test-response.derp521
ca-p521-key.der ca-p521-key.pem ca-p521-priv.der ca-p521-priv.pem ca-p521.der ca-p521.pem client-p521-key.der client-p521-key.pem client-p521-priv.der client-p521-priv.pem client-p521.der client-p521.pem gen-p521-certs.sh gen-p521-keys.sh include.am root-p521-key.der root-p521-key.pem root-p521-priv.der root-p521-priv.pem root-p521.der root-p521.pem server-p521-cert.pem server-p521-key.der server-p521-key.pem server-p521-priv.der server-p521-priv.pem server-p521.der server-p521.pemrpk
client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.derrsapss
ca-3072-rsapss-key.der ca-3072-rsapss-key.pem ca-3072-rsapss-priv.der ca-3072-rsapss-priv.pem ca-3072-rsapss.der ca-3072-rsapss.pem ca-rsapss-key.der ca-rsapss-key.pem ca-rsapss-priv.der ca-rsapss-priv.pem ca-rsapss.der ca-rsapss.pem client-3072-rsapss-key.der client-3072-rsapss-key.pem client-3072-rsapss-priv.der client-3072-rsapss-priv.pem client-3072-rsapss.der client-3072-rsapss.pem client-rsapss-key.der client-rsapss-key.pem client-rsapss-priv.der client-rsapss-priv.pem client-rsapss.der client-rsapss.pem gen-rsapss-keys.sh include.am renew-rsapss-certs.sh root-3072-rsapss-key.der root-3072-rsapss-key.pem root-3072-rsapss-priv.der root-3072-rsapss-priv.pem root-3072-rsapss.der root-3072-rsapss.pem root-rsapss-key.der root-rsapss-key.pem root-rsapss-priv.der root-rsapss-priv.pem root-rsapss.der root-rsapss.pem server-3072-rsapss-cert.pem server-3072-rsapss-key.der server-3072-rsapss-key.pem server-3072-rsapss-priv.der server-3072-rsapss-priv.pem server-3072-rsapss.der server-3072-rsapss.pem server-mix-rsapss-cert.pem server-rsapss-cert.pem server-rsapss-key.der server-rsapss-key.pem server-rsapss-priv.der server-rsapss-priv.pem server-rsapss.der server-rsapss.pemslhdsa
bench_slhdsa_sha2_128f_key.der bench_slhdsa_sha2_128s_key.der bench_slhdsa_sha2_192f_key.der bench_slhdsa_sha2_192s_key.der bench_slhdsa_sha2_256f_key.der bench_slhdsa_sha2_256s_key.der bench_slhdsa_shake128f_key.der bench_slhdsa_shake128s_key.der bench_slhdsa_shake192f_key.der bench_slhdsa_shake192s_key.der bench_slhdsa_shake256f_key.der bench_slhdsa_shake256s_key.der client-mldsa44-priv.pem client-mldsa44-sha2.der client-mldsa44-sha2.pem client-mldsa44-shake.der client-mldsa44-shake.pem gen-slhdsa-mldsa-certs.sh include.am root-slhdsa-sha2-128s-priv.der root-slhdsa-sha2-128s-priv.pem root-slhdsa-sha2-128s.der root-slhdsa-sha2-128s.pem root-slhdsa-shake-128s-priv.der root-slhdsa-shake-128s-priv.pem root-slhdsa-shake-128s.der root-slhdsa-shake-128s.pem server-mldsa44-priv.pem server-mldsa44-sha2.der server-mldsa44-sha2.pem server-mldsa44-shake.der server-mldsa44-shake.pemsm2
ca-sm2-key.der ca-sm2-key.pem ca-sm2-priv.der ca-sm2-priv.pem ca-sm2.der ca-sm2.pem client-sm2-key.der client-sm2-key.pem client-sm2-priv.der client-sm2-priv.pem client-sm2.der client-sm2.pem fix_sm2_spki.py gen-sm2-certs.sh gen-sm2-keys.sh include.am root-sm2-key.der root-sm2-key.pem root-sm2-priv.der root-sm2-priv.pem root-sm2.der root-sm2.pem self-sm2-cert.pem self-sm2-key.pem self-sm2-priv.pem server-sm2-cert.der server-sm2-cert.pem server-sm2-key.der server-sm2-key.pem server-sm2-priv.der server-sm2-priv.pem server-sm2.der server-sm2.pemstatickeys
dh-ffdhe2048-params.pem dh-ffdhe2048-pub.der dh-ffdhe2048-pub.pem dh-ffdhe2048.der dh-ffdhe2048.pem ecc-secp256r1.der ecc-secp256r1.pem gen-static.sh include.am x25519-pub.der x25519-pub.pem x25519.der x25519.pemtest
catalog.txt cert-bad-neg-int.der cert-bad-oid.der cert-bad-utf8.der cert-ext-ia.cfg cert-ext-ia.der cert-ext-ia.pem cert-ext-joi.cfg cert-ext-joi.der cert-ext-joi.pem cert-ext-mnc.der cert-ext-multiple.cfg cert-ext-multiple.der cert-ext-multiple.pem cert-ext-nc-combined.der cert-ext-nc-combined.pem cert-ext-nc.cfg cert-ext-nc.der cert-ext-nc.pem cert-ext-ncdns.der cert-ext-ncdns.pem cert-ext-ncip.der cert-ext-ncip.pem cert-ext-ncmixed.der cert-ext-ncmulti.der cert-ext-ncmulti.pem cert-ext-ncrid.der cert-ext-ncrid.pem cert-ext-nct.cfg cert-ext-nct.der cert-ext-nct.pem cert-ext-ndir-exc.cfg cert-ext-ndir-exc.der cert-ext-ndir-exc.pem cert-ext-ndir.cfg cert-ext-ndir.der cert-ext-ndir.pem cert-ext-ns.der cert-over-max-altnames.cfg cert-over-max-altnames.der cert-over-max-altnames.pem cert-over-max-nc.cfg cert-over-max-nc.der cert-over-max-nc.pem client-ecc-cert-ski.hex cn-ip-literal.der cn-ip-wildcard.der crit-cert.pem crit-key.pem dh1024.der dh1024.pem dh512.der dh512.pem digsigku.pem encrypteddata.msg gen-badsig.sh gen-ext-certs.sh gen-testcerts.sh include.am kari-keyid-cms.msg ktri-keyid-cms.msg ossl-trusted-cert.pem server-badaltname.der server-badaltname.pem server-badaltnull.der server-badaltnull.pem server-badcn.der server-badcn.pem server-badcnnull.der server-badcnnull.pem server-cert-ecc-badsig.der server-cert-ecc-badsig.pem server-cert-rsa-badsig.der server-cert-rsa-badsig.pem server-duplicate-policy.pem server-garbage.der server-garbage.pem server-goodalt.der server-goodalt.pem server-goodaltwild.der server-goodaltwild.pem server-goodcn.der server-goodcn.pem server-goodcnwild.der server-goodcnwild.pem server-localhost.der server-localhost.pem smime-test-canon.p7s smime-test-multipart-badsig.p7s smime-test-multipart.p7s smime-test.p7stest-pathlen
assemble-chains.sh chainA-ICA1-key.pem chainA-ICA1-pathlen0.pem chainA-assembled.pem chainA-entity-key.pem chainA-entity.pem chainB-ICA1-key.pem chainB-ICA1-pathlen0.pem chainB-ICA2-key.pem chainB-ICA2-pathlen1.pem chainB-assembled.pem chainB-entity-key.pem chainB-entity.pem chainC-ICA1-key.pem chainC-ICA1-pathlen1.pem chainC-assembled.pem chainC-entity-key.pem chainC-entity.pem chainD-ICA1-key.pem chainD-ICA1-pathlen127.pem chainD-assembled.pem chainD-entity-key.pem chainD-entity.pem chainE-ICA1-key.pem chainE-ICA1-pathlen128.pem chainE-assembled.pem chainE-entity-key.pem chainE-entity.pem chainF-ICA1-key.pem chainF-ICA1-pathlen1.pem chainF-ICA2-key.pem chainF-ICA2-pathlen0.pem chainF-assembled.pem chainF-entity-key.pem chainF-entity.pem chainG-ICA1-key.pem chainG-ICA1-pathlen0.pem chainG-ICA2-key.pem chainG-ICA2-pathlen1.pem chainG-ICA3-key.pem chainG-ICA3-pathlen99.pem chainG-ICA4-key.pem chainG-ICA4-pathlen5.pem chainG-ICA5-key.pem chainG-ICA5-pathlen20.pem chainG-ICA6-key.pem chainG-ICA6-pathlen10.pem chainG-ICA7-key.pem chainG-ICA7-pathlen100.pem chainG-assembled.pem chainG-entity-key.pem chainG-entity.pem chainH-ICA1-key.pem chainH-ICA1-pathlen0.pem chainH-ICA2-key.pem chainH-ICA2-pathlen2.pem chainH-ICA3-key.pem chainH-ICA3-pathlen2.pem chainH-ICA4-key.pem chainH-ICA4-pathlen2.pem chainH-assembled.pem chainH-entity-key.pem chainH-entity.pem chainI-ICA1-key.pem chainI-ICA1-no_pathlen.pem chainI-ICA2-key.pem chainI-ICA2-no_pathlen.pem chainI-ICA3-key.pem chainI-ICA3-pathlen2.pem chainI-assembled.pem chainI-entity-key.pem chainI-entity.pem chainJ-ICA1-key.pem chainJ-ICA1-no_pathlen.pem chainJ-ICA2-key.pem chainJ-ICA2-no_pathlen.pem chainJ-ICA3-key.pem chainJ-ICA3-no_pathlen.pem chainJ-ICA4-key.pem chainJ-ICA4-pathlen2.pem chainJ-assembled.pem chainJ-entity-key.pem chainJ-entity.pem include.am refreshkeys.shtest-serial0
ee_normal.pem ee_serial0.pem generate_certs.sh include.am intermediate_serial0.pem root_serial0.pem root_serial0_key.pem selfsigned_nonca_serial0.pemxmss
bc_xmss_chain_ca.der bc_xmss_chain_leaf.der bc_xmss_sha2_10_256_root.der bc_xmss_sha2_16_256_root.der bc_xmssmt_sha2_20_2_256_root.der bc_xmssmt_sha2_20_4_256_root.der bc_xmssmt_sha2_40_8_256_root.der include.amcmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.indebian
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.indoc
dox_comments
header_files
aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h puf.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wc_she.h wc_slhdsa.h wolfio.hheader_files-ja
aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wolfio.hexamples
async
Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.hconfigs
README.md include.am user_settings_EBSnet.h user_settings_all.h user_settings_arduino.h user_settings_baremetal.h user_settings_ca.h user_settings_curve25519nonblock.h user_settings_dtls13.h user_settings_eccnonblock.h user_settings_espressif.h user_settings_fipsv2.h user_settings_fipsv5.h user_settings_min_ecc.h user_settings_openssl_compat.h user_settings_pkcs7.h user_settings_platformio.h user_settings_pq.h user_settings_rsa_only.h user_settings_stm32.h user_settings_template.h user_settings_tls12.h user_settings_tls13.h user_settings_wolfboot_keytools.h user_settings_wolfssh.h user_settings_wolftpm.hechoclient
echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quitlinuxkm
Kbuild Makefile README.md get_thread_size.c include.am linuxkm-fips-hash-wrapper.sh linuxkm-fips-hash.c linuxkm_memory.c linuxkm_memory.h linuxkm_wc_port.h lkcapi_aes_glue.c lkcapi_dh_glue.c lkcapi_ecdh_glue.c lkcapi_ecdsa_glue.c lkcapi_glue.c lkcapi_rsa_glue.c lkcapi_sha_glue.c module_exports.c.template module_hooks.c pie_redirect_table.c wolfcrypt.lds x86_vector_register_glue.cm4
ax_add_am_macro.m4 ax_am_jobserver.m4 ax_am_macros.m4 ax_append_compile_flags.m4 ax_append_flag.m4 ax_append_link_flags.m4 ax_append_to_file.m4 ax_atomic.m4 ax_bsdkm.m4 ax_check_compile_flag.m4 ax_check_link_flag.m4 ax_compiler_version.m4 ax_count_cpus.m4 ax_create_generic_config.m4 ax_debug.m4 ax_file_escapes.m4 ax_harden_compiler_flags.m4 ax_linuxkm.m4 ax_print_to_file.m4 ax_pthread.m4 ax_require_defined.m4 ax_tls.m4 ax_vcs_checkout.m4 hexversion.m4 lib_socket_nsl.m4 visibility.m4mqx
wolfcrypt_benchmark
ReferencedRSESystems.xml wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchwolfcrypt_test
ReferencedRSESystems.xml wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchwolfssl_client
ReferencedRSESystems.xml wolfssl_client_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchscripts
aria-cmake-build-test.sh asn1_oid_sum.pl benchmark.test benchmark_compare.sh cleanup_testfiles.sh crl-gen-openssl.test crl-revoked.test dertoc.pl dtls.test dtlscid.test external.test google.test include.am makedistsmall.sh memtest.sh ocsp-responder-openssl-interop.test ocsp-stapling-with-ca-as-responder.test ocsp-stapling-with-wolfssl-responder.test ocsp-stapling.test ocsp-stapling2.test ocsp-stapling_tls13multi.test ocsp.test openssl.test openssl_srtp.test pem.test ping.test pkcallbacks.test psk.test resume.test rsapss.test sniffer-gen.sh sniffer-ipv6.pcap sniffer-static-rsa.pcap sniffer-testsuite.test sniffer-tls12-keylog.out sniffer-tls12-keylog.pcap sniffer-tls12-keylog.sslkeylog sniffer-tls13-dh-resume.pcap sniffer-tls13-dh.pcap sniffer-tls13-ecc-resume.pcap sniffer-tls13-ecc.pcap sniffer-tls13-hrr.pcap sniffer-tls13-keylog.out sniffer-tls13-keylog.pcap sniffer-tls13-keylog.sslkeylog sniffer-tls13-x25519-resume.pcap sniffer-tls13-x25519.pcap stm32l4-v4_0_1_build.sh tls13.test trusted_peer.test unit.test.in user_settings_asm.shsrc
bio.c conf.c crl.c dtls.c dtls13.c include.am internal.c keys.c ocsp.c pk.c pk_ec.c pk_rsa.c quic.c sniffer.c ssl.c ssl_api_cert.c ssl_api_crl_ocsp.c ssl_api_pk.c ssl_asn1.c ssl_bn.c ssl_certman.c ssl_crypto.c ssl_ech.c ssl_load.c ssl_misc.c ssl_p7p12.c ssl_sess.c ssl_sk.c tls.c tls13.c wolfio.c x509.c x509_str.ctests
api
api.h api_decl.h create_ocsp_test_blobs.py include.am test_aes.c test_aes.h test_arc4.c test_arc4.h test_ascon.c test_ascon.h test_ascon_kats.h test_asn.c test_asn.h test_blake2.c test_blake2.h test_camellia.c test_camellia.h test_certman.c test_certman.h test_chacha.c test_chacha.h test_chacha20_poly1305.c test_chacha20_poly1305.h test_cmac.c test_cmac.h test_curve25519.c test_curve25519.h test_curve448.c test_curve448.h test_des3.c test_des3.h test_dh.c test_dh.h test_digest.h test_dsa.c test_dsa.h test_dtls.c test_dtls.h test_ecc.c test_ecc.h test_ed25519.c test_ed25519.h test_ed448.c test_ed448.h test_evp.c test_evp.h test_evp_cipher.c test_evp_cipher.h test_evp_digest.c test_evp_digest.h test_evp_pkey.c test_evp_pkey.h test_hash.c test_hash.h test_hmac.c test_hmac.h test_md2.c test_md2.h test_md4.c test_md4.h test_md5.c test_md5.h test_mldsa.c test_mldsa.h test_mlkem.c test_mlkem.h test_ocsp.c test_ocsp.h test_ocsp_test_blobs.h test_ossl_asn1.c test_ossl_asn1.h test_ossl_bio.c test_ossl_bio.h test_ossl_bn.c test_ossl_bn.h test_ossl_cipher.c test_ossl_cipher.h test_ossl_dgst.c test_ossl_dgst.h test_ossl_dh.c test_ossl_dh.h test_ossl_dsa.c test_ossl_dsa.h test_ossl_ec.c test_ossl_ec.h test_ossl_ecx.c test_ossl_ecx.h test_ossl_mac.c test_ossl_mac.h test_ossl_obj.c test_ossl_obj.h test_ossl_p7p12.c test_ossl_p7p12.h test_ossl_pem.c test_ossl_pem.h test_ossl_rand.c test_ossl_rand.h test_ossl_rsa.c test_ossl_rsa.h test_ossl_sk.c test_ossl_sk.h test_ossl_x509.c test_ossl_x509.h test_ossl_x509_acert.c test_ossl_x509_acert.h test_ossl_x509_crypto.c test_ossl_x509_crypto.h test_ossl_x509_ext.c test_ossl_x509_ext.h test_ossl_x509_info.c test_ossl_x509_info.h test_ossl_x509_io.c test_ossl_x509_io.h test_ossl_x509_lu.c test_ossl_x509_lu.h test_ossl_x509_name.c test_ossl_x509_name.h test_ossl_x509_pk.c test_ossl_x509_pk.h test_ossl_x509_str.c test_ossl_x509_str.h test_ossl_x509_vp.c test_ossl_x509_vp.h test_pkcs12.c test_pkcs12.h test_pkcs7.c test_pkcs7.h test_poly1305.c test_poly1305.h test_random.c test_random.h test_rc2.c test_rc2.h test_ripemd.c test_ripemd.h test_rsa.c test_rsa.h test_sha.c test_sha.h test_sha256.c test_sha256.h test_sha3.c test_sha3.h test_sha512.c test_sha512.h test_she.c test_she.h test_signature.c test_signature.h test_slhdsa.c test_slhdsa.h test_sm2.c test_sm2.h test_sm3.c test_sm3.h test_sm4.c test_sm4.h test_tls.c test_tls.h test_tls13.c test_tls13.h test_tls_ext.c test_tls_ext.h test_wc_encrypt.c test_wc_encrypt.h test_wolfmath.c test_wolfmath.h test_x509.c test_x509.hwolfcrypt
benchmark
README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.amsrc
port
Espressif
esp_crt_bundle
README.md cacrt_all.pem cacrt_deprecated.pem cacrt_local.pem esp_crt_bundle.c gen_crt_bundle.py pio_install_cryptography.pyRenesas
README.md renesas_common.c renesas_fspsm_aes.c renesas_fspsm_rsa.c renesas_fspsm_sha.c renesas_fspsm_util.c renesas_rx64_hw_sha.c renesas_rx64_hw_util.c renesas_tsip_aes.c renesas_tsip_rsa.c renesas_tsip_sha.c renesas_tsip_util.carm
armv8-32-aes-asm.S armv8-32-aes-asm_c.c armv8-32-chacha-asm.S armv8-32-chacha-asm_c.c armv8-32-curve25519.S armv8-32-curve25519_c.c armv8-32-mlkem-asm.S armv8-32-mlkem-asm_c.c armv8-32-poly1305-asm.S armv8-32-poly1305-asm_c.c armv8-32-sha256-asm.S armv8-32-sha256-asm_c.c armv8-32-sha3-asm.S armv8-32-sha3-asm_c.c armv8-32-sha512-asm.S armv8-32-sha512-asm_c.c armv8-aes-asm.S armv8-aes-asm_c.c armv8-aes.c armv8-chacha-asm.S armv8-chacha-asm_c.c armv8-curve25519.S armv8-curve25519_c.c armv8-mlkem-asm.S armv8-mlkem-asm_c.c armv8-poly1305-asm.S armv8-poly1305-asm_c.c armv8-sha256-asm.S armv8-sha256-asm_c.c armv8-sha256.c armv8-sha3-asm.S armv8-sha3-asm_c.c armv8-sha512-asm.S armv8-sha512-asm_c.c armv8-sha512.c cryptoCell.c cryptoCellHash.c thumb2-aes-asm.S thumb2-aes-asm_c.c thumb2-chacha-asm.S thumb2-chacha-asm_c.c thumb2-curve25519.S thumb2-curve25519_c.c thumb2-mlkem-asm.S thumb2-mlkem-asm_c.c thumb2-poly1305-asm.S thumb2-poly1305-asm_c.c thumb2-sha256-asm.S thumb2-sha256-asm_c.c thumb2-sha3-asm.S thumb2-sha3-asm_c.c thumb2-sha512-asm.S thumb2-sha512-asm_c.ccaam
README.md caam_aes.c caam_doc.pdf caam_driver.c caam_error.c caam_integrity.c caam_qnx.c caam_sha.c wolfcaam_aes.c wolfcaam_cmac.c wolfcaam_ecdsa.c wolfcaam_fsl_nxp.c wolfcaam_hash.c wolfcaam_hmac.c wolfcaam_init.c wolfcaam_qnx.c wolfcaam_rsa.c wolfcaam_seco.c wolfcaam_x25519.cdevcrypto
README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.criscv
riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.cwolfssl
openssl
aes.h asn1.h asn1t.h bio.h bn.h buffer.h camellia.h cmac.h cms.h compat_types.h conf.h crypto.h des.h dh.h dsa.h ec.h ec25519.h ec448.h ecdh.h ecdsa.h ed25519.h ed448.h engine.h err.h evp.h fips_rand.h hmac.h include.am kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pkcs12.h pkcs7.h rand.h rc4.h ripemd.h rsa.h safestack.h sha.h sha3.h srp.h ssl.h ssl23.h stack.h tls1.h txt_db.h ui.h x509.h x509_vfy.h x509v3.hwolfcrypt
port
Renesas
renesas-fspsm-crypt.h renesas-fspsm-types.h renesas-rx64-hw-crypt.h renesas-tsip-crypt.h renesas_cmn.h renesas_fspsm_internal.h renesas_sync.h renesas_tsip_internal.h renesas_tsip_types.hcaam
caam_driver.h caam_error.h caam_qnx.h wolfcaam.h wolfcaam_aes.h wolfcaam_cmac.h wolfcaam_ecdsa.h wolfcaam_fsl_nxp.h wolfcaam_hash.h wolfcaam_qnx.h wolfcaam_rsa.h wolfcaam_seco.h wolfcaam_sha.h wolfcaam_x25519.hwrapper
Ada
examples
src
aes_verify_main.adb rsa_verify_main.adb sha256_main.adb spark_sockets.adb spark_sockets.ads spark_terminal.adb spark_terminal.ads tls_client.adb tls_client.ads tls_client_main.adb tls_server.adb tls_server.ads tls_server_main.adbtests
src
aes_bindings_tests.adb aes_bindings_tests.ads rsa_verify_bindings_tests.adb rsa_verify_bindings_tests.ads sha256_bindings_tests.adb sha256_bindings_tests.ads tests.adbCSharp
wolfSSL-Example-IOCallbacks
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csprojwolfSSL-TLS-ServerThreaded
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csprojrust
wolfssl-wolfcrypt
src
aes.rs blake2.rs chacha20_poly1305.rs cmac.rs cmac_mac.rs curve25519.rs dh.rs dilithium.rs ecc.rs ecdsa.rs ed25519.rs ed448.rs fips.rs hkdf.rs hmac.rs hmac_mac.rs kdf.rs lib.rs lms.rs mlkem.rs mlkem_kem.rs pbkdf2_password_hash.rs prf.rs random.rs rsa.rs rsa_pkcs1v15.rs sha.rs sha_digest.rs sys.rstests
test_aes.rs test_blake2.rs test_chacha20_poly1305.rs test_cmac.rs test_cmac_mac.rs test_curve25519.rs test_dh.rs test_dilithium.rs test_ecc.rs test_ecdsa.rs test_ed25519.rs test_ed448.rs test_hkdf.rs test_hmac.rs test_hmac_mac.rs test_kdf.rs test_lms.rs test_mlkem.rs test_mlkem_kem.rs test_pbkdf2_password_hash.rs test_prf.rs test_random.rs test_rsa.rs test_rsa_pkcs1v15.rs test_sha.rs test_sha_digest.rs test_wolfcrypt.rszephyr
samples
wolfssl_benchmark
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.confwolfssl_test
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl/src/tls.c
raw
1/* tls.c
2 *
3 * Copyright (C) 2006-2026 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22/*
23 * TLS Build Options:
24 * (See tls13.c for TLS 1.3-specific options)
25 *
26 * Protocol Control:
27 * NO_OLD_TLS: Disable TLS 1.0 and 1.1 default: off
28 * WOLFSSL_ALLOW_TLSV10: Allow TLS 1.0 connections default: off
29 * WOLFSSL_NO_TLS12: Disable TLS 1.2 default: off
30 * NO_TLS: Disable TLS entirely (SSL only) default: off
31 * WOLFSSL_DTLS: Enable DTLS support default: off
32 * WOLFSSL_DTLS13: Enable DTLS 1.3 support default: off
33 * WOLFSSL_DTLS_CID: Enable DTLS Connection ID default: off
34 * WOLFSSL_AEAD_ONLY: Only allow AEAD cipher suites default: off
35 * NO_WOLFSSL_CLIENT: Disable TLS client functionality default: off
36 * NO_WOLFSSL_SERVER: Disable TLS server functionality default: off
37 * WOLFSSL_EITHER_SIDE: Allow same context for client/server default: off
38 * HAVE_TLS_EXTENSIONS: Enable TLS extension support default: on
39 * HAVE_SNI: Server Name Indication extension default: off
40 * WOLFSSL_ALWAYS_KEEP_SNI: Keep SNI after handshake default: off
41 * HAVE_MAX_FRAGMENT: Max Fragment Length extension default: off
42 * HAVE_TRUNCATED_HMAC: Truncated HMAC extension default: off
43 * HAVE_SUPPORTED_CURVES: Supported Curves extension default: on
44 * HAVE_EXTENDED_MASTER: Extended Master Secret (RFC 7627) default: on
45 * HAVE_ENCRYPT_THEN_MAC: Encrypt-Then-MAC extension default: on
46 * HAVE_ALPN: Application-Layer Protocol Negotiation default: off
47 * HAVE_CERTIFICATE_STATUS_REQUEST: OCSP stapling default: off
48 * HAVE_CERTIFICATE_STATUS_REQUEST_V2: OCSP stapling v2 default: off
49 * HAVE_SECURE_RENEGOTIATION: Secure renegotiation support default: off
50 * HAVE_SERVER_RENEGOTIATION_INFO: Server renegotiation info default: off
51 * HAVE_SESSION_TICKET: Session ticket support default: off
52 * HAVE_TRUSTED_CA: Trusted CA Indication extension default: off
53 * HAVE_RPK: Raw Public Key support (RFC 7250) default: off
54 * HAVE_ECH: Encrypted Client Hello support default: off
55 * WOLFSSL_NO_SIGALG: Disable signature algorithms ext default: off
56 * WOLFSSL_NO_CA_NAMES: Disable CA Names in CertificateReq default: off
57 * WOLFSSL_NO_SERVER_GROUPS_EXT: Don't send server groups ext default: off
58 * NO_TLSX_PSKKEM_PLAIN_ANNOUNCE: Disable plain PSK announce default: off
59 * WOLFSSL_OLD_UNSUPPORTED_EXTENSION: Old unsupported ext handling default: off
60 * WOLFSSL_ALLOW_SERVER_SC_EXT: Allow server supported curves ext default: off
61 *
62 * Pre-Shared Keys:
63 * NO_PSK: Disable PSK cipher suites default: off
64 *
65 * Key Exchange:
66 * HAVE_FFDHE: Enable Finite Field DH ephemeral default: off
67 * HAVE_FFDHE_2048: Enable FFDHE 2048-bit group default: off
68 * HAVE_FFDHE_3072: Enable FFDHE 3072-bit group default: off
69 * HAVE_FFDHE_4096: Enable FFDHE 4096-bit group default: off
70 * HAVE_FFDHE_6144: Enable FFDHE 6144-bit group default: off
71 * HAVE_FFDHE_8192: Enable FFDHE 8192-bit group default: off
72 * HAVE_PUBLIC_FFDHE: Use public FFDHE parameters only default: off
73 * WOLFSSL_OLD_PRIME_CHECK: Use old DH prime checking method default: off
74 * WOLFSSL_STATIC_DH: Enable static DH cipher suites default: off
75 * WOLFSSL_STATIC_EPHEMERAL: Enable static ephemeral key loading default: off
76 *
77 * Post-Quantum:
78 * WOLFSSL_HAVE_MLKEM: Enable ML-KEM (Kyber) support default: off
79 * WOLFSSL_MLKEM_KYBER: Use Kyber round 3 parameters default: off
80 * WOLFSSL_KYBER512: Enable Kyber/ML-KEM-512 default: off
81 * WOLFSSL_KYBER768: Enable Kyber/ML-KEM-768 default: off
82 * WOLFSSL_KYBER1024: Enable Kyber/ML-KEM-1024 default: off
83 * WOLFSSL_NO_ML_KEM: Disable all ML-KEM support default: off
84 * WOLFSSL_NO_ML_KEM_512: Disable ML-KEM-512 default: off
85 * WOLFSSL_NO_ML_KEM_768: Disable ML-KEM-768 default: off
86 * WOLFSSL_NO_ML_KEM_1024: Disable ML-KEM-1024 default: off
87 * WOLFSSL_ML_KEM_USE_OLD_IDS: Use old IANA IDs for ML-KEM default: off
88 * WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ: Store ML-KEM object in ext default: off
89 * WOLFSSL_TLSX_PQC_MLKEM_STORE_PRIV_KEY: Store ML-KEM priv key default: off
90 * WOLFSSL_MLKEM_CACHE_A: Cache ML-KEM A matrix default: off
91 * WOLFSSL_MLKEM_NO_MAKE_KEY: Disable ML-KEM key generation default: off
92 * WOLFSSL_MLKEM_NO_ENCAPSULATE: Disable ML-KEM encapsulation default: off
93 * WOLFSSL_MLKEM_NO_DECAPSULATE: Disable ML-KEM decapsulation default: off
94 * HAVE_LIBOQS: Use liboqs for PQ algorithms default: off
95 *
96 * Curves:
97 * HAVE_SECRET_CALLBACK: Enable TLS secret callback default: off
98 * HAVE_PK_CALLBACKS: Enable public key callbacks default: off
99 * HAVE_FUZZER: Enable fuzzing callback support default: off
100 *
101 * Features:
102 * WOLFSSL_SNIFFER: Enable TLS packet sniffing support default: off
103 * WOLFSSL_SNIFFER_KEYLOGFILE: Sniffer keylog file support default: off
104 * WOLFSSL_SSLKEYLOGFILE: Enable SSL key log file output default: off
105 * WOLFSSL_SRTP: Enable SRTP extension support default: off
106 * WOLFSSL_DUAL_ALG_CERTS: Enable dual algorithm certificates default: off
107 * WOLFSSL_HAVE_PRF: Enable TLS PRF function access default: off
108 * WOLFSSL_DEBUG_TLS: Debug TLS protocol messages default: off
109 * WOLFSSL_32BIT_MILLI_TIME: 32-bit millisecond time function default: off
110 * WOLFSSL_REQUIRE_TCA: Require Trusted CA extension default: off
111 * WOLFSSL_DH_EXTRA: Extra DH key info in SSL object default: off
112 * WOLFSSL_CURVE25519_BLINDING: Curve25519 blinding in TLS default: off
113 * HAVE_NULL_CIPHER: Allow NULL cipher suites default: off
114 * HAVE_WEBSERVER: Enable web server features default: off
115 * NO_CERTS: Disable certificate processing default: off
116 */
117
118#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
119
120#ifndef WOLFCRYPT_ONLY
121
122#include <wolfssl/ssl.h>
123#include <wolfssl/internal.h>
124#include <wolfssl/error-ssl.h>
125#include <wolfssl/wolfcrypt/hash.h>
126#include <wolfssl/wolfcrypt/hmac.h>
127#include <wolfssl/wolfcrypt/kdf.h>
128#ifdef NO_INLINE
129 #include <wolfssl/wolfcrypt/misc.h>
130#else
131 #define WOLFSSL_MISC_INCLUDED
132 #include <wolfcrypt/src/misc.c>
133#endif
134
135#ifdef HAVE_CURVE25519
136 #include <wolfssl/wolfcrypt/curve25519.h>
137#endif
138#ifdef HAVE_CURVE448
139 #include <wolfssl/wolfcrypt/curve448.h>
140#endif
141#ifdef WOLFSSL_HAVE_MLKEM
142 #include <wolfssl/wolfcrypt/wc_mlkem.h>
143#endif
144
145#if defined(WOLFSSL_RENESAS_TSIP_TLS)
146 #include <wolfssl/wolfcrypt/port/Renesas/renesas_tsip_internal.h>
147#endif
148
149#include <wolfssl/wolfcrypt/hpke.h>
150
151#ifndef NO_TLS
152
153#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
154static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap);
155#endif
156
157#ifdef HAVE_SUPPORTED_CURVES
158static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions);
159#endif
160
161/* Digest enable checks */
162#ifdef NO_OLD_TLS /* TLS 1.2 only */
163 #if defined(NO_SHA256) && !defined(WOLFSSL_SHA384) && \
164 !defined(WOLFSSL_SHA512)
165 #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
166 #endif
167#else /* TLS 1.1 or older */
168 #if defined(NO_MD5) && defined(NO_SHA)
169 #error Must have SHA1 and MD5 enabled for old TLS
170 #endif
171#endif
172
173#ifdef WOLFSSL_TLS13
174 #if !defined(NO_DH) && \
175 !defined(HAVE_FFDHE_2048) && !defined(HAVE_FFDHE_3072) && \
176 !defined(HAVE_FFDHE_4096) && !defined(HAVE_FFDHE_6144) && \
177 !defined(HAVE_FFDHE_8192)
178 #error Please configure your TLS 1.3 DH key size using either: HAVE_FFDHE_2048, HAVE_FFDHE_3072, HAVE_FFDHE_4096, HAVE_FFDHE_6144 or HAVE_FFDHE_8192
179 #endif
180 #if !defined(NO_RSA) && !defined(WC_RSA_PSS)
181 #error The build option WC_RSA_PSS is required for TLS 1.3 with RSA
182 #endif
183 #ifndef HAVE_TLS_EXTENSIONS
184 #if !defined(_MSC_VER) && !defined(__TASKING__)
185 #error "The build option HAVE_TLS_EXTENSIONS is required for TLS 1.3"
186 #else
187 #pragma message("Error: The build option HAVE_TLS_EXTENSIONS is required for TLS 1.3")
188 #endif
189 #endif
190#endif
191
192/* Warn if secrets logging is enabled */
193#if (defined(SHOW_SECRETS) || defined(WOLFSSL_SSLKEYLOGFILE)) && \
194 !defined(WOLFSSL_KEYLOG_EXPORT_WARNED)
195 #if !defined(_MSC_VER) && !defined(__TASKING__)
196 #warning The SHOW_SECRETS and WOLFSSL_SSLKEYLOGFILE options should only be used for debugging and never in a production environment
197 #else
198 #pragma message("Warning: The SHOW_SECRETS and WOLFSSL_SSLKEYLOGFILE options should only be used for debugging and never in a production environment")
199 #endif
200#endif
201
202#ifndef WOLFSSL_NO_TLS12
203
204#ifdef WOLFSSL_SHA384
205 #define HSHASH_SZ WC_SHA384_DIGEST_SIZE
206#else
207 #define HSHASH_SZ FINISHED_SZ
208#endif
209
210int BuildTlsHandshakeHash(WOLFSSL* ssl, byte* hash, word32* hashLen)
211{
212 int ret = 0;
213 word32 hashSz = FINISHED_SZ;
214
215 if (ssl == NULL || hash == NULL || hashLen == NULL || *hashLen < HSHASH_SZ)
216 return BAD_FUNC_ARG;
217
218 /* for constant timing perform these even if error */
219#ifndef NO_OLD_TLS
220 ret |= wc_Md5GetHash(&ssl->hsHashes->hashMd5, hash);
221 ret |= wc_ShaGetHash(&ssl->hsHashes->hashSha, &hash[WC_MD5_DIGEST_SIZE]);
222#endif
223
224 if (IsAtLeastTLSv1_2(ssl)) {
225#ifndef NO_SHA256
226 if (ssl->specs.mac_algorithm <= sha256_mac ||
227 ssl->specs.mac_algorithm == blake2b_mac) {
228 ret |= wc_Sha256GetHash(&ssl->hsHashes->hashSha256, hash);
229 hashSz = WC_SHA256_DIGEST_SIZE;
230 }
231#endif
232#ifdef WOLFSSL_SHA384
233 if (ssl->specs.mac_algorithm == sha384_mac) {
234 ret |= wc_Sha384GetHash(&ssl->hsHashes->hashSha384, hash);
235 hashSz = WC_SHA384_DIGEST_SIZE;
236 }
237#endif
238#ifdef WOLFSSL_SM3
239 if (ssl->specs.mac_algorithm == sm3_mac) {
240 ret |= wc_Sm3GetHash(&ssl->hsHashes->hashSm3, hash);
241 hashSz = WC_SM3_DIGEST_SIZE;
242 }
243#endif
244 }
245
246 *hashLen = hashSz;
247#ifdef WOLFSSL_CHECK_MEM_ZERO
248 wc_MemZero_Add("TLS handshake hash", hash, hashSz);
249#endif
250
251 if (ret != 0) {
252 ret = BUILD_MSG_ERROR;
253 WOLFSSL_ERROR_VERBOSE(ret);
254 }
255
256 return ret;
257}
258
259
260int BuildTlsFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
261{
262 int ret;
263 const byte* side = NULL;
264 word32 hashSz = HSHASH_SZ;
265#if !defined(WOLFSSL_ASYNC_CRYPT) || defined(WC_ASYNC_NO_HASH)
266 byte handshake_hash[HSHASH_SZ];
267#else
268 byte* handshake_hash = NULL;
269 handshake_hash = (byte*)XMALLOC(HSHASH_SZ, ssl->heap, DYNAMIC_TYPE_DIGEST);
270 if (handshake_hash == NULL)
271 return MEMORY_E;
272#endif
273
274 XMEMSET(handshake_hash, 0, HSHASH_SZ);
275 ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
276 if (ret == 0) {
277 if (XSTRNCMP((const char*)sender, (const char*)kTlsClientStr,
278 SIZEOF_SENDER) == 0) {
279 side = kTlsClientFinStr;
280 }
281 else if (XSTRNCMP((const char*)sender, (const char*)kTlsServerStr,
282 SIZEOF_SENDER) == 0) {
283 side = kTlsServerFinStr;
284 }
285 else {
286 ret = BAD_FUNC_ARG;
287 WOLFSSL_MSG("Unexpected sender value");
288 }
289 }
290
291 if (ret == 0) {
292#ifdef WOLFSSL_HAVE_PRF
293#if !defined(NO_CERTS) && defined(HAVE_PK_CALLBACKS)
294 if (ssl->ctx->TlsFinishedCb) {
295 void* ctx = wolfSSL_GetTlsFinishedCtx(ssl);
296 ret = ssl->ctx->TlsFinishedCb(ssl, side, handshake_hash, hashSz,
297 (byte*)hashes, ctx);
298 }
299 if (!ssl->ctx->TlsFinishedCb ||
300 ret == WC_NO_ERR_TRACE(PROTOCOLCB_UNAVAILABLE))
301#endif
302 {
303 PRIVATE_KEY_UNLOCK();
304 ret = wc_PRF_TLS((byte*)hashes, TLS_FINISHED_SZ,
305 ssl->arrays->masterSecret, SECRET_LEN, side,
306 FINISHED_LABEL_SZ, handshake_hash, hashSz,
307 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
308 ssl->heap, ssl->devId);
309 PRIVATE_KEY_LOCK();
310 }
311 ForceZero(handshake_hash, hashSz);
312#else
313 /* Pseudo random function must be enabled in the configuration. */
314 ret = PRF_MISSING;
315 WOLFSSL_ERROR_VERBOSE(ret);
316 WOLFSSL_MSG("Pseudo-random function is not enabled");
317
318 (void)side;
319 (void)hashes;
320#endif
321 }
322
323#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
324 XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST);
325#elif defined(WOLFSSL_CHECK_MEM_ZERO)
326 wc_MemZero_Check(handshake_hash, HSHASH_SZ);
327#endif
328
329 return ret;
330}
331
332#endif /* !WOLFSSL_NO_TLS12 */
333
334#ifndef NO_OLD_TLS
335
336#ifdef WOLFSSL_ALLOW_TLSV10
337ProtocolVersion MakeTLSv1(void)
338{
339 ProtocolVersion pv;
340 pv.major = SSLv3_MAJOR;
341 pv.minor = TLSv1_MINOR;
342
343 return pv;
344}
345#endif /* WOLFSSL_ALLOW_TLSV10 */
346
347
348ProtocolVersion MakeTLSv1_1(void)
349{
350 ProtocolVersion pv;
351 pv.major = SSLv3_MAJOR;
352 pv.minor = TLSv1_1_MINOR;
353
354 return pv;
355}
356
357#endif /* !NO_OLD_TLS */
358
359
360#ifndef WOLFSSL_NO_TLS12
361
362ProtocolVersion MakeTLSv1_2(void)
363{
364 ProtocolVersion pv;
365 pv.major = SSLv3_MAJOR;
366 pv.minor = TLSv1_2_MINOR;
367
368 return pv;
369}
370
371#endif /* !WOLFSSL_NO_TLS12 */
372
373#ifdef WOLFSSL_TLS13
374/* The TLS v1.3 protocol version.
375 *
376 * returns the protocol version data for TLS v1.3.
377 */
378ProtocolVersion MakeTLSv1_3(void)
379{
380 ProtocolVersion pv;
381 pv.major = SSLv3_MAJOR;
382 pv.minor = TLSv1_3_MINOR;
383
384 return pv;
385}
386#endif
387
388#if defined(HAVE_SUPPORTED_CURVES)
389/* Sets the key exchange groups in rank order on a context.
390 *
391 * ctx SSL/TLS context object.
392 * groups Array of groups.
393 * count Number of groups in array.
394 * returns BAD_FUNC_ARG when ctx or groups is NULL, not using TLS v1.3 or
395 * count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
396 */
397int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count)
398{
399 int ret, i;
400
401 WOLFSSL_ENTER("wolfSSL_CTX_set_groups");
402 if (ctx == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
403 return BAD_FUNC_ARG;
404 if (!IsTLS_ex(ctx->method->version))
405 return BAD_FUNC_ARG;
406
407 #ifdef WOLFSSL_TLS13
408 ctx->numGroups = 0;
409 #endif
410 #if !defined(NO_TLS)
411 TLSX_Remove(&ctx->extensions, TLSX_SUPPORTED_GROUPS, ctx->heap);
412 #endif /* !NO_TLS */
413 for (i = 0; i < count; i++) {
414 /* Call to wolfSSL_CTX_UseSupportedCurve also checks if input groups
415 * are valid */
416 if ((ret = wolfSSL_CTX_UseSupportedCurve(ctx, (word16)groups[i]))
417 != WOLFSSL_SUCCESS) {
418 #if !defined(NO_TLS)
419 TLSX_Remove(&ctx->extensions, TLSX_SUPPORTED_GROUPS, ctx->heap);
420 #endif /* !NO_TLS */
421 return ret;
422 }
423 #ifdef WOLFSSL_TLS13
424 ctx->group[i] = (word16)groups[i];
425 #endif
426 }
427 #ifdef WOLFSSL_TLS13
428 ctx->numGroups = (byte)count;
429 #endif
430
431 return WOLFSSL_SUCCESS;
432}
433
434/* Sets the key exchange groups in rank order.
435 *
436 * ssl SSL/TLS object.
437 * groups Array of groups.
438 * count Number of groups in array.
439 * returns BAD_FUNC_ARG when ssl or groups is NULL, not using TLS v1.3 or
440 * count is greater than WOLFSSL_MAX_GROUP_COUNT and WOLFSSL_SUCCESS on success.
441 */
442int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count)
443{
444 int ret, i;
445
446 WOLFSSL_ENTER("wolfSSL_set_groups");
447 if (ssl == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
448 return BAD_FUNC_ARG;
449 if (!IsTLS_ex(ssl->version))
450 return BAD_FUNC_ARG;
451
452 #ifdef WOLFSSL_TLS13
453 ssl->numGroups = 0;
454 #endif
455 #if !defined(NO_TLS)
456 TLSX_Remove(&ssl->extensions, TLSX_SUPPORTED_GROUPS, ssl->heap);
457 #endif /* !NO_TLS */
458 for (i = 0; i < count; i++) {
459 /* Call to wolfSSL_UseSupportedCurve also checks if input groups
460 * are valid */
461 if ((ret = wolfSSL_UseSupportedCurve(ssl, (word16)groups[i]))
462 != WOLFSSL_SUCCESS) {
463 #if !defined(NO_TLS)
464 TLSX_Remove(&ssl->extensions, TLSX_SUPPORTED_GROUPS, ssl->heap);
465 #endif /* !NO_TLS */
466 return ret;
467 }
468 #ifdef WOLFSSL_TLS13
469 ssl->group[i] = (word16)groups[i];
470 #endif
471 }
472 #ifdef WOLFSSL_TLS13
473 ssl->numGroups = (byte)count;
474 #endif
475
476 return WOLFSSL_SUCCESS;
477}
478#endif /* HAVE_SUPPORTED_CURVES */
479
480#ifndef WOLFSSL_NO_TLS12
481
482#ifdef HAVE_EXTENDED_MASTER
483static const byte ext_master_label[EXT_MASTER_LABEL_SZ + 1] =
484 "extended master secret";
485#endif
486static const byte master_label[MASTER_LABEL_SZ + 1] = "master secret";
487static const byte key_label [KEY_LABEL_SZ + 1] = "key expansion";
488
489static int _DeriveTlsKeys(byte* key_dig, word32 key_dig_len,
490 const byte* ms, word32 msLen,
491 const byte* sr, const byte* cr,
492 int tls1_2, int hash_type,
493 void* heap, int devId)
494{
495 int ret;
496#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
497 byte* seed = NULL;
498 seed = (byte*)XMALLOC(SEED_LEN, heap, DYNAMIC_TYPE_SEED);
499 if (seed == NULL)
500 return MEMORY_E;
501#else
502 byte seed[SEED_LEN];
503#endif
504
505 XMEMCPY(seed, sr, RAN_LEN);
506 XMEMCPY(seed + RAN_LEN, cr, RAN_LEN);
507
508#ifdef WOLFSSL_HAVE_PRF
509 PRIVATE_KEY_UNLOCK();
510 ret = wc_PRF_TLS(key_dig, key_dig_len, ms, msLen, key_label, KEY_LABEL_SZ,
511 seed, SEED_LEN, tls1_2, hash_type, heap, devId);
512 PRIVATE_KEY_LOCK();
513#else
514 /* Pseudo random function must be enabled in the configuration. */
515 ret = PRF_MISSING;
516 WOLFSSL_ERROR_VERBOSE(ret);
517 WOLFSSL_MSG("Pseudo-random function is not enabled");
518
519 (void)key_dig;
520 (void)key_dig_len;
521 (void)ms;
522 (void)msLen;
523 (void)tls1_2;
524 (void)hash_type;
525 (void)heap;
526 (void)devId;
527 (void)key_label;
528 (void)master_label;
529#ifdef HAVE_EXTENDED_MASTER
530 (void)ext_master_label;
531#endif
532#endif
533
534#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
535 XFREE(seed, heap, DYNAMIC_TYPE_SEED);
536#endif
537
538 return ret;
539}
540
541/* External facing wrapper so user can call as well, 0 on success */
542int wolfSSL_DeriveTlsKeys(byte* key_data, word32 keyLen,
543 const byte* ms, word32 msLen,
544 const byte* sr, const byte* cr,
545 int tls1_2, int hash_type)
546{
547 return _DeriveTlsKeys(key_data, keyLen, ms, msLen, sr, cr, tls1_2,
548 hash_type, NULL, INVALID_DEVID);
549}
550
551
552int DeriveTlsKeys(WOLFSSL* ssl)
553{
554 int ret;
555 int key_dig_len = 2 * ssl->specs.hash_size +
556 2 * ssl->specs.key_size +
557 2 * ssl->specs.iv_size;
558 WC_DECLARE_VAR(key_dig, byte, MAX_PRF_DIG, 0);
559
560 WC_ALLOC_VAR_EX(key_dig, byte, MAX_PRF_DIG, ssl->heap,
561 DYNAMIC_TYPE_DIGEST, return MEMORY_E);
562
563 XMEMSET(key_dig, 0, MAX_PRF_DIG);
564
565#if !defined(NO_CERTS) && defined(HAVE_PK_CALLBACKS)
566 ret = PROTOCOLCB_UNAVAILABLE;
567 if (ssl->ctx->GenSessionKeyCb) {
568 void* ctx = wolfSSL_GetGenSessionKeyCtx(ssl);
569 ret = ssl->ctx->GenSessionKeyCb(ssl, ctx);
570 }
571 if (!ssl->ctx->GenSessionKeyCb ||
572 ret == WC_NO_ERR_TRACE(PROTOCOLCB_UNAVAILABLE))
573#endif
574 ret = _DeriveTlsKeys(key_dig, (word32)key_dig_len,
575 ssl->arrays->masterSecret, SECRET_LEN,
576 ssl->arrays->serverRandom, ssl->arrays->clientRandom,
577 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
578 ssl->heap, ssl->devId);
579 if (ret == 0)
580 ret = StoreKeys(ssl, key_dig, PROVISION_CLIENT_SERVER);
581
582#ifdef WOLFSSL_CHECK_MEM_ZERO
583 wc_MemZero_Add("DeriveTlsKeys key_dig", key_dig, MAX_PRF_DIG);
584#endif
585 ForceZero(key_dig, MAX_PRF_DIG);
586#ifdef WOLFSSL_CHECK_MEM_ZERO
587 wc_MemZero_Check(key_dig, MAX_PRF_DIG);
588#endif
589
590 WC_FREE_VAR_EX(key_dig, ssl->heap, DYNAMIC_TYPE_DIGEST);
591
592 return ret;
593}
594
595static int _MakeTlsMasterSecret(byte* ms, word32 msLen,
596 const byte* pms, word32 pmsLen,
597 const byte* cr, const byte* sr,
598 int tls1_2, int hash_type,
599 void* heap, int devId)
600{
601 int ret;
602#if !defined(WOLFSSL_ASYNC_CRYPT) || defined(WC_ASYNC_NO_HASH)
603 byte seed[SEED_LEN];
604#else
605 byte* seed = NULL;
606 seed = (byte*)XMALLOC(SEED_LEN, heap, DYNAMIC_TYPE_SEED);
607 if (seed == NULL)
608 return MEMORY_E;
609#endif
610
611 XMEMCPY(seed, cr, RAN_LEN);
612 XMEMCPY(seed + RAN_LEN, sr, RAN_LEN);
613
614#ifdef WOLFSSL_HAVE_PRF
615 PRIVATE_KEY_UNLOCK();
616 ret = wc_PRF_TLS(ms, msLen, pms, pmsLen, master_label, MASTER_LABEL_SZ,
617 seed, SEED_LEN, tls1_2, hash_type, heap, devId);
618 PRIVATE_KEY_LOCK();
619#else
620 /* Pseudo random function must be enabled in the configuration. */
621 ret = PRF_MISSING;
622 WOLFSSL_MSG("Pseudo-random function is not enabled");
623
624 (void)ms;
625 (void)msLen;
626 (void)pms;
627 (void)pmsLen;
628 (void)tls1_2;
629 (void)hash_type;
630 (void)heap;
631 (void)devId;
632#endif
633
634#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
635 XFREE(seed, heap, DYNAMIC_TYPE_SEED);
636#endif
637
638 return ret;
639}
640
641/* External facing wrapper so user can call as well, 0 on success */
642int wolfSSL_MakeTlsMasterSecret(byte* ms, word32 msLen,
643 const byte* pms, word32 pmsLen,
644 const byte* cr, const byte* sr,
645 int tls1_2, int hash_type)
646{
647 return _MakeTlsMasterSecret(ms, msLen, pms, pmsLen, cr, sr, tls1_2,
648 hash_type, NULL, INVALID_DEVID);
649}
650
651
652#ifdef HAVE_EXTENDED_MASTER
653
654static int _MakeTlsExtendedMasterSecret(byte* ms, word32 msLen,
655 const byte* pms, word32 pmsLen,
656 const byte* sHash, word32 sHashLen,
657 int tls1_2, int hash_type,
658 void* heap, int devId)
659{
660 int ret;
661
662#ifdef WOLFSSL_HAVE_PRF
663 PRIVATE_KEY_UNLOCK();
664 ret = wc_PRF_TLS(ms, msLen, pms, pmsLen, ext_master_label, EXT_MASTER_LABEL_SZ,
665 sHash, sHashLen, tls1_2, hash_type, heap, devId);
666 PRIVATE_KEY_LOCK();
667#else
668 /* Pseudo random function must be enabled in the configuration. */
669 ret = PRF_MISSING;
670 WOLFSSL_MSG("Pseudo-random function is not enabled");
671
672 (void)ms;
673 (void)msLen;
674 (void)pms;
675 (void)pmsLen;
676 (void)sHash;
677 (void)sHashLen;
678 (void)tls1_2;
679 (void)hash_type;
680 (void)heap;
681 (void)devId;
682#endif
683 return ret;
684}
685
686/* External facing wrapper so user can call as well, 0 on success */
687int wolfSSL_MakeTlsExtendedMasterSecret(byte* ms, word32 msLen,
688 const byte* pms, word32 pmsLen,
689 const byte* sHash, word32 sHashLen,
690 int tls1_2, int hash_type)
691{
692 return _MakeTlsExtendedMasterSecret(ms, msLen, pms, pmsLen, sHash, sHashLen,
693 tls1_2, hash_type, NULL, INVALID_DEVID);
694}
695
696#endif /* HAVE_EXTENDED_MASTER */
697
698
699int MakeTlsMasterSecret(WOLFSSL* ssl)
700{
701 int ret;
702
703#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_KEYLOGFILE)
704 /* If this is called from a sniffer session with keylog file support, obtain
705 * the master secret from the callback */
706 if (ssl->snifferSecretCb != NULL) {
707 ret = ssl->snifferSecretCb(ssl->arrays->clientRandom,
708 SNIFFER_SECRET_TLS12_MASTER_SECRET,
709 ssl->arrays->masterSecret);
710 if (ret != 0) {
711 return ret;
712 }
713 ret = DeriveTlsKeys(ssl);
714 return ret;
715 }
716#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_KEYLOGFILE */
717
718#ifdef HAVE_EXTENDED_MASTER
719 if (ssl->options.haveEMS) {
720 word32 hashSz = HSHASH_SZ;
721 #ifdef WOLFSSL_SMALL_STACK
722 byte* handshake_hash = (byte*)XMALLOC(HSHASH_SZ, ssl->heap,
723 DYNAMIC_TYPE_DIGEST);
724 if (handshake_hash == NULL)
725 return MEMORY_E;
726 #else
727 byte handshake_hash[HSHASH_SZ];
728 #endif
729
730 XMEMSET(handshake_hash, 0, HSHASH_SZ);
731 ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz);
732 if (ret == 0) {
733 #if !defined(NO_CERTS) && defined(HAVE_PK_CALLBACKS)
734 ret = PROTOCOLCB_UNAVAILABLE;
735 if (ssl->ctx->GenExtMasterCb) {
736 void* ctx = wolfSSL_GetGenExtMasterSecretCtx(ssl);
737 ret = ssl->ctx->GenExtMasterCb(ssl, handshake_hash, hashSz,
738 ctx);
739 }
740 if (!ssl->ctx->GenExtMasterCb ||
741 ret == WC_NO_ERR_TRACE(PROTOCOLCB_UNAVAILABLE))
742 #endif /* (HAVE_SECRET_CALLBACK) && (HAVE_EXT_SECRET_CALLBACK) */
743 {
744 ret = _MakeTlsExtendedMasterSecret(
745 ssl->arrays->masterSecret, SECRET_LEN,
746 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
747 handshake_hash, hashSz,
748 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
749 ssl->heap, ssl->devId);
750 }
751 ForceZero(handshake_hash, hashSz);
752 }
753
754 #ifdef WOLFSSL_SMALL_STACK
755 XFREE(handshake_hash, ssl->heap, DYNAMIC_TYPE_DIGEST);
756 #elif defined(WOLFSSL_CHECK_MEM_ZERO)
757 wc_MemZero_Check(handshake_hash, HSHASH_SZ);
758 #endif
759 }
760 else
761#endif /* HAVE_EXTENDED_MASTER */
762 {
763
764#if !defined(NO_CERTS) && defined(HAVE_PK_CALLBACKS)
765 ret = PROTOCOLCB_UNAVAILABLE;
766 if (ssl->ctx->GenMasterCb) {
767 void* ctx = wolfSSL_GetGenMasterSecretCtx(ssl);
768 ret = ssl->ctx->GenMasterCb(ssl, ctx);
769 }
770 if (!ssl->ctx->GenMasterCb ||
771 ret == WC_NO_ERR_TRACE(PROTOCOLCB_UNAVAILABLE))
772#endif
773 {
774 ret = _MakeTlsMasterSecret(ssl->arrays->masterSecret,
775 SECRET_LEN, ssl->arrays->preMasterSecret,
776 ssl->arrays->preMasterSz, ssl->arrays->clientRandom,
777 ssl->arrays->serverRandom, IsAtLeastTLSv1_2(ssl),
778 ssl->specs.mac_algorithm, ssl->heap, ssl->devId);
779 }
780 }
781#ifdef HAVE_SECRET_CALLBACK
782 if (ret == 0 && ssl->tlsSecretCb != NULL) {
783 ret = ssl->tlsSecretCb(ssl, ssl->arrays->masterSecret,
784 SECRET_LEN, ssl->tlsSecretCtx);
785 }
786#endif /* HAVE_SECRET_CALLBACK */
787 if (ret == 0) {
788 ret = DeriveTlsKeys(ssl);
789 }
790
791 return ret;
792}
793
794
795/* Used by EAP-TLS and EAP-TTLS to derive keying material from
796 * the master_secret. */
797int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* key, unsigned int len,
798 const char* label)
799{
800 int ret;
801 WC_DECLARE_VAR(seed, byte, SEED_LEN, 0);
802
803 WC_ALLOC_VAR_EX(seed, byte, SEED_LEN, ssl->heap, DYNAMIC_TYPE_SEED,
804 return MEMORY_E);
805
806 /*
807 * As per RFC-5281, the order of the client and server randoms is reversed
808 * from that used by the TLS protocol to derive keys.
809 */
810 XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
811 XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
812
813#ifdef WOLFSSL_HAVE_PRF
814 PRIVATE_KEY_UNLOCK();
815 ret = wc_PRF_TLS((byte*)key, len, ssl->arrays->masterSecret, SECRET_LEN,
816 (const byte *)label, (word32)XSTRLEN(label), seed, SEED_LEN,
817 IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
818 ssl->heap, ssl->devId);
819 PRIVATE_KEY_LOCK();
820#else
821 /* Pseudo random function must be enabled in the configuration. */
822 ret = PRF_MISSING;
823 WOLFSSL_MSG("Pseudo-random function is not enabled");
824
825 (void)key;
826 (void)len;
827 (void)label;
828#endif
829
830 WC_FREE_VAR_EX(seed, ssl->heap, DYNAMIC_TYPE_SEED);
831
832 return ret;
833}
834
835/* return HMAC digest type in wolfSSL format */
836int wolfSSL_GetHmacType(WOLFSSL* ssl)
837{
838 if (ssl == NULL)
839 return BAD_FUNC_ARG;
840
841 return wolfSSL_GetHmacType_ex(&ssl->specs);
842}
843
844
845int wolfSSL_SetTlsHmacInner(WOLFSSL* ssl, byte* inner, word32 sz, int content,
846 int verify)
847{
848 if (ssl == NULL || inner == NULL)
849 return BAD_FUNC_ARG;
850
851 if (content == dtls12_cid
852#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
853 || (ssl->options.dtls && DtlsGetCidTxSize(ssl) > 0)
854#endif
855 ) {
856 WOLFSSL_MSG("wolfSSL_SetTlsHmacInner doesn't support CID");
857 return BAD_FUNC_ARG;
858 }
859
860 XMEMSET(inner, 0, WOLFSSL_TLS_HMAC_INNER_SZ);
861
862 WriteSEQ(ssl, verify, inner);
863 inner[SEQ_SZ] = (byte)content;
864 inner[SEQ_SZ + ENUM_LEN] = ssl->version.major;
865 inner[SEQ_SZ + ENUM_LEN + ENUM_LEN] = ssl->version.minor;
866 c16toa((word16)sz, inner + SEQ_SZ + ENUM_LEN + VERSION_SZ);
867
868 return 0;
869}
870
871
872#ifndef WOLFSSL_AEAD_ONLY
873#if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS) && \
874 !defined(HAVE_SELFTEST)
875
876/* Update the hash in the HMAC.
877 *
878 * hmac HMAC object.
879 * data Data to be hashed.
880 * sz Size of data to hash.
881 * returns 0 on success, otherwise failure.
882 */
883static int Hmac_HashUpdate(Hmac* hmac, const byte* data, word32 sz)
884{
885 int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
886
887 switch (hmac->macType) {
888 #ifndef NO_SHA
889 case WC_SHA:
890 ret = wc_ShaUpdate(&hmac->hash.sha, data, sz);
891 break;
892 #endif /* !NO_SHA */
893
894 #ifndef NO_SHA256
895 case WC_SHA256:
896 ret = wc_Sha256Update(&hmac->hash.sha256, data, sz);
897 break;
898 #endif /* !NO_SHA256 */
899
900 #ifdef WOLFSSL_SHA384
901 case WC_SHA384:
902 ret = wc_Sha384Update(&hmac->hash.sha384, data, sz);
903 break;
904 #endif /* WOLFSSL_SHA384 */
905
906 #ifdef WOLFSSL_SHA512
907 case WC_SHA512:
908 ret = wc_Sha512Update(&hmac->hash.sha512, data, sz);
909 break;
910 #endif /* WOLFSSL_SHA512 */
911
912 #ifdef WOLFSSL_SM3
913 case WC_SM3:
914 ret = wc_Sm3Update(&hmac->hash.sm3, data, sz);
915 break;
916 #endif /* WOLFSSL_SM3 */
917
918 default:
919 ret = BAD_FUNC_ARG;
920 break;
921 }
922
923 return ret;
924}
925
926/* Finalize the hash but don't put the EOC, padding or length in.
927 *
928 * hmac HMAC object.
929 * hash Hash result.
930 * returns 0 on success, otherwise failure.
931 */
932static int Hmac_HashFinalRaw(Hmac* hmac, unsigned char* hash)
933{
934 int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
935
936 switch (hmac->macType) {
937 #ifndef NO_SHA
938 case WC_SHA:
939 ret = wc_ShaFinalRaw(&hmac->hash.sha, hash);
940 break;
941 #endif /* !NO_SHA */
942
943 #ifndef NO_SHA256
944 case WC_SHA256:
945 ret = wc_Sha256FinalRaw(&hmac->hash.sha256, hash);
946 break;
947 #endif /* !NO_SHA256 */
948
949 #ifdef WOLFSSL_SHA384
950 case WC_SHA384:
951 ret = wc_Sha384FinalRaw(&hmac->hash.sha384, hash);
952 break;
953 #endif /* WOLFSSL_SHA384 */
954
955 #ifdef WOLFSSL_SHA512
956 case WC_SHA512:
957 ret = wc_Sha512FinalRaw(&hmac->hash.sha512, hash);
958 break;
959 #endif /* WOLFSSL_SHA512 */
960
961 #ifdef WOLFSSL_SM3
962 case WC_SM3:
963 ret = wc_Sm3FinalRaw(&hmac->hash.sm3, hash);
964 break;
965 #endif /* WOLFSSL_SM3 */
966
967 default:
968 ret = BAD_FUNC_ARG;
969 break;
970 }
971
972 return ret;
973}
974
975/* Finalize the HMAC by performing outer hash.
976 *
977 * hmac HMAC object.
978 * mac MAC result.
979 * returns 0 on success, otherwise failure.
980 */
981static int Hmac_OuterHash(Hmac* hmac, unsigned char* mac)
982{
983 int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
984 WC_DECLARE_VAR(hash, wc_HashAlg, 1, hmac ? hmac->heap : NULL);
985 enum wc_HashType hashType = (enum wc_HashType)hmac->macType;
986 int digestSz = wc_HashGetDigestSize(hashType);
987 int blockSz = wc_HashGetBlockSize(hashType);
988
989 WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, hmac->heap, DYNAMIC_TYPE_HASHES,
990 return MEMORY_E);
991
992 if ((digestSz >= 0) && (blockSz >= 0)) {
993 ret = wc_HashInit(hash, hashType);
994 }
995 else {
996 ret = BAD_FUNC_ARG;
997 }
998
999 if (ret == 0) {
1000 ret = wc_HashUpdate(hash, hashType, (byte*)hmac->opad,
1001 (word32)blockSz);
1002 if (ret == 0)
1003 ret = wc_HashUpdate(hash, hashType, (byte*)hmac->innerHash,
1004 (word32)digestSz);
1005 if (ret == 0)
1006 ret = wc_HashFinal(hash, hashType, mac);
1007 wc_HashFree(hash, hashType);
1008 }
1009
1010 WC_FREE_VAR_EX(hash, hmac->heap, DYNAMIC_TYPE_HASHES);
1011 return ret;
1012}
1013
1014/* Calculate the HMAC of the header + message data.
1015 * Constant time implementation using wc_Sha*FinalRaw().
1016 *
1017 * hmac HMAC object.
1018 * digest MAC result.
1019 * in Message data.
1020 * sz Size of the message data.
1021 * header Constructed record header with length of handshake data.
1022 * headerSz Length of header
1023 * returns 0 on success, otherwise failure.
1024 */
1025static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in,
1026 word32 sz, int macLen, byte* header, word32 headerSz)
1027{
1028 byte lenBytes[8];
1029 int i, j;
1030 unsigned int k;
1031 int blockBits, blockMask;
1032 int lastBlockLen, extraLen, eocIndex;
1033 int blocks;
1034 int safeBlocks;
1035 int lenBlock;
1036 int eocBlock;
1037 word32 maxLen;
1038 int blockSz, padSz;
1039 int ret;
1040 word32 realLen;
1041 byte extraBlock;
1042
1043 if (macLen <= 0 || macLen > (int)sizeof(hmac->innerHash))
1044 return BAD_FUNC_ARG;
1045
1046 switch (hmac->macType) {
1047 #ifndef NO_SHA
1048 case WC_SHA:
1049 blockSz = WC_SHA_BLOCK_SIZE;
1050 blockBits = 6;
1051 padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
1052 break;
1053 #endif /* !NO_SHA */
1054
1055 #ifndef NO_SHA256
1056 case WC_SHA256:
1057 blockSz = WC_SHA256_BLOCK_SIZE;
1058 blockBits = 6;
1059 padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
1060 break;
1061 #endif /* !NO_SHA256 */
1062
1063 #ifdef WOLFSSL_SHA384
1064 case WC_SHA384:
1065 blockSz = WC_SHA384_BLOCK_SIZE;
1066 blockBits = 7;
1067 padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
1068 break;
1069 #endif /* WOLFSSL_SHA384 */
1070
1071 #ifdef WOLFSSL_SHA512
1072 case WC_SHA512:
1073 blockSz = WC_SHA512_BLOCK_SIZE;
1074 blockBits = 7;
1075 padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
1076 break;
1077 #endif /* WOLFSSL_SHA512 */
1078
1079 #ifdef WOLFSSL_SM3
1080 case WC_SM3:
1081 blockSz = WC_SM3_BLOCK_SIZE;
1082 blockBits = 6;
1083 padSz = WC_SM3_BLOCK_SIZE - WC_SM3_PAD_SIZE + 1;
1084 break;
1085 #endif /* WOLFSSL_SM3 */
1086
1087 default:
1088 return BAD_FUNC_ARG;
1089 }
1090 blockMask = blockSz - 1;
1091
1092 /* Size of data to HMAC if padding length byte is zero. */
1093 maxLen = WOLFSSL_TLS_HMAC_INNER_SZ + sz - 1 - (word32)macLen;
1094
1095 /* Complete data (including padding) has block for EOC and/or length. */
1096 extraBlock = ctSetLTE(((int)maxLen + padSz) & blockMask, padSz);
1097 /* Total number of blocks for data including padding. */
1098 blocks = ((int)(maxLen + (word32)blockSz - 1) >> blockBits) + extraBlock;
1099 /* Up to last 6 blocks can be hashed safely. */
1100 safeBlocks = blocks - 6;
1101
1102 /* Length of message data. */
1103 realLen = maxLen - in[sz - 1];
1104 /* Number of message bytes in last block. */
1105 lastBlockLen = (int)realLen & blockMask;
1106 /* Number of padding bytes in last block. */
1107 extraLen = ((blockSz * 2 - padSz - lastBlockLen) & blockMask) + 1;
1108 /* Number of blocks to create for hash. */
1109 lenBlock = ((int)realLen + extraLen) >> blockBits;
1110 /* Block containing EOC byte. */
1111 eocBlock = (int)(realLen >> (word32)blockBits);
1112 /* Index of EOC byte in block. */
1113 eocIndex = (int)(realLen & (word32)blockMask);
1114
1115 /* Add length of hmac's ipad to total length. */
1116 realLen += (word32)blockSz;
1117 /* Length as bits - 8 bytes bigendian. */
1118 c32toa(realLen >> ((sizeof(word32) * 8) - 3), lenBytes);
1119 c32toa(realLen << 3, lenBytes + sizeof(word32));
1120
1121 ret = Hmac_HashUpdate(hmac, (unsigned char*)hmac->ipad, (word32)blockSz);
1122 if (ret != 0)
1123 return ret;
1124
1125 XMEMSET(hmac->innerHash, 0, (size_t)macLen);
1126
1127 if (safeBlocks > 0) {
1128 ret = Hmac_HashUpdate(hmac, header, headerSz);
1129 if (ret != 0)
1130 return ret;
1131 ret = Hmac_HashUpdate(hmac, in, (word32)(safeBlocks * blockSz -
1132 WOLFSSL_TLS_HMAC_INNER_SZ));
1133
1134 if (ret != 0)
1135 return ret;
1136 }
1137 else
1138 safeBlocks = 0;
1139
1140 XMEMSET(digest, 0, (size_t)macLen);
1141 k = (unsigned int)(safeBlocks * blockSz);
1142 for (i = safeBlocks; i < blocks; i++) {
1143 unsigned char hashBlock[WC_MAX_BLOCK_SIZE];
1144 unsigned char isEocBlock = ctMaskEq(i, eocBlock);
1145 unsigned char isOutBlock = ctMaskEq(i, lenBlock);
1146
1147 for (j = 0; j < blockSz; j++) {
1148 unsigned char atEoc = ctMaskEq(j, eocIndex) & isEocBlock;
1149 volatile unsigned char maskPastEoc = ctMaskGT(j, eocIndex);
1150 volatile unsigned char pastEoc = maskPastEoc & isEocBlock;
1151 unsigned char b = 0;
1152
1153 if (k < headerSz)
1154 b = header[k];
1155 else if (k < maxLen)
1156 b = in[k - headerSz];
1157 k++;
1158
1159 b = ctMaskSel(atEoc, 0x80, b);
1160 b &= (unsigned char)~(word32)pastEoc;
1161 b &= ((unsigned char)~(word32)isOutBlock) | isEocBlock;
1162
1163 if (j >= blockSz - 8) {
1164 b = ctMaskSel(isOutBlock, lenBytes[j - (blockSz - 8)], b);
1165 }
1166
1167 hashBlock[j] = b;
1168 }
1169
1170 /* cppcheck-suppress uninitvar */
1171 ret = Hmac_HashUpdate(hmac, hashBlock, (word32)blockSz);
1172 if (ret != 0)
1173 return ret;
1174 ret = Hmac_HashFinalRaw(hmac, hashBlock);
1175 if (ret != 0)
1176 return ret;
1177 for (j = 0; j < macLen; j++)
1178 ((unsigned char*)hmac->innerHash)[j] |= hashBlock[j] & isOutBlock;
1179 }
1180
1181 ret = Hmac_OuterHash(hmac, digest);
1182
1183 return ret;
1184}
1185
1186#endif
1187
1188#if defined(WOLFSSL_NO_HASH_RAW) || defined(HAVE_FIPS) || \
1189 defined(HAVE_SELFTEST) || defined(HAVE_BLAKE2B)
1190
1191/* Calculate the HMAC of the header + message data.
1192 * Constant time implementation using normal hashing operations.
1193 * Update-Final need to be constant time.
1194 *
1195 * hmac HMAC object.
1196 * digest MAC result.
1197 * in Message data.
1198 * sz Size of the message data.
1199 * header Constructed record header with length of handshake data.
1200 * headerSz Length of header
1201 * returns 0 on success, otherwise failure.
1202 */
1203static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in,
1204 word32 sz, byte* header, word32 headerSz)
1205{
1206 byte dummy[WC_MAX_BLOCK_SIZE] = {0};
1207 int ret = 0;
1208 word32 msgSz, blockSz, macSz, padSz, maxSz, realSz;
1209 word32 offset = 0;
1210 int msgBlocks, blocks, blockBits;
1211 int i;
1212
1213 switch (hmac->macType) {
1214 #ifndef NO_SHA
1215 case WC_SHA:
1216 blockSz = WC_SHA_BLOCK_SIZE;
1217 blockBits = 6;
1218 macSz = WC_SHA_DIGEST_SIZE;
1219 padSz = WC_SHA_BLOCK_SIZE - WC_SHA_PAD_SIZE + 1;
1220 break;
1221 #endif /* !NO_SHA */
1222
1223 #ifndef NO_SHA256
1224 case WC_SHA256:
1225 blockSz = WC_SHA256_BLOCK_SIZE;
1226 blockBits = 6;
1227 macSz = WC_SHA256_DIGEST_SIZE;
1228 padSz = WC_SHA256_BLOCK_SIZE - WC_SHA256_PAD_SIZE + 1;
1229 break;
1230 #endif /* !NO_SHA256 */
1231
1232 #ifdef WOLFSSL_SHA384
1233 case WC_SHA384:
1234 blockSz = WC_SHA384_BLOCK_SIZE;
1235 blockBits = 7;
1236 macSz = WC_SHA384_DIGEST_SIZE;
1237 padSz = WC_SHA384_BLOCK_SIZE - WC_SHA384_PAD_SIZE + 1;
1238 break;
1239 #endif /* WOLFSSL_SHA384 */
1240
1241 #ifdef WOLFSSL_SHA512
1242 case WC_SHA512:
1243 blockSz = WC_SHA512_BLOCK_SIZE;
1244 blockBits = 7;
1245 macSz = WC_SHA512_DIGEST_SIZE;
1246 padSz = WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE + 1;
1247 break;
1248 #endif /* WOLFSSL_SHA512 */
1249
1250 #ifdef HAVE_BLAKE2B
1251 case WC_HASH_TYPE_BLAKE2B:
1252 blockSz = BLAKE2B_BLOCKBYTES;
1253 blockBits = 7;
1254 macSz = BLAKE2B_256;
1255 padSz = 0;
1256 break;
1257 #endif /* HAVE_BLAKE2B */
1258
1259 #ifdef WOLFSSL_SM3
1260 case WC_SM3:
1261 blockSz = WC_SM3_BLOCK_SIZE;
1262 blockBits = 6;
1263 macSz = WC_SM3_DIGEST_SIZE;
1264 padSz = WC_SM3_BLOCK_SIZE - WC_SM3_PAD_SIZE + 1;
1265 break;
1266 #endif
1267
1268 default:
1269 WOLFSSL_MSG("ERROR: Hmac_UpdateFinal failed, no hmac->macType");
1270 return BAD_FUNC_ARG;
1271 }
1272
1273 msgSz = sz - (1 + in[sz - 1] + macSz);
1274 /* Make negative result 0 */
1275 msgSz &= ~(0 - (msgSz >> 31));
1276 realSz = WOLFSSL_TLS_HMAC_INNER_SZ + msgSz;
1277 maxSz = WOLFSSL_TLS_HMAC_INNER_SZ + (sz - 1) - macSz;
1278 /* Make negative result 0 */
1279 maxSz &= ~(0 - (maxSz >> 31));
1280
1281 /* Calculate #blocks processed in HMAC for max and real data. */
1282 blocks = (int)(maxSz >> blockBits);
1283 blocks += ((maxSz + padSz) % blockSz) < padSz;
1284 msgBlocks = (int)(realSz >> blockBits);
1285 /* #Extra blocks to process. */
1286 blocks -= msgBlocks + ((((realSz + padSz) % blockSz) < padSz) ? 1 : 0);
1287 /* Calculate whole blocks. */
1288 msgBlocks--;
1289
1290 ret = wc_HmacUpdate(hmac, header, headerSz);
1291 if (ret == 0) {
1292 /* Fill the rest of the block with any available data. */
1293 word32 currSz = ctMaskLT((int)msgSz, (int)blockSz) & msgSz;
1294 currSz |= ctMaskGTE((int)msgSz, (int)blockSz) & blockSz;
1295 currSz -= WOLFSSL_TLS_HMAC_INNER_SZ;
1296 currSz &= ~(0 - (currSz >> 31));
1297 ret = wc_HmacUpdate(hmac, in, currSz);
1298 offset = currSz;
1299 }
1300 if (ret == 0) {
1301 /* Do the hash operations on a block basis. */
1302 for (i = 0; i < msgBlocks; i++, offset += blockSz) {
1303 ret = wc_HmacUpdate(hmac, in + offset, blockSz);
1304 if (ret != 0)
1305 break;
1306 }
1307 }
1308 if (ret == 0)
1309 ret = wc_HmacUpdate(hmac, in + offset, msgSz - offset);
1310 if (ret == 0)
1311 ret = wc_HmacFinal(hmac, digest);
1312 if (ret == 0) {
1313 /* Do the dummy hash operations. Do at least one. */
1314 for (i = 0; i < blocks + 1; i++) {
1315 ret = wc_HmacUpdate(hmac, dummy, blockSz);
1316 if (ret != 0)
1317 break;
1318 }
1319 }
1320
1321 return ret;
1322}
1323
1324#endif
1325
1326#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
1327#define TLS_HMAC_CID_SZ(s, v) \
1328 ((v) ? DtlsGetCidRxSize((s)) \
1329 : DtlsGetCidTxSize((s)))
1330#define TLS_HMAC_CID(s, v, b, c) \
1331 ((v) ? wolfSSL_dtls_cid_get_rx((s), (b), (c)) \
1332 : wolfSSL_dtls_cid_get_tx((s), (b), (c)))
1333#endif
1334
1335static int TLS_hmac_SetInner(WOLFSSL* ssl, byte* inner, word32* innerSz,
1336 word32 sz, int content, int verify, int epochOrder)
1337{
1338#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
1339 unsigned int cidSz = 0;
1340 if (ssl->options.dtls && (cidSz = TLS_HMAC_CID_SZ(ssl, verify)) > 0) {
1341 word32 idx = 0;
1342 if (cidSz > DTLS_CID_MAX_SIZE) {
1343 WOLFSSL_MSG("DTLS CID too large");
1344 return DTLS_CID_ERROR;
1345 }
1346
1347 XMEMSET(inner + idx, 0xFF, SEQ_SZ);
1348 idx += SEQ_SZ;
1349 inner[idx++] = dtls12_cid;
1350 inner[idx++] = (byte)cidSz;
1351 inner[idx++] = dtls12_cid;
1352 inner[idx++] = ssl->version.major;
1353 inner[idx++] = ssl->version.minor;
1354 WriteSEQ(ssl, epochOrder, inner + idx);
1355 idx += SEQ_SZ;
1356 if (TLS_HMAC_CID(ssl, verify, inner + idx, cidSz) ==
1357 WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
1358 WOLFSSL_MSG("DTLS CID write failed");
1359 return DTLS_CID_ERROR;
1360 }
1361 idx += cidSz;
1362 c16toa((word16)sz, inner + idx);
1363 idx += LENGTH_SZ;
1364
1365 *innerSz = idx;
1366 return 0;
1367 }
1368#endif
1369 *innerSz = WOLFSSL_TLS_HMAC_INNER_SZ;
1370 return wolfSSL_SetTlsHmacInner(ssl, inner, sz, content,
1371 !ssl->options.dtls ? verify : epochOrder);
1372}
1373
1374#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
1375#define TLS_HMAC_INNER_SZ WOLFSSL_TLS_HMAC_CID_INNER_SZ
1376#else
1377#define TLS_HMAC_INNER_SZ WOLFSSL_TLS_HMAC_INNER_SZ
1378#endif
1379
1380int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz,
1381 int content, int verify, int epochOrder)
1382{
1383 WC_DECLARE_VAR(hmac, Hmac, 1, ssl ? ssl->heap : NULL);
1384 byte myInner[TLS_HMAC_INNER_SZ];
1385 word32 innerSz = TLS_HMAC_INNER_SZ;
1386 int ret = 0;
1387 const byte* macSecret = NULL;
1388 word32 hashSz = 0;
1389 word32 totalSz = 0;
1390
1391 if (ssl == NULL)
1392 return BAD_FUNC_ARG;
1393
1394 WC_ALLOC_VAR_EX(hmac, Hmac, 1, ssl->heap, DYNAMIC_TYPE_HMAC,
1395 return MEMORY_E);
1396
1397#ifdef HAVE_TRUNCATED_HMAC
1398 hashSz = ssl->truncated_hmac ? (byte)TRUNCATED_HMAC_SZ
1399 : ssl->specs.hash_size;
1400#else
1401 hashSz = ssl->specs.hash_size;
1402#endif
1403
1404 /* Pre-compute sz + hashSz + padSz + 1 with overflow checking.
1405 * Used by fuzzer callback and Hmac_UpdateFinal* in the verify path. */
1406 if (verify && padSz >= 0) {
1407 word32 hmacSz = 0;
1408 if (!WC_SAFE_SUM_WORD32(sz, hashSz, hmacSz) ||
1409 !WC_SAFE_SUM_WORD32(hmacSz, (word32)padSz, hmacSz) ||
1410 !WC_SAFE_SUM_WORD32(hmacSz, 1, hmacSz)) {
1411 WC_FREE_VAR_EX(hmac, ssl->heap, DYNAMIC_TYPE_HMAC);
1412 return BUFFER_E;
1413 }
1414 totalSz = hmacSz;
1415 }
1416
1417#ifdef HAVE_FUZZER
1418 /* Fuzz "in" buffer with sz to be used in HMAC algorithm */
1419 if (ssl->fuzzerCb) {
1420 if (verify && padSz >= 0) {
1421 ssl->fuzzerCb(ssl, in, totalSz, FUZZ_HMAC,
1422 ssl->fuzzerCtx);
1423 }
1424 else {
1425 ssl->fuzzerCb(ssl, in, sz, FUZZ_HMAC, ssl->fuzzerCtx);
1426 }
1427 }
1428#endif
1429
1430 ret = TLS_hmac_SetInner(ssl, myInner, &innerSz, sz, content, verify,
1431 epochOrder);
1432 if (ret != 0) {
1433 WC_FREE_VAR_EX(hmac, ssl->heap, DYNAMIC_TYPE_HMAC);
1434 return ret;
1435 }
1436
1437 ret = wc_HmacInit(hmac, ssl->heap, ssl->devId);
1438 if (ret != 0) {
1439 WC_FREE_VAR_EX(hmac, ssl->heap, DYNAMIC_TYPE_HMAC);
1440 return ret;
1441 }
1442
1443
1444#ifdef WOLFSSL_DTLS
1445 if (ssl->options.dtls)
1446 macSecret = wolfSSL_GetDtlsMacSecret(ssl, verify, epochOrder);
1447 else
1448#endif
1449 macSecret = wolfSSL_GetMacSecret(ssl, verify);
1450 ret = wc_HmacSetKey(hmac, wolfSSL_GetHmacType(ssl),
1451 macSecret,
1452 ssl->specs.hash_size);
1453
1454 if (ret == 0) {
1455 /* Constant time verification required. */
1456 if (verify && padSz >= 0) {
1457#if !defined(WOLFSSL_NO_HASH_RAW) && !defined(HAVE_FIPS) && \
1458 !defined(HAVE_SELFTEST)
1459 #ifdef HAVE_BLAKE2B
1460 if (wolfSSL_GetHmacType(ssl) == WC_HASH_TYPE_BLAKE2B) {
1461 ret = Hmac_UpdateFinal(hmac, digest, in,
1462 totalSz, myInner, innerSz);
1463 }
1464 else
1465 #endif
1466 {
1467 ret = Hmac_UpdateFinal_CT(hmac, digest, in,
1468 totalSz,
1469 (int)hashSz, myInner, innerSz);
1470
1471 }
1472#else
1473 ret = Hmac_UpdateFinal(hmac, digest, in, totalSz,
1474 myInner, innerSz);
1475#endif
1476 }
1477 else {
1478 ret = wc_HmacUpdate(hmac, myInner, innerSz);
1479 if (ret == 0)
1480 ret = wc_HmacUpdate(hmac, in, sz); /* content */
1481 if (ret == 0)
1482 ret = wc_HmacFinal(hmac, digest);
1483 }
1484 }
1485
1486 wc_HmacFree(hmac);
1487 WC_FREE_VAR_EX(hmac, ssl->heap, DYNAMIC_TYPE_HMAC);
1488
1489 return ret;
1490}
1491#endif /* WOLFSSL_AEAD_ONLY */
1492
1493#endif /* !WOLFSSL_NO_TLS12 */
1494
1495int wolfSSL_GetHmacType_ex(CipherSpecs* specs)
1496{
1497 if (specs == NULL)
1498 return BAD_FUNC_ARG;
1499
1500 switch (specs->mac_algorithm) {
1501 #ifndef NO_MD5
1502 case md5_mac:
1503 {
1504 return WC_MD5;
1505 }
1506 #endif
1507 #ifndef NO_SHA256
1508 case sha256_mac:
1509 {
1510 return WC_SHA256;
1511 }
1512 #endif
1513 #ifdef WOLFSSL_SHA384
1514 case sha384_mac:
1515 {
1516 return WC_SHA384;
1517 }
1518 #endif
1519 #ifdef WOLFSSL_SM3
1520 case sm3_mac:
1521 {
1522 return WC_SM3;
1523 }
1524 #endif
1525 #ifndef NO_SHA
1526 case sha_mac:
1527 {
1528 return WC_SHA;
1529 }
1530 #endif
1531 #ifdef HAVE_BLAKE2B
1532 case blake2b_mac:
1533 {
1534 return BLAKE2B_ID;
1535 }
1536 #endif
1537 default:
1538 {
1539 return WOLFSSL_FATAL_ERROR;
1540 }
1541 }
1542}
1543
1544#ifdef HAVE_TLS_EXTENSIONS
1545
1546/**
1547 * The TLSX semaphore is used to calculate the size of the extensions to be sent
1548 * from one peer to another.
1549 */
1550
1551/** Supports up to 72 flags. Increase as needed. */
1552#define SEMAPHORE_SIZE 9
1553
1554/**
1555 * Converts the extension type (id) to an index in the semaphore.
1556 *
1557 * Official reference for TLS extension types:
1558 * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xml
1559 *
1560 * Motivation:
1561 * Previously, we used the extension type itself as the index of that
1562 * extension in the semaphore as the extension types were declared
1563 * sequentially, but maintain a semaphore as big as the number of available
1564 * extensions is no longer an option since the release of renegotiation_info.
1565 *
1566 * How to update:
1567 * Assign extension types that extrapolate the number of available semaphores
1568 * to the first available index going backwards in the semaphore array.
1569 * When adding a new extension type that don't extrapolate the number of
1570 * available semaphores, check for a possible collision with with a
1571 * 'remapped' extension type.
1572 *
1573 * Update TLSX_Parse for duplicate detection if more added above 62.
1574 */
1575static WC_INLINE word16 TLSX_ToSemaphore(word16 type)
1576{
1577 switch (type) {
1578
1579 case TLSX_RENEGOTIATION_INFO: /* 0xFF01 */
1580 return 63;
1581#ifdef WOLFSSL_QUIC
1582 case TLSX_KEY_QUIC_TP_PARAMS_DRAFT: /* 0xffa5 */
1583 return 64;
1584#endif
1585#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
1586 case TLSX_ECH: /* 0xfe0d */
1587 return 65;
1588#endif
1589#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DUAL_ALG_CERTS)
1590 case TLSX_CKS:
1591 return 66;
1592#endif
1593 default:
1594 if (type > 62) {
1595 /* This message SHOULD only happens during the adding of
1596 new TLS extensions in which its IANA number overflows
1597 the current semaphore's range, or if its number already
1598 is assigned to be used by another extension.
1599 Use this check value for the new extension and decrement
1600 the check value by one. */
1601 WOLFSSL_MSG("### TLSX semaphore collision or overflow detected!");
1602 }
1603 }
1604
1605 return type;
1606}
1607
1608/** Checks if a specific light (tls extension) is not set in the semaphore. */
1609#define IS_OFF(semaphore, light) \
1610 (!(((semaphore)[(light) / 8] & (byte) (0x01 << ((light) % 8)))))
1611
1612/** Turn on a specific light (tls extension) in the semaphore. */
1613/* the semaphore marks the extensions already written to the message */
1614#define TURN_ON(semaphore, light) \
1615 ((semaphore)[(light) / 8] |= (byte) (0x01 << ((light) % 8)))
1616
1617/** Turn off a specific light (tls extension) in the semaphore. */
1618#define TURN_OFF(semaphore, light) \
1619 ((semaphore)[(light) / 8] &= (byte) ~(0x01 << ((light) % 8)))
1620
1621/** Creates a new extension. */
1622static TLSX* TLSX_New(TLSX_Type type, const void* data, void* heap)
1623{
1624 TLSX* extension = (TLSX*)XMALLOC(sizeof(TLSX), heap, DYNAMIC_TYPE_TLSX);
1625
1626 (void)heap;
1627
1628 if (extension) {
1629 extension->type = type;
1630 extension->data = (void*)data;
1631 extension->resp = 0;
1632 extension->next = NULL;
1633 }
1634
1635 return extension;
1636}
1637
1638/**
1639 * Creates a new extension and appends it to the provided list.
1640 * Checks for duplicate extensions, keeps the newest.
1641 */
1642int TLSX_Append(TLSX** list, TLSX_Type type, const void* data, void* heap)
1643{
1644 TLSX* extension = TLSX_New(type, data, heap);
1645 TLSX* cur;
1646 TLSX** prevNext = list;
1647
1648 if (extension == NULL)
1649 return MEMORY_E;
1650
1651 for (cur = *list; cur != NULL;) {
1652 if (cur->type == type) {
1653 *prevNext = cur->next;
1654 cur->next = NULL;
1655 TLSX_FreeAll(cur, heap);
1656 cur = *prevNext;
1657 }
1658 else {
1659 prevNext = &cur->next;
1660 cur = cur->next;
1661 }
1662 }
1663
1664 /* Append the extension to the list */
1665 *prevNext = extension;
1666
1667 return 0;
1668}
1669
1670/**
1671 * Creates a new extension and pushes it to the provided list.
1672 * Checks for duplicate extensions, keeps the newest.
1673 */
1674int TLSX_Push(TLSX** list, TLSX_Type type, const void* data, void* heap)
1675{
1676 TLSX* extension = TLSX_New(type, data, heap);
1677
1678 if (extension == NULL)
1679 return MEMORY_E;
1680
1681 /* pushes the new extension on the list. */
1682 extension->next = *list;
1683 *list = extension;
1684
1685 /* remove duplicate extensions, there should be only one of each type. */
1686 do {
1687 if (extension->next && extension->next->type == type) {
1688 TLSX *next = extension->next;
1689
1690 extension->next = next->next;
1691 next->next = NULL;
1692
1693 TLSX_FreeAll(next, heap);
1694
1695 /* there is no way to occur more than
1696 * two extensions of the same type.
1697 */
1698 break;
1699 }
1700 } while ((extension = extension->next));
1701
1702 return 0;
1703}
1704
1705#ifndef NO_WOLFSSL_CLIENT
1706
1707int TLSX_CheckUnsupportedExtension(WOLFSSL* ssl, TLSX_Type type);
1708
1709int TLSX_CheckUnsupportedExtension(WOLFSSL* ssl, TLSX_Type type)
1710{
1711 TLSX *extension = TLSX_Find(ssl->extensions, type);
1712
1713 if (!extension)
1714 extension = TLSX_Find(ssl->ctx->extensions, type);
1715
1716 return extension == NULL;
1717}
1718
1719int TLSX_HandleUnsupportedExtension(WOLFSSL* ssl);
1720
1721int TLSX_HandleUnsupportedExtension(WOLFSSL* ssl)
1722{
1723 SendAlert(ssl, alert_fatal, unsupported_extension);
1724 WOLFSSL_ERROR_VERBOSE(UNSUPPORTED_EXTENSION);
1725 return UNSUPPORTED_EXTENSION;
1726}
1727
1728#else
1729
1730#define TLSX_CheckUnsupportedExtension(ssl, type) 0
1731#define TLSX_HandleUnsupportedExtension(ssl) 0
1732
1733#endif
1734
1735#if !defined(NO_WOLFSSL_SERVER) || defined(WOLFSSL_TLS13)
1736void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type);
1737/** Mark an extension to be sent back to the client. */
1738void TLSX_SetResponse(WOLFSSL* ssl, TLSX_Type type)
1739{
1740 TLSX *extension = TLSX_Find(ssl->extensions, type);
1741
1742 if (extension)
1743 extension->resp = 1;
1744}
1745#endif
1746
1747/******************************************************************************/
1748/* Application-Layer Protocol Negotiation */
1749/******************************************************************************/
1750
1751#ifdef HAVE_ALPN
1752/** Creates a new ALPN object, providing protocol name to use. */
1753static ALPN* TLSX_ALPN_New(char *protocol_name, word16 protocol_nameSz,
1754 void* heap)
1755{
1756 ALPN *alpn;
1757
1758 WOLFSSL_ENTER("TLSX_ALPN_New");
1759
1760 if (protocol_name == NULL ||
1761 protocol_nameSz > WOLFSSL_MAX_ALPN_PROTO_NAME_LEN) {
1762 WOLFSSL_MSG("Invalid arguments");
1763 return NULL;
1764 }
1765
1766 alpn = (ALPN*)XMALLOC(sizeof(ALPN), heap, DYNAMIC_TYPE_TLSX);
1767 if (alpn == NULL) {
1768 WOLFSSL_MSG("Memory failure");
1769 return NULL;
1770 }
1771
1772 alpn->next = NULL;
1773 alpn->negotiated = 0;
1774 alpn->options = 0;
1775
1776 alpn->protocol_name = (char*)XMALLOC(protocol_nameSz + 1,
1777 heap, DYNAMIC_TYPE_TLSX);
1778 if (alpn->protocol_name == NULL) {
1779 WOLFSSL_MSG("Memory failure");
1780 XFREE(alpn, heap, DYNAMIC_TYPE_TLSX);
1781 return NULL;
1782 }
1783
1784 XMEMCPY(alpn->protocol_name, protocol_name, protocol_nameSz);
1785 alpn->protocol_name[protocol_nameSz] = 0;
1786
1787 (void)heap;
1788
1789 return alpn;
1790}
1791
1792/** Releases an ALPN object. */
1793static void TLSX_ALPN_Free(ALPN *alpn, void* heap)
1794{
1795 (void)heap;
1796
1797 if (alpn == NULL)
1798 return;
1799
1800 XFREE(alpn->protocol_name, heap, DYNAMIC_TYPE_TLSX);
1801 XFREE(alpn, heap, DYNAMIC_TYPE_TLSX);
1802}
1803
1804/** Releases all ALPN objects in the provided list. */
1805static void TLSX_ALPN_FreeAll(ALPN *list, void* heap)
1806{
1807 ALPN* alpn;
1808
1809 while ((alpn = list)) {
1810 list = alpn->next;
1811 TLSX_ALPN_Free(alpn, heap);
1812 }
1813}
1814
1815/** Tells the buffered size of the ALPN objects in a list. */
1816static word16 TLSX_ALPN_GetSize(ALPN *list)
1817{
1818 ALPN* alpn;
1819 word32 length = OPAQUE16_LEN; /* list length */
1820
1821 while ((alpn = list)) {
1822 list = alpn->next;
1823
1824 length++; /* protocol name length is on one byte */
1825 length += (word32)XSTRLEN(alpn->protocol_name);
1826
1827 if (length > WOLFSSL_MAX_16BIT) {
1828 return 0;
1829 }
1830 }
1831
1832 return (word16)length;
1833}
1834
1835/** Writes the ALPN objects of a list in a buffer. */
1836static word16 TLSX_ALPN_Write(ALPN *list, byte *output)
1837{
1838 ALPN* alpn;
1839 word16 length = 0;
1840 word16 offset = OPAQUE16_LEN; /* list length offset */
1841
1842 while ((alpn = list)) {
1843 list = alpn->next;
1844
1845 length = (word16)XSTRLEN(alpn->protocol_name);
1846
1847 /* protocol name length */
1848 output[offset++] = (byte)length;
1849
1850 /* protocol name value */
1851 XMEMCPY(output + offset, alpn->protocol_name, length);
1852
1853 offset += length;
1854 }
1855
1856 /* writing list length */
1857 c16toa(offset - OPAQUE16_LEN, output);
1858
1859 return offset;
1860}
1861
1862/** Finds a protocol name in the provided ALPN list */
1863static ALPN* TLSX_ALPN_Find(ALPN *list, char *protocol_name, word16 size)
1864{
1865 ALPN *alpn;
1866
1867 if (list == NULL || protocol_name == NULL)
1868 return NULL;
1869
1870 alpn = list;
1871 while (alpn != NULL && (
1872 (word16)XSTRLEN(alpn->protocol_name) != size ||
1873 XSTRNCMP(alpn->protocol_name, protocol_name, size)))
1874 alpn = alpn->next;
1875
1876 return alpn;
1877}
1878
1879/** Set the ALPN matching client and server requirements */
1880static int TLSX_SetALPN(TLSX** extensions, const void* data, word16 size,
1881 void* heap)
1882{
1883 ALPN *alpn;
1884 int ret;
1885
1886 if (extensions == NULL || data == NULL)
1887 return BAD_FUNC_ARG;
1888
1889 alpn = TLSX_ALPN_New((char *)data, size, heap);
1890 if (alpn == NULL) {
1891 WOLFSSL_MSG("Memory failure");
1892 return MEMORY_E;
1893 }
1894
1895 alpn->negotiated = 1;
1896
1897 ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL, (void*)alpn,
1898 heap);
1899 if (ret != 0) {
1900 TLSX_ALPN_Free(alpn, heap);
1901 return ret;
1902 }
1903
1904 return WOLFSSL_SUCCESS;
1905}
1906
1907static int ALPN_find_match(WOLFSSL *ssl, TLSX **pextension,
1908 const byte **psel, byte *psel_len,
1909 const byte *alpn_val, word16 alpn_val_len)
1910{
1911 TLSX *extension;
1912 ALPN *alpn, *list;
1913 const byte *sel = NULL, *s;
1914 byte sel_len = 0, wlen;
1915
1916 extension = TLSX_Find(ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
1917 if (extension == NULL)
1918 extension = TLSX_Find(ssl->ctx->extensions,
1919 TLSX_APPLICATION_LAYER_PROTOCOL);
1920
1921 /* No ALPN configured here */
1922 if (extension == NULL || extension->data == NULL) {
1923 *pextension = NULL;
1924 *psel = NULL;
1925 *psel_len = 0;
1926 return 0;
1927 }
1928
1929 list = (ALPN*)extension->data;
1930 for (s = alpn_val;
1931 (s - alpn_val) < alpn_val_len;
1932 s += wlen) {
1933 wlen = *s++; /* bounds already checked on save */
1934 alpn = TLSX_ALPN_Find(list, (char*)s, wlen);
1935 if (alpn != NULL) {
1936 WOLFSSL_MSG("ALPN protocol match");
1937 sel = s,
1938 sel_len = wlen;
1939 break;
1940 }
1941 }
1942
1943 if (sel == NULL) {
1944 WOLFSSL_MSG("No ALPN protocol match");
1945
1946 /* do nothing if no protocol match between client and server and option
1947 is set to continue (like OpenSSL) */
1948 if (list->options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) {
1949 WOLFSSL_MSG("Continue on mismatch");
1950 }
1951 else {
1952 SendAlert(ssl, alert_fatal, no_application_protocol);
1953 WOLFSSL_ERROR_VERBOSE(UNKNOWN_ALPN_PROTOCOL_NAME_E);
1954 return UNKNOWN_ALPN_PROTOCOL_NAME_E;
1955 }
1956 }
1957
1958 *pextension = extension;
1959 *psel = sel;
1960 *psel_len = sel_len;
1961 return 0;
1962}
1963
1964int ALPN_Select(WOLFSSL *ssl)
1965{
1966 TLSX *extension;
1967 const byte *sel = NULL;
1968 byte sel_len = 0;
1969 int r = 0;
1970
1971 WOLFSSL_ENTER("ALPN_Select");
1972 if (ssl->alpn_peer_requested == NULL)
1973 return 0;
1974
1975#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
1976 if (ssl->alpnSelect != NULL && ssl->options.side == WOLFSSL_SERVER_END) {
1977 r = ssl->alpnSelect(ssl, &sel, &sel_len, ssl->alpn_peer_requested,
1978 ssl->alpn_peer_requested_length, ssl->alpnSelectArg);
1979 switch (r) {
1980 case SSL_TLSEXT_ERR_OK:
1981 WOLFSSL_MSG("ALPN protocol match");
1982 break;
1983 case SSL_TLSEXT_ERR_NOACK:
1984 WOLFSSL_MSG("ALPN cb no match but not fatal");
1985 sel = NULL;
1986 sel_len = 0;
1987 break;
1988 case SSL_TLSEXT_ERR_ALERT_FATAL:
1989 default:
1990 WOLFSSL_MSG("ALPN cb no match and fatal");
1991 SendAlert(ssl, alert_fatal, no_application_protocol);
1992 WOLFSSL_ERROR_VERBOSE(UNKNOWN_ALPN_PROTOCOL_NAME_E);
1993 return UNKNOWN_ALPN_PROTOCOL_NAME_E;
1994 }
1995 }
1996 else
1997#endif
1998 {
1999 r = ALPN_find_match(ssl, &extension, &sel, &sel_len,
2000 ssl->alpn_peer_requested,
2001 ssl->alpn_peer_requested_length);
2002 if (r != 0)
2003 return r;
2004 }
2005
2006 if (sel != NULL) {
2007 /* set the matching negotiated protocol */
2008 r = TLSX_SetALPN(&ssl->extensions, sel, sel_len, ssl->heap);
2009 if (r != WOLFSSL_SUCCESS) {
2010 WOLFSSL_MSG("TLSX_SetALPN failed");
2011 return BUFFER_ERROR;
2012 }
2013 /* reply to ALPN extension sent from peer */
2014#ifndef NO_WOLFSSL_SERVER
2015 TLSX_SetResponse(ssl, TLSX_APPLICATION_LAYER_PROTOCOL);
2016#endif
2017 }
2018 return 0;
2019}
2020
2021/** Parses a buffer of ALPN extensions and set the first one matching
2022 * client and server requirements */
2023static int TLSX_ALPN_ParseAndSet(WOLFSSL *ssl, const byte *input, word16 length,
2024 byte isRequest)
2025{
2026 word16 size = 0, offset = 0, wlen;
2027 int r = WC_NO_ERR_TRACE(BUFFER_ERROR);
2028 const byte *s;
2029
2030 if (OPAQUE16_LEN > length)
2031 return BUFFER_ERROR;
2032
2033 ato16(input, &size);
2034 offset += OPAQUE16_LEN;
2035
2036 /* validating alpn list length */
2037 if (size == 0 || length != OPAQUE16_LEN + size)
2038 return BUFFER_ERROR;
2039
2040 /* validating length of entries before accepting */
2041 for (s = input + offset; (s - input) < length; s += wlen) {
2042 wlen = *s++;
2043 if (wlen == 0 || (s + wlen - input) > length)
2044 return BUFFER_ERROR;
2045 }
2046
2047 if (isRequest) {
2048 /* keep the list sent by peer, if this is from a request. We
2049 * use it later in ALPN_Select() for evaluation. */
2050 if (ssl->alpn_peer_requested != NULL) {
2051 XFREE(ssl->alpn_peer_requested, ssl->heap, DYNAMIC_TYPE_ALPN);
2052 ssl->alpn_peer_requested_length = 0;
2053 }
2054 ssl->alpn_peer_requested = (byte *)XMALLOC(size, ssl->heap,
2055 DYNAMIC_TYPE_ALPN);
2056 if (ssl->alpn_peer_requested == NULL) {
2057 return MEMORY_ERROR;
2058 }
2059 ssl->alpn_peer_requested_length = size;
2060 XMEMCPY(ssl->alpn_peer_requested, (char*)input + offset, size);
2061 }
2062 else {
2063 /* a response, we should find the value in our config */
2064 const byte *sel = NULL;
2065 byte sel_len = 0;
2066 TLSX *extension = NULL;
2067
2068 r = ALPN_find_match(ssl, &extension, &sel, &sel_len, input + offset, size);
2069 if (r != 0)
2070 return r;
2071
2072 if (sel != NULL) {
2073 /* set the matching negotiated protocol */
2074 r = TLSX_SetALPN(&ssl->extensions, sel, sel_len, ssl->heap);
2075 if (r != WOLFSSL_SUCCESS) {
2076 WOLFSSL_MSG("TLSX_SetALPN failed");
2077 return BUFFER_ERROR;
2078 }
2079 }
2080 /* If we had nothing configured, the response is unexpected */
2081 else if (extension == NULL) {
2082 r = TLSX_HandleUnsupportedExtension(ssl);
2083 if (r != 0)
2084 return r;
2085 }
2086 }
2087 return 0;
2088}
2089
2090/** Add a protocol name to the list of accepted usable ones */
2091int TLSX_UseALPN(TLSX** extensions, const void* data, word16 size, byte options,
2092 void* heap)
2093{
2094 ALPN *alpn;
2095 TLSX *extension;
2096 int ret;
2097
2098 if (extensions == NULL || data == NULL)
2099 return BAD_FUNC_ARG;
2100
2101 alpn = TLSX_ALPN_New((char *)data, size, heap);
2102 if (alpn == NULL) {
2103 WOLFSSL_MSG("Memory failure");
2104 return MEMORY_E;
2105 }
2106
2107 /* Set Options of ALPN */
2108 alpn->options = options;
2109
2110 extension = TLSX_Find(*extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
2111 if (extension == NULL) {
2112 ret = TLSX_Push(extensions, TLSX_APPLICATION_LAYER_PROTOCOL,
2113 (void*)alpn, heap);
2114 if (ret != 0) {
2115 TLSX_ALPN_Free(alpn, heap);
2116 return ret;
2117 }
2118 }
2119 else {
2120 /* push new ALPN object to extension data. */
2121 alpn->next = (ALPN*)extension->data;
2122 extension->data = (void*)alpn;
2123 }
2124
2125 return WOLFSSL_SUCCESS;
2126}
2127
2128/** Get the protocol name set by the server */
2129int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
2130{
2131 TLSX *extension;
2132 ALPN *alpn;
2133
2134 if (extensions == NULL || data == NULL || dataSz == NULL)
2135 return BAD_FUNC_ARG;
2136
2137 *data = NULL;
2138 *dataSz = 0;
2139
2140 extension = TLSX_Find(extensions, TLSX_APPLICATION_LAYER_PROTOCOL);
2141 if (extension == NULL) {
2142 WOLFSSL_MSG("TLS extension not found");
2143 WOLFSSL_ERROR_VERBOSE(WOLFSSL_ALPN_NOT_FOUND);
2144 return WOLFSSL_ALPN_NOT_FOUND;
2145 }
2146
2147 alpn = (ALPN *)extension->data;
2148 if (alpn == NULL) {
2149 WOLFSSL_MSG("ALPN extension not found");
2150 WOLFSSL_ERROR_VERBOSE(WOLFSSL_FATAL_ERROR);
2151 return WOLFSSL_FATAL_ERROR;
2152 }
2153
2154 if (alpn->negotiated != 1) {
2155
2156 /* consider as an error */
2157 if (alpn->options & WOLFSSL_ALPN_FAILED_ON_MISMATCH) {
2158 WOLFSSL_MSG("No protocol match with peer -> Failed");
2159 WOLFSSL_ERROR_VERBOSE(WOLFSSL_FATAL_ERROR);
2160 return WOLFSSL_FATAL_ERROR;
2161 }
2162
2163 /* continue without negotiated protocol */
2164 WOLFSSL_MSG("No protocol match with peer -> Continue");
2165 WOLFSSL_ERROR_VERBOSE(WOLFSSL_ALPN_NOT_FOUND);
2166 return WOLFSSL_ALPN_NOT_FOUND;
2167 }
2168
2169 if (alpn->next != NULL) {
2170 WOLFSSL_MSG("Only one protocol name must be accepted");
2171 WOLFSSL_ERROR_VERBOSE(WOLFSSL_FATAL_ERROR);
2172 return WOLFSSL_FATAL_ERROR;
2173 }
2174
2175 *data = alpn->protocol_name;
2176 *dataSz = (word16)XSTRLEN((char*)*data);
2177
2178 return WOLFSSL_SUCCESS;
2179}
2180
2181#define ALPN_FREE_ALL TLSX_ALPN_FreeAll
2182#define ALPN_GET_SIZE TLSX_ALPN_GetSize
2183#define ALPN_WRITE TLSX_ALPN_Write
2184#define ALPN_PARSE TLSX_ALPN_ParseAndSet
2185
2186#else /* HAVE_ALPN */
2187
2188#define ALPN_FREE_ALL(list, heap) WC_DO_NOTHING
2189#define ALPN_GET_SIZE(list) 0
2190#define ALPN_WRITE(a, b) 0
2191#define ALPN_PARSE(a, b, c, d) 0
2192
2193#endif /* HAVE_ALPN */
2194
2195/******************************************************************************/
2196/* Server Name Indication */
2197/******************************************************************************/
2198
2199#ifdef HAVE_SNI
2200
2201/** Creates a new SNI object. */
2202static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap)
2203{
2204 SNI* sni = (SNI*)XMALLOC(sizeof(SNI), heap, DYNAMIC_TYPE_TLSX);
2205
2206 (void)heap;
2207
2208 if (sni) {
2209 sni->type = type;
2210 sni->next = NULL;
2211
2212 #ifndef NO_WOLFSSL_SERVER
2213 sni->options = 0;
2214 sni->status = WOLFSSL_SNI_NO_MATCH;
2215 #endif
2216
2217 switch (sni->type) {
2218 case WOLFSSL_SNI_HOST_NAME:
2219 sni->data.host_name = (char*)XMALLOC(size + 1, heap,
2220 DYNAMIC_TYPE_TLSX);
2221 if (sni->data.host_name) {
2222 XSTRNCPY(sni->data.host_name, (const char*)data, size);
2223 sni->data.host_name[size] = '\0';
2224 } else {
2225 XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
2226 sni = NULL;
2227 }
2228 break;
2229
2230 default: /* invalid type */
2231 XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
2232 sni = NULL;
2233 }
2234 }
2235
2236 return sni;
2237}
2238
2239/** Releases a SNI object. */
2240static void TLSX_SNI_Free(SNI* sni, void* heap)
2241{
2242 if (sni) {
2243 switch (sni->type) {
2244 case WOLFSSL_SNI_HOST_NAME:
2245 XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX);
2246 break;
2247 }
2248
2249 XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
2250 }
2251 (void)heap;
2252}
2253
2254/** Releases all SNI objects in the provided list. */
2255static void TLSX_SNI_FreeAll(SNI* list, void* heap)
2256{
2257 SNI* sni;
2258
2259 while ((sni = list)) {
2260 list = sni->next;
2261 TLSX_SNI_Free(sni, heap);
2262 }
2263}
2264
2265/** Tells the buffered size of the SNI objects in a list. */
2266WOLFSSL_TEST_VIS word16 TLSX_SNI_GetSize(SNI* list)
2267{
2268 SNI* sni;
2269 word32 length = OPAQUE16_LEN; /* list length */
2270
2271 while ((sni = list)) {
2272 list = sni->next;
2273
2274 length += ENUM_LEN + OPAQUE16_LEN; /* sni type + sni length */
2275
2276 switch (sni->type) {
2277 case WOLFSSL_SNI_HOST_NAME:
2278 length += (word32)XSTRLEN((char*)sni->data.host_name);
2279 break;
2280 }
2281
2282 if (length > WOLFSSL_MAX_16BIT) {
2283 return 0;
2284 }
2285 }
2286
2287 return (word16)length;
2288}
2289
2290/** Writes the SNI objects of a list in a buffer. */
2291static word16 TLSX_SNI_Write(SNI* list, byte* output)
2292{
2293 SNI* sni;
2294 word16 length = 0;
2295 word16 offset = OPAQUE16_LEN; /* list length offset */
2296
2297 while ((sni = list)) {
2298 list = sni->next;
2299
2300 output[offset++] = sni->type; /* sni type */
2301
2302 switch (sni->type) {
2303 case WOLFSSL_SNI_HOST_NAME:
2304 length = (word16)XSTRLEN((char*)sni->data.host_name);
2305
2306 c16toa(length, output + offset); /* sni length */
2307 offset += OPAQUE16_LEN;
2308
2309 XMEMCPY(output + offset, sni->data.host_name, length);
2310
2311 offset += length;
2312 break;
2313 }
2314 }
2315
2316 c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
2317
2318 return offset;
2319}
2320
2321/** Finds a SNI object in the provided list. */
2322static SNI* TLSX_SNI_Find(SNI *list, byte type)
2323{
2324 SNI* sni = list;
2325
2326 while (sni && sni->type != type)
2327 sni = sni->next;
2328
2329 return sni;
2330}
2331
2332#if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
2333/** Sets the status of a SNI object. */
2334static void TLSX_SNI_SetStatus(TLSX* extensions, byte type, byte status)
2335{
2336 TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
2337 SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
2338
2339 if (sni)
2340 sni->status = status;
2341}
2342#endif
2343
2344/** Gets the status of a SNI object. */
2345byte TLSX_SNI_Status(TLSX* extensions, byte type)
2346{
2347 TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
2348 SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
2349
2350 if (sni)
2351 return sni->status;
2352
2353 return 0;
2354}
2355
2356/** Parses a buffer of SNI extensions. */
2357static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
2358 byte isRequest)
2359{
2360#ifndef NO_WOLFSSL_SERVER
2361 word16 size = 0;
2362 word16 offset = 0;
2363 int cacheOnly = 0;
2364 SNI *sni = NULL;
2365 byte type;
2366 byte matched;
2367#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2368 TLSX* echX = NULL;
2369 WOLFSSL_ECH* ech = NULL;
2370 WOLFSSL_EchConfig* workingConfig;
2371 word16 privateNameLen;
2372#endif
2373#endif /* !NO_WOLFSSL_SERVER */
2374 TLSX *extension = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
2375
2376 if (!extension)
2377 extension = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
2378
2379 if (!isRequest) {
2380 #ifndef NO_WOLFSSL_CLIENT
2381 if (!extension || !extension->data)
2382 return TLSX_HandleUnsupportedExtension(ssl);
2383
2384 if (length > 0)
2385 return BUFFER_ERROR; /* SNI response MUST be empty. */
2386
2387 /* This call enables wolfSSL_SNI_GetRequest() to be called in the
2388 * client side to fetch the used SNI. It will only work if the SNI
2389 * was set at the SSL object level. Right now we only support one
2390 * name type, WOLFSSL_SNI_HOST_NAME, but in the future, the
2391 * inclusion of other name types will turn this method inaccurate,
2392 * as the extension response doesn't contains information of which
2393 * name was accepted.
2394 */
2395 TLSX_SNI_SetStatus(ssl->extensions, WOLFSSL_SNI_HOST_NAME,
2396 WOLFSSL_SNI_REAL_MATCH);
2397
2398 return 0;
2399 #endif
2400 }
2401
2402#ifndef NO_WOLFSSL_SERVER
2403#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2404 if (!ssl->options.disableECH) {
2405 echX = TLSX_Find(ssl->extensions, TLSX_ECH);
2406 if (echX != NULL) {
2407 ech = (WOLFSSL_ECH*)(echX->data);
2408 }
2409 }
2410#endif
2411
2412#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2413 if ((!extension || !extension->data) ||
2414 (ech != NULL && ech->sniState == ECH_INNER_SNI &&
2415 ech->privateName == NULL)) {
2416#else
2417 if (!extension || !extension->data) {
2418#endif
2419 /* This will keep SNI even though TLSX_UseSNI has not been called.
2420 * Enable it so that the received sni is available to functions
2421 * that use a custom callback when SNI is received.
2422 */
2423 #ifdef WOLFSSL_ALWAYS_KEEP_SNI
2424 cacheOnly = 1;
2425 #endif
2426 if (ssl->ctx->sniRecvCb) {
2427 cacheOnly = 1;
2428 }
2429
2430 if (cacheOnly) {
2431 WOLFSSL_MSG("Forcing SSL object to store SNI parameter");
2432 }
2433 else {
2434 /* Skipping, SNI not enabled at server side. */
2435 return 0;
2436 }
2437 }
2438
2439 if (OPAQUE16_LEN > length)
2440 return BUFFER_ERROR;
2441
2442 ato16(input, &size);
2443 offset += OPAQUE16_LEN;
2444
2445 /* validating sni list length */
2446 if (length != OPAQUE16_LEN + size || size == 0)
2447 return BUFFER_ERROR;
2448
2449 /* SNI was badly specified and only one type is now recognized and allowed.
2450 * Only one SNI value per type (RFC6066), so, no loop. */
2451 type = input[offset++];
2452 if (type != WOLFSSL_SNI_HOST_NAME)
2453 return BUFFER_ERROR;
2454
2455 if (offset + OPAQUE16_LEN > length)
2456 return BUFFER_ERROR;
2457 ato16(input + offset, &size);
2458 offset += OPAQUE16_LEN;
2459
2460 if (offset + size != length || size == 0)
2461 return BUFFER_ERROR;
2462
2463 if (!cacheOnly && !(sni = TLSX_SNI_Find((SNI*)extension->data, type)))
2464 return 0; /* not using this type of SNI. */
2465
2466#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2467 if (ech != NULL && ech->sniState == ECH_INNER_SNI){
2468 /* SNI status is carried over from processing the outer hello so it is
2469 * necessary to clear it before processing the inner hello */
2470 ech->sniState = ECH_INNER_SNI_ATTEMPT;
2471 if (sni != NULL){
2472 sni->status = WOLFSSL_SNI_NO_MATCH;
2473 }
2474 }
2475 else if (ech != NULL && ech->sniState == ECH_OUTER_SNI &&
2476 ech->privateName == NULL && sni != NULL){
2477 /* save the private SNI before it is overwritten by the public SNI */
2478 privateNameLen = (word16)XSTRLEN(sni->data.host_name) + 1;
2479 ech->privateName = (char*)XMALLOC(privateNameLen, ssl->heap,
2480 DYNAMIC_TYPE_TMP_BUFFER);
2481 if (ech->privateName == NULL)
2482 return MEMORY_E;
2483 XMEMCPY((char*)ech->privateName, sni->data.host_name,
2484 privateNameLen);
2485 }
2486#endif
2487
2488#if defined(WOLFSSL_TLS13)
2489 /* Don't process the second ClientHello SNI extension if there
2490 * was problems with the first.
2491 */
2492 if (!cacheOnly && sni != NULL && sni->status != WOLFSSL_SNI_NO_MATCH)
2493 return 0;
2494#endif
2495
2496#if defined(HAVE_ECH)
2497 if (ech != NULL && ech->sniState == ECH_INNER_SNI_ATTEMPT &&
2498 ech->privateName != NULL) {
2499 matched = cacheOnly || (XSTRLEN(ech->privateName) == size &&
2500 XSTRNCMP(ech->privateName, (const char*)input + offset, size) == 0);
2501 }
2502 else
2503#endif
2504 {
2505 const char* hostName = (sni != NULL) ? sni->data.host_name : NULL;
2506 matched = cacheOnly || (hostName != NULL &&
2507 XSTRLEN(hostName) == size &&
2508 XSTRNCMP(hostName, (const char*)input + offset, size) == 0);
2509 }
2510
2511#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
2512 if (!matched && ech != NULL && ech->sniState == ECH_OUTER_SNI) {
2513 workingConfig = ech->echConfig;
2514 while (workingConfig != NULL) {
2515 matched = XSTRLEN(workingConfig->publicName) == size &&
2516 XSTRNCMP(workingConfig->publicName,
2517 (const char*)input + offset, size) == 0;
2518
2519 if (matched)
2520 break;
2521
2522 workingConfig = workingConfig->next;
2523 }
2524 }
2525#endif
2526
2527 if (matched ||
2528 (sni != NULL && (sni->options & WOLFSSL_SNI_ANSWER_ON_MISMATCH))) {
2529 int matchStat;
2530 int r = TLSX_UseSNI(&ssl->extensions, type, input + offset, size,
2531 ssl->heap);
2532
2533 if (r != WOLFSSL_SUCCESS)
2534 return r; /* throws error. */
2535
2536 if (cacheOnly) {
2537 WOLFSSL_MSG("Forcing storage of SNI, Fake match");
2538 matchStat = WOLFSSL_SNI_FORCE_KEEP;
2539 }
2540 else if (matched) {
2541 WOLFSSL_MSG("SNI did match!");
2542 matchStat = WOLFSSL_SNI_REAL_MATCH;
2543 }
2544 else {
2545 WOLFSSL_MSG("fake SNI match from ANSWER_ON_MISMATCH");
2546 matchStat = WOLFSSL_SNI_FAKE_MATCH;
2547 }
2548
2549 TLSX_SNI_SetStatus(ssl->extensions, type, (byte)matchStat);
2550
2551 if (!cacheOnly)
2552 TLSX_SetResponse(ssl, TLSX_SERVER_NAME);
2553 }
2554 else if ((sni == NULL) ||
2555 !(sni->options & WOLFSSL_SNI_CONTINUE_ON_MISMATCH)) {
2556 SendAlert(ssl, alert_fatal, unrecognized_name);
2557 WOLFSSL_ERROR_VERBOSE(UNKNOWN_SNI_HOST_NAME_E);
2558 return UNKNOWN_SNI_HOST_NAME_E;
2559 }
2560#else
2561 (void)input;
2562#endif /* !NO_WOLFSSL_SERVER */
2563
2564#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
2565 (void)length;
2566#endif
2567
2568 return 0;
2569}
2570
2571static int TLSX_SNI_VerifyParse(WOLFSSL* ssl, byte isRequest)
2572{
2573 (void)ssl;
2574
2575 if (isRequest) {
2576 #ifndef NO_WOLFSSL_SERVER
2577 TLSX* ctx_ext = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
2578 TLSX* ssl_ext = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
2579 SNI* ctx_sni = ctx_ext ? (SNI*)ctx_ext->data : NULL;
2580 SNI* ssl_sni = ssl_ext ? (SNI*)ssl_ext->data : NULL;
2581 SNI* sni = NULL;
2582
2583 for (; ctx_sni; ctx_sni = ctx_sni->next) {
2584 if (ctx_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
2585 sni = TLSX_SNI_Find(ssl_sni, ctx_sni->type);
2586
2587 if (sni) {
2588 if (sni->status != WOLFSSL_SNI_NO_MATCH)
2589 continue;
2590
2591 /* if ssl level overrides ctx level, it is ok. */
2592 if ((sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) == 0)
2593 continue;
2594 }
2595
2596 SendAlert(ssl, alert_fatal, handshake_failure);
2597 WOLFSSL_ERROR_VERBOSE(SNI_ABSENT_ERROR);
2598 return SNI_ABSENT_ERROR;
2599 }
2600 }
2601
2602 for (; ssl_sni; ssl_sni = ssl_sni->next) {
2603 if (ssl_sni->options & WOLFSSL_SNI_ABORT_ON_ABSENCE) {
2604 if (ssl_sni->status != WOLFSSL_SNI_NO_MATCH)
2605 continue;
2606
2607 SendAlert(ssl, alert_fatal, handshake_failure);
2608 WOLFSSL_ERROR_VERBOSE(SNI_ABSENT_ERROR);
2609 return SNI_ABSENT_ERROR;
2610 }
2611 }
2612 #endif /* NO_WOLFSSL_SERVER */
2613 }
2614
2615 return 0;
2616}
2617
2618int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size,
2619 void* heap)
2620{
2621 TLSX* extension;
2622 SNI* sni = NULL;
2623
2624 if (extensions == NULL || data == NULL)
2625 return BAD_FUNC_ARG;
2626
2627 if ((type == WOLFSSL_SNI_HOST_NAME) && (size >= WOLFSSL_HOST_NAME_MAX))
2628 return BAD_LENGTH_E;
2629
2630 if ((sni = TLSX_SNI_New(type, data, size, heap)) == NULL)
2631 return MEMORY_E;
2632
2633 extension = TLSX_Find(*extensions, TLSX_SERVER_NAME);
2634 if (!extension) {
2635 int ret = TLSX_Push(extensions, TLSX_SERVER_NAME, (void*)sni, heap);
2636
2637 if (ret != 0) {
2638 TLSX_SNI_Free(sni, heap);
2639 return ret;
2640 }
2641 }
2642 else {
2643 /* push new SNI object to extension data. */
2644 sni->next = (SNI*)extension->data;
2645 extension->data = (void*)sni;
2646
2647 /* remove duplicate SNI, there should be only one of each type. */
2648 do {
2649 if (sni->next && sni->next->type == type) {
2650 SNI* next = sni->next;
2651
2652 sni->next = next->next;
2653 TLSX_SNI_Free(next, heap);
2654
2655 /* there is no way to occur more than
2656 * two SNIs of the same type.
2657 */
2658 break;
2659 }
2660 } while ((sni = sni->next));
2661 }
2662
2663 return WOLFSSL_SUCCESS;
2664}
2665
2666#ifndef NO_WOLFSSL_SERVER
2667
2668/** Tells the SNI requested by the client. */
2669word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data,
2670 byte ignoreStatus)
2671{
2672 TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
2673 SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
2674
2675 if (sni && (ignoreStatus || sni->status != WOLFSSL_SNI_NO_MATCH)) {
2676 switch (sni->type) {
2677 case WOLFSSL_SNI_HOST_NAME:
2678 if (data) {
2679 *data = sni->data.host_name;
2680 return (word16)XSTRLEN((char*)*data);
2681 }
2682 }
2683 }
2684
2685 return 0;
2686}
2687
2688/** Sets the options for a SNI object. */
2689void TLSX_SNI_SetOptions(TLSX* extensions, byte type, byte options)
2690{
2691 TLSX* extension = TLSX_Find(extensions, TLSX_SERVER_NAME);
2692 SNI* sni = TLSX_SNI_Find(extension ? (SNI*)extension->data : NULL, type);
2693
2694 if (sni)
2695 sni->options = options;
2696}
2697
2698/** Retrieves a SNI request from a client hello buffer. */
2699int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
2700 byte type, byte* sni, word32* inOutSz)
2701{
2702 word32 offset = 0;
2703 word32 len32 = 0;
2704 word16 len16 = 0;
2705
2706 if (helloSz < RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + CLIENT_HELLO_FIRST)
2707 return INCOMPLETE_DATA;
2708
2709 /* TLS record header */
2710 if ((enum ContentType) clientHello[offset++] != handshake) {
2711
2712 /* checking for SSLv2.0 client hello according to: */
2713 /* http://tools.ietf.org/html/rfc4346#appendix-E.1 */
2714 if ((enum HandShakeType) clientHello[++offset] == client_hello) {
2715 offset += ENUM_LEN + VERSION_SZ; /* skip version */
2716
2717 ato16(clientHello + offset, &len16);
2718 offset += OPAQUE16_LEN;
2719
2720 if (len16 % 3) /* cipher_spec_length must be multiple of 3 */
2721 return BUFFER_ERROR;
2722
2723 ato16(clientHello + offset, &len16);
2724 /* Returning SNI_UNSUPPORTED do not increment offset here */
2725
2726 if (len16 != 0) /* session_id_length must be 0 */
2727 return BUFFER_ERROR;
2728
2729 WOLFSSL_ERROR_VERBOSE(SNI_UNSUPPORTED);
2730 return SNI_UNSUPPORTED;
2731 }
2732
2733 return BUFFER_ERROR;
2734 }
2735
2736 if (clientHello[offset++] != SSLv3_MAJOR)
2737 return BUFFER_ERROR;
2738
2739 if (clientHello[offset++] < TLSv1_MINOR) {
2740 WOLFSSL_ERROR_VERBOSE(SNI_UNSUPPORTED);
2741 return SNI_UNSUPPORTED;
2742 }
2743
2744 ato16(clientHello + offset, &len16);
2745 offset += OPAQUE16_LEN;
2746
2747 if (offset + len16 > helloSz)
2748 return INCOMPLETE_DATA;
2749
2750 /* Handshake header */
2751 if ((enum HandShakeType) clientHello[offset] != client_hello)
2752 return BUFFER_ERROR;
2753
2754 c24to32(clientHello + offset + 1, &len32);
2755 offset += HANDSHAKE_HEADER_SZ;
2756
2757 if (offset + len32 > helloSz)
2758 return BUFFER_ERROR;
2759
2760 /* client hello */
2761 offset += VERSION_SZ + RAN_LEN; /* version, random */
2762
2763 if (helloSz < offset + clientHello[offset])
2764 return BUFFER_ERROR;
2765
2766 offset += ENUM_LEN + clientHello[offset]; /* skip session id */
2767
2768 /* cypher suites */
2769 if (helloSz < offset + OPAQUE16_LEN)
2770 return BUFFER_ERROR;
2771
2772 ato16(clientHello + offset, &len16);
2773 offset += OPAQUE16_LEN;
2774
2775 if (helloSz < offset + len16)
2776 return BUFFER_ERROR;
2777
2778 offset += len16; /* skip cypher suites */
2779
2780 /* compression methods */
2781 if (helloSz < offset + 1)
2782 return BUFFER_ERROR;
2783
2784 if (helloSz < offset + clientHello[offset])
2785 return BUFFER_ERROR;
2786
2787 offset += ENUM_LEN + clientHello[offset]; /* skip compression methods */
2788
2789 /* extensions */
2790 if (helloSz < offset + OPAQUE16_LEN)
2791 return 0; /* no extensions in client hello. */
2792
2793 ato16(clientHello + offset, &len16);
2794 offset += OPAQUE16_LEN;
2795
2796 if (helloSz < offset + len16)
2797 return BUFFER_ERROR;
2798
2799 while (len16 >= OPAQUE16_LEN + OPAQUE16_LEN) {
2800 word16 extType;
2801 word16 extLen;
2802
2803 ato16(clientHello + offset, &extType);
2804 offset += OPAQUE16_LEN;
2805
2806 ato16(clientHello + offset, &extLen);
2807 offset += OPAQUE16_LEN;
2808
2809 if (helloSz < offset + extLen)
2810 return BUFFER_ERROR;
2811
2812 if (extType != TLSX_SERVER_NAME) {
2813 offset += extLen; /* skip extension */
2814 } else {
2815 word16 listLen;
2816
2817 if (extLen < OPAQUE16_LEN)
2818 return BUFFER_ERROR;
2819
2820 ato16(clientHello + offset, &listLen);
2821 offset += OPAQUE16_LEN;
2822
2823 if (helloSz < offset + listLen)
2824 return BUFFER_ERROR;
2825
2826 while (listLen > ENUM_LEN + OPAQUE16_LEN) {
2827 byte sniType = clientHello[offset++];
2828 word16 sniLen;
2829
2830 ato16(clientHello + offset, &sniLen);
2831 offset += OPAQUE16_LEN;
2832
2833 if (helloSz < offset + sniLen)
2834 return BUFFER_ERROR;
2835
2836 if (sniType != type) {
2837 offset += sniLen;
2838 listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
2839 continue;
2840 }
2841
2842 *inOutSz = min(sniLen, *inOutSz);
2843 XMEMCPY(sni, clientHello + offset, *inOutSz);
2844
2845 return WOLFSSL_SUCCESS;
2846 }
2847 }
2848
2849 len16 -= min(2 * OPAQUE16_LEN + extLen, len16);
2850 }
2851
2852 return len16 ? BUFFER_ERROR : 0;
2853}
2854
2855#endif
2856
2857#define SNI_FREE_ALL TLSX_SNI_FreeAll
2858#define SNI_GET_SIZE TLSX_SNI_GetSize
2859#define SNI_WRITE TLSX_SNI_Write
2860#define SNI_PARSE TLSX_SNI_Parse
2861#define SNI_VERIFY_PARSE TLSX_SNI_VerifyParse
2862
2863#else
2864
2865#define SNI_FREE_ALL(list, heap) WC_DO_NOTHING
2866#define SNI_GET_SIZE(list) 0
2867#define SNI_WRITE(a, b) 0
2868#define SNI_PARSE(a, b, c, d) 0
2869#define SNI_VERIFY_PARSE(a, b) 0
2870
2871#endif /* HAVE_SNI */
2872
2873/******************************************************************************/
2874/* Trusted CA Key Indication */
2875/******************************************************************************/
2876
2877#ifdef HAVE_TRUSTED_CA
2878
2879/** Creates a new TCA object. */
2880static TCA* TLSX_TCA_New(byte type, const byte* id, word16 idSz, void* heap)
2881{
2882 TCA* tca = (TCA*)XMALLOC(sizeof(TCA), heap, DYNAMIC_TYPE_TLSX);
2883
2884 if (tca) {
2885 XMEMSET(tca, 0, sizeof(TCA));
2886 tca->type = type;
2887
2888 switch (type) {
2889 case WOLFSSL_TRUSTED_CA_PRE_AGREED:
2890 break;
2891
2892 #ifndef NO_SHA
2893 case WOLFSSL_TRUSTED_CA_KEY_SHA1:
2894 case WOLFSSL_TRUSTED_CA_CERT_SHA1:
2895 if (idSz == WC_SHA_DIGEST_SIZE &&
2896 (tca->id =
2897 (byte*)XMALLOC(idSz, heap, DYNAMIC_TYPE_TLSX))) {
2898 XMEMCPY(tca->id, id, idSz);
2899 tca->idSz = idSz;
2900 }
2901 else {
2902 XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
2903 tca = NULL;
2904 }
2905 break;
2906 #endif
2907
2908 case WOLFSSL_TRUSTED_CA_X509_NAME:
2909 if (idSz > 0 &&
2910 (tca->id =
2911 (byte*)XMALLOC(idSz, heap, DYNAMIC_TYPE_TLSX))) {
2912 XMEMCPY(tca->id, id, idSz);
2913 tca->idSz = idSz;
2914 }
2915 else {
2916 XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
2917 tca = NULL;
2918 }
2919 break;
2920
2921 default: /* invalid type */
2922 XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
2923 tca = NULL;
2924 }
2925 }
2926
2927 (void)heap;
2928
2929 return tca;
2930}
2931
2932/** Releases a TCA object. */
2933static void TLSX_TCA_Free(TCA* tca, void* heap)
2934{
2935 (void)heap;
2936
2937 if (tca) {
2938 XFREE(tca->id, heap, DYNAMIC_TYPE_TLSX);
2939 XFREE(tca, heap, DYNAMIC_TYPE_TLSX);
2940 }
2941}
2942
2943/** Releases all TCA objects in the provided list. */
2944static void TLSX_TCA_FreeAll(TCA* list, void* heap)
2945{
2946 TCA* tca;
2947
2948 while ((tca = list)) {
2949 list = tca->next;
2950 TLSX_TCA_Free(tca, heap);
2951 }
2952}
2953
2954/** Tells the buffered size of the TCA objects in a list. */
2955static word16 TLSX_TCA_GetSize(TCA* list)
2956{
2957 TCA* tca;
2958 word32 length = OPAQUE16_LEN; /* list length */
2959
2960 while ((tca = list)) {
2961 list = tca->next;
2962
2963 length += ENUM_LEN; /* tca type */
2964
2965 switch (tca->type) {
2966 case WOLFSSL_TRUSTED_CA_PRE_AGREED:
2967 break;
2968 case WOLFSSL_TRUSTED_CA_KEY_SHA1:
2969 case WOLFSSL_TRUSTED_CA_CERT_SHA1:
2970 length += tca->idSz;
2971 break;
2972 case WOLFSSL_TRUSTED_CA_X509_NAME:
2973 length += OPAQUE16_LEN + tca->idSz;
2974 break;
2975 }
2976
2977 if (length > WOLFSSL_MAX_16BIT) {
2978 return 0;
2979 }
2980 }
2981
2982 return (word16)length;
2983}
2984
2985/** Writes the TCA objects of a list in a buffer. */
2986static word16 TLSX_TCA_Write(TCA* list, byte* output)
2987{
2988 TCA* tca;
2989 word16 offset = OPAQUE16_LEN; /* list length offset */
2990
2991 while ((tca = list)) {
2992 list = tca->next;
2993
2994 output[offset++] = tca->type; /* tca type */
2995
2996 switch (tca->type) {
2997 case WOLFSSL_TRUSTED_CA_PRE_AGREED:
2998 break;
2999 #ifndef NO_SHA
3000 case WOLFSSL_TRUSTED_CA_KEY_SHA1:
3001 case WOLFSSL_TRUSTED_CA_CERT_SHA1:
3002 if (tca->id != NULL) {
3003 XMEMCPY(output + offset, tca->id, tca->idSz);
3004 offset += tca->idSz;
3005 }
3006 else {
3007 /* ID missing. Set to an empty string. */
3008 c16toa(0, output + offset);
3009 offset += OPAQUE16_LEN;
3010 }
3011 break;
3012 #endif
3013 case WOLFSSL_TRUSTED_CA_X509_NAME:
3014 if (tca->id != NULL) {
3015 c16toa(tca->idSz, output + offset); /* tca length */
3016 offset += OPAQUE16_LEN;
3017 XMEMCPY(output + offset, tca->id, tca->idSz);
3018 offset += tca->idSz;
3019 }
3020 else {
3021 /* ID missing. Set to an empty string. */
3022 c16toa(0, output + offset);
3023 offset += OPAQUE16_LEN;
3024 }
3025 break;
3026 default:
3027 /* ID unknown. Set to an empty string. */
3028 c16toa(0, output + offset);
3029 offset += OPAQUE16_LEN;
3030 }
3031 }
3032
3033 c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
3034
3035 return offset;
3036}
3037
3038#ifndef NO_WOLFSSL_SERVER
3039static TCA* TLSX_TCA_Find(TCA *list, byte type, const byte* id, word16 idSz)
3040{
3041 TCA* tca = list;
3042
3043 while (tca) {
3044 if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED)
3045 break;
3046 if (tca->type == type && idSz == tca->idSz &&
3047 XMEMCMP(id, tca->id, idSz) == 0)
3048 break;
3049 tca = tca->next;
3050 }
3051
3052 return tca;
3053}
3054#endif /* NO_WOLFSSL_SERVER */
3055
3056/** Parses a buffer of TCA extensions. */
3057static int TLSX_TCA_Parse(WOLFSSL* ssl, const byte* input, word16 length,
3058 byte isRequest)
3059{
3060#ifndef NO_WOLFSSL_SERVER
3061 word16 size = 0;
3062 word16 offset = 0;
3063#endif
3064
3065 TLSX *extension = TLSX_Find(ssl->extensions, TLSX_TRUSTED_CA_KEYS);
3066
3067 if (!extension)
3068 extension = TLSX_Find(ssl->ctx->extensions, TLSX_TRUSTED_CA_KEYS);
3069
3070 if (!isRequest) {
3071 #ifndef NO_WOLFSSL_CLIENT
3072 if (!extension || !extension->data)
3073 return TLSX_HandleUnsupportedExtension(ssl);
3074
3075 if (length > 0)
3076 return BUFFER_ERROR; /* TCA response MUST be empty. */
3077
3078 /* Set the flag that we're good for keys */
3079 TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS);
3080
3081 return 0;
3082 #endif
3083 }
3084
3085#ifndef NO_WOLFSSL_SERVER
3086 if (!extension || !extension->data) {
3087 /* Skipping, TCA not enabled at server side. */
3088 return 0;
3089 }
3090
3091 if (OPAQUE16_LEN > length)
3092 return BUFFER_ERROR;
3093
3094 ato16(input, &size);
3095 offset += OPAQUE16_LEN;
3096
3097 /* validating tca list length */
3098 if (length != OPAQUE16_LEN + size)
3099 return BUFFER_ERROR;
3100
3101 for (size = 0; offset < length; offset += size) {
3102 TCA *tca = NULL;
3103 byte type;
3104 const byte* id = NULL;
3105 word16 idSz = 0;
3106
3107 if (offset + ENUM_LEN > length)
3108 return BUFFER_ERROR;
3109
3110 type = input[offset++];
3111
3112 switch (type) {
3113 case WOLFSSL_TRUSTED_CA_PRE_AGREED:
3114 break;
3115 #ifndef NO_SHA
3116 case WOLFSSL_TRUSTED_CA_KEY_SHA1:
3117 case WOLFSSL_TRUSTED_CA_CERT_SHA1:
3118 if (offset + WC_SHA_DIGEST_SIZE > length)
3119 return BUFFER_ERROR;
3120 idSz = WC_SHA_DIGEST_SIZE;
3121 id = input + offset;
3122 offset += idSz;
3123 break;
3124 #endif
3125 case WOLFSSL_TRUSTED_CA_X509_NAME:
3126 if (offset + OPAQUE16_LEN > length)
3127 return BUFFER_ERROR;
3128 ato16(input + offset, &idSz);
3129 offset += OPAQUE16_LEN;
3130 if ((offset > length) || (idSz > length - offset))
3131 return BUFFER_ERROR;
3132 id = input + offset;
3133 offset += idSz;
3134 break;
3135 default:
3136 WOLFSSL_ERROR_VERBOSE(TCA_INVALID_ID_TYPE);
3137 return TCA_INVALID_ID_TYPE;
3138 }
3139
3140 /* Find the type/ID in the TCA list. */
3141 tca = TLSX_TCA_Find((TCA*)extension->data, type, id, idSz);
3142 if (tca != NULL) {
3143 /* Found it. Set the response flag and break out of the loop. */
3144 TLSX_SetResponse(ssl, TLSX_TRUSTED_CA_KEYS);
3145 break;
3146 }
3147 }
3148#else
3149 (void)input;
3150#endif
3151
3152 return 0;
3153}
3154
3155/* Checks to see if the server sent a response for the TCA. */
3156static int TLSX_TCA_VerifyParse(WOLFSSL* ssl, byte isRequest)
3157{
3158 (void)ssl;
3159
3160 if (!isRequest) {
3161 /* RFC 6066 section 6 states that the server responding
3162 * to trusted_ca_keys is optional. Do not error out unless
3163 * opted into with the define WOLFSSL_REQUIRE_TCA. */
3164 #if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_REQUIRE_TCA)
3165 TLSX* extension = TLSX_Find(ssl->extensions, TLSX_TRUSTED_CA_KEYS);
3166
3167 if (extension && !extension->resp) {
3168 SendAlert(ssl, alert_fatal, handshake_failure);
3169 WOLFSSL_ERROR_VERBOSE(TCA_ABSENT_ERROR);
3170 return TCA_ABSENT_ERROR;
3171 }
3172 #else
3173 WOLFSSL_MSG("No response received for trusted_ca_keys. Continuing.");
3174 #endif /* !NO_WOLFSSL_CLIENT && WOLFSSL_REQUIRE_TCA */
3175 }
3176
3177 return 0;
3178}
3179
3180int TLSX_UseTrustedCA(TLSX** extensions, byte type,
3181 const byte* id, word16 idSz, void* heap)
3182{
3183 TLSX* extension;
3184 TCA* tca = NULL;
3185
3186 if (extensions == NULL)
3187 return BAD_FUNC_ARG;
3188
3189 if ((tca = TLSX_TCA_New(type, id, idSz, heap)) == NULL)
3190 return MEMORY_E;
3191
3192 extension = TLSX_Find(*extensions, TLSX_TRUSTED_CA_KEYS);
3193 if (!extension) {
3194 int ret = TLSX_Push(extensions, TLSX_TRUSTED_CA_KEYS, (void*)tca, heap);
3195
3196 if (ret != 0) {
3197 TLSX_TCA_Free(tca, heap);
3198 return ret;
3199 }
3200 }
3201 else {
3202 /* push new TCA object to extension data. */
3203 tca->next = (TCA*)extension->data;
3204 extension->data = (void*)tca;
3205 }
3206
3207 return WOLFSSL_SUCCESS;
3208}
3209
3210#define TCA_FREE_ALL TLSX_TCA_FreeAll
3211#define TCA_GET_SIZE TLSX_TCA_GetSize
3212#define TCA_WRITE TLSX_TCA_Write
3213#define TCA_PARSE TLSX_TCA_Parse
3214#define TCA_VERIFY_PARSE TLSX_TCA_VerifyParse
3215
3216#else /* HAVE_TRUSTED_CA */
3217
3218#define TCA_FREE_ALL(list, heap) WC_DO_NOTHING
3219#define TCA_GET_SIZE(list) 0
3220#define TCA_WRITE(a, b) 0
3221#define TCA_PARSE(a, b, c, d) 0
3222#define TCA_VERIFY_PARSE(a, b) 0
3223
3224#endif /* HAVE_TRUSTED_CA */
3225
3226/******************************************************************************/
3227/* Max Fragment Length Negotiation */
3228/******************************************************************************/
3229
3230#ifdef HAVE_MAX_FRAGMENT
3231
3232static word16 TLSX_MFL_Write(byte* data, byte* output)
3233{
3234 output[0] = data[0];
3235
3236 return ENUM_LEN;
3237}
3238
3239static int TLSX_MFL_Parse(WOLFSSL* ssl, const byte* input, word16 length,
3240 byte isRequest)
3241{
3242 if (length != ENUM_LEN)
3243 return BUFFER_ERROR;
3244
3245#ifdef WOLFSSL_OLD_UNSUPPORTED_EXTENSION
3246 (void) isRequest;
3247#else
3248 if (!isRequest)
3249 if (TLSX_CheckUnsupportedExtension(ssl, TLSX_MAX_FRAGMENT_LENGTH))
3250 return TLSX_HandleUnsupportedExtension(ssl);
3251#endif
3252
3253 switch (*input) {
3254 case WOLFSSL_MFL_2_8 : ssl->max_fragment = 256; break;
3255 case WOLFSSL_MFL_2_9 : ssl->max_fragment = 512; break;
3256 case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
3257 case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
3258 case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
3259 case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
3260
3261 default:
3262 SendAlert(ssl, alert_fatal, illegal_parameter);
3263 WOLFSSL_ERROR_VERBOSE(UNKNOWN_MAX_FRAG_LEN_E);
3264 return UNKNOWN_MAX_FRAG_LEN_E;
3265 }
3266 if (ssl->session != NULL) {
3267 ssl->session->mfl = *input;
3268 }
3269
3270#ifndef NO_WOLFSSL_SERVER
3271 if (isRequest) {
3272 int ret = TLSX_UseMaxFragment(&ssl->extensions, *input, ssl->heap);
3273
3274 if (ret != WOLFSSL_SUCCESS)
3275 return ret; /* throw error */
3276
3277 TLSX_SetResponse(ssl, TLSX_MAX_FRAGMENT_LENGTH);
3278 }
3279#endif
3280
3281 return 0;
3282}
3283
3284int TLSX_UseMaxFragment(TLSX** extensions, byte mfl, void* heap)
3285{
3286 byte* data = NULL;
3287 int ret = 0;
3288
3289 if (extensions == NULL || mfl < WOLFSSL_MFL_MIN || mfl > WOLFSSL_MFL_MAX)
3290 return BAD_FUNC_ARG;
3291
3292 data = (byte*)XMALLOC(ENUM_LEN, heap, DYNAMIC_TYPE_TLSX);
3293 if (data == NULL)
3294 return MEMORY_E;
3295
3296 data[0] = mfl;
3297
3298 ret = TLSX_Push(extensions, TLSX_MAX_FRAGMENT_LENGTH, data, heap);
3299 if (ret != 0) {
3300 XFREE(data, heap, DYNAMIC_TYPE_TLSX);
3301 return ret;
3302 }
3303
3304 return WOLFSSL_SUCCESS;
3305}
3306
3307
3308#define MFL_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX)
3309#define MFL_GET_SIZE(data) ENUM_LEN
3310#define MFL_WRITE TLSX_MFL_Write
3311#define MFL_PARSE TLSX_MFL_Parse
3312
3313#else
3314
3315#define MFL_FREE_ALL(a, b) WC_DO_NOTHING
3316#define MFL_GET_SIZE(a) 0
3317#define MFL_WRITE(a, b) 0
3318#define MFL_PARSE(a, b, c, d) 0
3319
3320#endif /* HAVE_MAX_FRAGMENT */
3321
3322/******************************************************************************/
3323/* Truncated HMAC */
3324/******************************************************************************/
3325
3326#ifdef HAVE_TRUNCATED_HMAC
3327
3328static int TLSX_THM_Parse(WOLFSSL* ssl, const byte* input, word16 length,
3329 byte isRequest)
3330{
3331 if (length != 0 || input == NULL)
3332 return BUFFER_ERROR;
3333
3334 if (!isRequest) {
3335 #ifndef WOLFSSL_OLD_UNSUPPORTED_EXTENSION
3336 if (TLSX_CheckUnsupportedExtension(ssl, TLSX_TRUNCATED_HMAC))
3337 return TLSX_HandleUnsupportedExtension(ssl);
3338 #endif
3339 }
3340 else {
3341 #ifndef NO_WOLFSSL_SERVER
3342 int ret = TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
3343
3344 if (ret != WOLFSSL_SUCCESS)
3345 return ret; /* throw error */
3346
3347 TLSX_SetResponse(ssl, TLSX_TRUNCATED_HMAC);
3348 #endif
3349 }
3350
3351 ssl->truncated_hmac = 1;
3352
3353 return 0;
3354}
3355
3356int TLSX_UseTruncatedHMAC(TLSX** extensions, void* heap)
3357{
3358 int ret = 0;
3359
3360 if (extensions == NULL)
3361 return BAD_FUNC_ARG;
3362
3363 ret = TLSX_Push(extensions, TLSX_TRUNCATED_HMAC, NULL, heap);
3364 if (ret != 0)
3365 return ret;
3366
3367 return WOLFSSL_SUCCESS;
3368}
3369
3370#define THM_PARSE TLSX_THM_Parse
3371
3372#else
3373
3374#define THM_PARSE(a, b, c, d) 0
3375
3376#endif /* HAVE_TRUNCATED_HMAC */
3377
3378/******************************************************************************/
3379/* Certificate Status Request */
3380/******************************************************************************/
3381
3382#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
3383
3384static void TLSX_CSR_Free(CertificateStatusRequest* csr, void* heap)
3385{
3386 int i;
3387
3388 switch (csr->status_type) {
3389 case WOLFSSL_CSR_OCSP:
3390 for (i = 0; i <= csr->requests; i++) {
3391 FreeOcspRequest(&csr->request.ocsp[i]);
3392 }
3393 break;
3394 }
3395#ifdef WOLFSSL_TLS13
3396 for (i = 0; i < MAX_CERT_EXTENSIONS; i++) {
3397 if (csr->responses[i].buffer != NULL) {
3398 XFREE(csr->responses[i].buffer, heap,
3399 DYNAMIC_TYPE_TMP_BUFFER);
3400 }
3401 }
3402#endif
3403 XFREE(csr, heap, DYNAMIC_TYPE_TLSX);
3404 (void)heap;
3405}
3406
3407word16 TLSX_CSR_GetSize_ex(CertificateStatusRequest* csr, byte isRequest,
3408 int idx)
3409{
3410 word32 size = 0;
3411
3412 /* shut up compiler warnings */
3413 (void) csr; (void) isRequest;
3414#ifndef NO_WOLFSSL_CLIENT
3415 if (isRequest) {
3416 switch (csr->status_type) {
3417 case WOLFSSL_CSR_OCSP:
3418 size += ENUM_LEN + 2 * OPAQUE16_LEN;
3419
3420 if (csr->request.ocsp[0].nonceSz)
3421 size += OCSP_NONCE_EXT_SZ;
3422 break;
3423 }
3424 }
3425#endif
3426#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
3427 if (!isRequest && IsAtLeastTLSv1_3(csr->ssl->version)) {
3428 if (csr->ssl != NULL && SSL_CM(csr->ssl) != NULL &&
3429 SSL_CM(csr->ssl)->ocsp_stapling != NULL &&
3430 SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL) {
3431 if (WOLFSSL_MAX_16BIT - OPAQUE8_LEN - OPAQUE24_LEN <
3432 csr->ssl->ocspCsrResp[idx].length) {
3433 return 0;
3434 }
3435 size = OPAQUE8_LEN + OPAQUE24_LEN +
3436 csr->ssl->ocspCsrResp[idx].length;
3437 return (word16)size;
3438 }
3439 if (WOLFSSL_MAX_16BIT - OPAQUE8_LEN - OPAQUE24_LEN <
3440 csr->responses[idx].length) {
3441 return 0;
3442 }
3443 size = OPAQUE8_LEN + OPAQUE24_LEN + csr->responses[idx].length;
3444 return (word16)size;
3445 }
3446#else
3447 (void)idx;
3448#endif
3449 return (word16)size;
3450}
3451
3452#if (defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER))
3453int TLSX_CSR_SetResponseWithStatusCB(WOLFSSL *ssl)
3454{
3455 WOLFSSL_OCSP *ocsp;
3456 int ret;
3457
3458 if (ssl == NULL || SSL_CM(ssl) == NULL)
3459 return BAD_FUNC_ARG;
3460 ocsp = SSL_CM(ssl)->ocsp_stapling;
3461 if (ocsp == NULL || ocsp->statusCb == NULL)
3462 return BAD_FUNC_ARG;
3463 ret = ocsp->statusCb(ssl, ocsp->statusCbArg);
3464 switch (ret) {
3465 case WOLFSSL_OCSP_STATUS_CB_OK: {
3466 size_t i;
3467 for (i = 0; i < XELEM_CNT(ssl->ocspCsrResp); i++) {
3468 if (ssl->ocspCsrResp[i].length > 0) {
3469 /* ack the extension, status cb provided the response in
3470 * ssl->ocspCsrResp */
3471 TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST);
3472 ssl->status_request = WOLFSSL_CSR_OCSP;
3473 break;
3474 }
3475 }
3476 ret = 0;
3477 break;
3478 }
3479 case WOLFSSL_OCSP_STATUS_CB_NOACK:
3480 /* suppressing as not critical */
3481 ret = 0;
3482 break;
3483 case WOLFSSL_OCSP_STATUS_CB_ALERT_FATAL:
3484 default:
3485 ret = WOLFSSL_FATAL_ERROR;
3486 break;
3487 }
3488 return ret;
3489}
3490
3491static int TLSX_CSR_WriteWithStatusCB(CertificateStatusRequest* csr,
3492 byte* output, int idx)
3493{
3494 WOLFSSL *ssl = csr->ssl;
3495 WOLFSSL_OCSP *ocsp;
3496 word16 offset = 0;
3497 byte *response;
3498 int respSz;
3499
3500 if (ssl == NULL || SSL_CM(ssl) == NULL)
3501 return BAD_FUNC_ARG;
3502 ocsp = SSL_CM(ssl)->ocsp_stapling;
3503 if (ocsp == NULL || ocsp->statusCb == NULL)
3504 return BAD_FUNC_ARG;
3505 response = ssl->ocspCsrResp[idx].buffer;
3506 respSz = ssl->ocspCsrResp[idx].length;
3507 if (response == NULL || respSz == 0)
3508 return BAD_FUNC_ARG;
3509 output[offset++] = WOLFSSL_CSR_OCSP;
3510 c32to24(respSz, output + offset);
3511 offset += OPAQUE24_LEN;
3512 XMEMCPY(output + offset, response, respSz);
3513 return offset + respSz;
3514}
3515#endif /* (TLS13 && !NO_WOLFSLL_SERVER) */
3516
3517static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest)
3518{
3519 return TLSX_CSR_GetSize_ex(csr, isRequest, 0);
3520}
3521
3522int TLSX_CSR_Write_ex(CertificateStatusRequest* csr, byte* output,
3523 byte isRequest, int idx)
3524{
3525 /* shut up compiler warnings */
3526 (void) csr; (void) output; (void) isRequest;
3527
3528#ifndef NO_WOLFSSL_CLIENT
3529 if (isRequest) {
3530 int ret = 0;
3531 word16 offset = 0;
3532 word16 length = 0;
3533
3534 /* type */
3535 output[offset++] = csr->status_type;
3536
3537 switch (csr->status_type) {
3538 case WOLFSSL_CSR_OCSP:
3539 /* responder id list */
3540 c16toa(0, output + offset);
3541 offset += OPAQUE16_LEN;
3542
3543 /* request extensions */
3544 if (csr->request.ocsp[0].nonceSz) {
3545 ret = (int)EncodeOcspRequestExtensions(&csr->request.ocsp[0],
3546 output + offset + OPAQUE16_LEN,
3547 OCSP_NONCE_EXT_SZ);
3548
3549 if (ret > 0) {
3550 length = (word16)ret;
3551 }
3552 else {
3553 return ret;
3554 }
3555 }
3556
3557 c16toa(length, output + offset);
3558 offset += OPAQUE16_LEN + length;
3559
3560 break;
3561 }
3562
3563 return (int)offset;
3564 }
3565#endif
3566#if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)
3567 if (!isRequest && IsAtLeastTLSv1_3(csr->ssl->version)) {
3568 word16 offset = 0;
3569 if (csr->ssl != NULL && SSL_CM(csr->ssl) != NULL &&
3570 SSL_CM(csr->ssl)->ocsp_stapling != NULL &&
3571 SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL) {
3572 return TLSX_CSR_WriteWithStatusCB(csr, output, idx);
3573 }
3574 output[offset++] = csr->status_type;
3575 c32to24(csr->responses[idx].length, output + offset);
3576 offset += OPAQUE24_LEN;
3577 XMEMCPY(output + offset, csr->responses[idx].buffer,
3578 csr->responses[idx].length);
3579 offset += (word16)csr->responses[idx].length;
3580 return offset;
3581 }
3582#else
3583 (void)idx;
3584#endif
3585
3586 return 0;
3587}
3588
3589static int TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
3590 byte isRequest)
3591{
3592 return TLSX_CSR_Write_ex(csr, output, isRequest, 0);
3593}
3594
3595#if !defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
3596 defined(WOLFSSL_TLS_OCSP_MULTI)
3597/* Process OCSP request certificate chain
3598 *
3599 * ssl SSL/TLS object.
3600 * returns 0 on success, otherwise failure.
3601 */
3602int ProcessChainOCSPRequest(WOLFSSL* ssl)
3603{
3604 DecodedCert* cert;
3605 OcspRequest* request;
3606 TLSX* extension;
3607 CertificateStatusRequest* csr;
3608 DerBuffer* chain;
3609 word32 pos = 0;
3610 buffer der;
3611 int i = 1;
3612 int ret = 0;
3613 byte ctxOwnsRequest = 0;
3614
3615 /* use certChain if available, otherwise use peer certificate */
3616 chain = ssl->buffers.certChain;
3617 if (chain == NULL) {
3618 chain = ssl->buffers.certificate;
3619 }
3620
3621 extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
3622 csr = extension ?
3623 (CertificateStatusRequest*)extension->data : NULL;
3624 if (csr == NULL)
3625 return MEMORY_ERROR;
3626
3627 cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap,
3628 DYNAMIC_TYPE_DCERT);
3629 if (cert == NULL) {
3630 return MEMORY_E;
3631 }
3632
3633 if (chain && chain->buffer) {
3634 while (ret == 0 && pos + OPAQUE24_LEN < chain->length) {
3635 if (i >= MAX_CERT_EXTENSIONS) {
3636 WOLFSSL_MSG_EX(
3637 "OCSP request cert chain exceeds maximum length: "
3638 "i=%d, MAX_CERT_EXTENSIONS=%d", i, MAX_CERT_EXTENSIONS);
3639 ret = MAX_CERT_EXTENSIONS_ERR;
3640 break;
3641 }
3642
3643 c24to32(chain->buffer + pos, &der.length);
3644 pos += OPAQUE24_LEN;
3645 der.buffer = chain->buffer + pos;
3646 pos += der.length;
3647
3648 if (pos > chain->length)
3649 break;
3650 request = &csr->request.ocsp[i];
3651 if (ret == 0) {
3652 ret = CreateOcspRequest(ssl, request, cert,
3653 der.buffer, der.length, &ctxOwnsRequest);
3654 if (ctxOwnsRequest) {
3655 wolfSSL_Mutex* ocspLock =
3656 &SSL_CM(ssl)->ocsp_stapling->ocspLock;
3657 if (wc_LockMutex(ocspLock) == 0) {
3658 /* the request is ours */
3659 ssl->ctx->certOcspRequest = NULL;
3660 }
3661 wc_UnLockMutex(ocspLock);
3662 }
3663 }
3664
3665 if (ret == 0) {
3666 request->ssl = ssl;
3667 ret = CheckOcspRequest(SSL_CM(ssl)->ocsp_stapling,
3668 request, &csr->responses[i], ssl->heap);
3669 /* Suppressing, not critical */
3670 if (ret == WC_NO_ERR_TRACE(OCSP_CERT_REVOKED) ||
3671 ret == WC_NO_ERR_TRACE(OCSP_CERT_UNKNOWN) ||
3672 ret == WC_NO_ERR_TRACE(OCSP_LOOKUP_FAIL)) {
3673 ret = 0;
3674 }
3675 i++;
3676 csr->requests++;
3677 }
3678 }
3679 }
3680 XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
3681
3682 return ret;
3683}
3684#endif
3685
3686static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length,
3687 byte isRequest)
3688{
3689 int ret;
3690#if !defined(NO_WOLFSSL_SERVER)
3691 byte status_type;
3692 word16 size = 0;
3693#endif
3694
3695#if !defined(NO_WOLFSSL_CLIENT)
3696 OcspRequest* request;
3697 TLSX* extension;
3698 CertificateStatusRequest* csr;
3699#endif
3700
3701#if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_TLS13) \
3702 || !defined(NO_WOLFSSL_SERVER)
3703 word32 offset = 0;
3704#endif
3705
3706#if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_TLS13)
3707 word32 resp_length = 0;
3708#endif
3709
3710 /* shut up compiler warnings */
3711 (void) ssl; (void) input;
3712
3713 if (!isRequest) {
3714#ifndef NO_WOLFSSL_CLIENT
3715 extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
3716 csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
3717
3718 if (!csr) {
3719 /* look at context level */
3720 extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST);
3721 csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
3722
3723 if (!csr) /* unexpected extension */
3724 return TLSX_HandleUnsupportedExtension(ssl);
3725
3726 /* enable extension at ssl level */
3727 ret = TLSX_UseCertificateStatusRequest(&ssl->extensions,
3728 csr->status_type, csr->options, ssl,
3729 ssl->heap, ssl->devId);
3730 if (ret != WOLFSSL_SUCCESS)
3731 return ret == 0 ? -1 : ret;
3732
3733 switch (csr->status_type) {
3734 case WOLFSSL_CSR_OCSP:
3735 /* propagate nonce */
3736 if (csr->request.ocsp[0].nonceSz) {
3737 request =
3738 (OcspRequest*)TLSX_CSR_GetRequest(ssl->extensions);
3739
3740 if (request) {
3741 XMEMCPY(request->nonce, csr->request.ocsp[0].nonce,
3742 (size_t)csr->request.ocsp[0].nonceSz);
3743 request->nonceSz = csr->request.ocsp[0].nonceSz;
3744 }
3745 }
3746 break;
3747 }
3748 }
3749
3750 ssl->status_request = 1;
3751
3752 #ifdef WOLFSSL_TLS13
3753 if (ssl->options.tls1_3) {
3754 /* Get the new extension potentially created above. */
3755 extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
3756 csr = extension ? (CertificateStatusRequest*)extension->data : NULL;
3757 if (csr == NULL)
3758 return MEMORY_ERROR;
3759
3760 ret = 0;
3761 if (OPAQUE8_LEN + OPAQUE24_LEN > length)
3762 ret = BUFFER_ERROR;
3763 if (ret == 0 && input[offset++] != WOLFSSL_CSR_OCSP) {
3764 ret = BAD_CERTIFICATE_STATUS_ERROR;
3765 WOLFSSL_ERROR_VERBOSE(ret);
3766 }
3767 if (ret == 0) {
3768 c24to32(input + offset, &resp_length);
3769 offset += OPAQUE24_LEN;
3770 if (offset + resp_length != length)
3771 ret = BUFFER_ERROR;
3772 }
3773 if (ret == 0) {
3774 if (ssl->response_idx < (1 + MAX_CHAIN_DEPTH))
3775 csr->responses[ssl->response_idx].buffer =
3776 (byte*)XMALLOC(resp_length, ssl->heap,
3777 DYNAMIC_TYPE_TMP_BUFFER);
3778 else
3779 ret = BAD_FUNC_ARG;
3780
3781 if (ret == 0 &&
3782 csr->responses[ssl->response_idx].buffer == NULL)
3783 ret = MEMORY_ERROR;
3784 }
3785 if (ret == 0) {
3786 XMEMCPY(csr->responses[ssl->response_idx].buffer,
3787 input + offset, resp_length);
3788 csr->responses[ssl->response_idx].length = resp_length;
3789 }
3790
3791 return ret;
3792 }
3793 else
3794 #endif
3795 {
3796 /* extension_data MUST be empty. */
3797 return length ? BUFFER_ERROR : 0;
3798 }
3799#endif
3800 }
3801 else {
3802#ifndef NO_WOLFSSL_SERVER
3803 if (length == 0)
3804 return 0;
3805
3806 status_type = input[offset++];
3807
3808 switch (status_type) {
3809 case WOLFSSL_CSR_OCSP: {
3810
3811 /* skip responder_id_list */
3812 if ((int)(length - offset) < OPAQUE16_LEN)
3813 return BUFFER_ERROR;
3814
3815 ato16(input + offset, &size);
3816 offset += OPAQUE16_LEN + size;
3817
3818 /* skip request_extensions */
3819 if ((int)(length - offset) < OPAQUE16_LEN)
3820 return BUFFER_ERROR;
3821
3822 ato16(input + offset, &size);
3823 offset += OPAQUE16_LEN + size;
3824
3825 if (offset > length)
3826 return BUFFER_ERROR;
3827
3828 /* is able to send OCSP response? */
3829 if (SSL_CM(ssl) == NULL || !SSL_CM(ssl)->ocspStaplingEnabled)
3830 return 0;
3831 }
3832 break;
3833
3834 /* unknown status type */
3835 default:
3836 return 0;
3837 }
3838
3839 /* if using status_request and already sending it, skip this one */
3840 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
3841 if (ssl->status_request_v2)
3842 return 0;
3843 #endif
3844
3845 /* accept the first good status_type and return */
3846 ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
3847 0, ssl, ssl->heap, ssl->devId);
3848 if (ret != WOLFSSL_SUCCESS)
3849 return ret == 0 ? -1 : ret; /* throw error */
3850
3851 TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST);
3852 ssl->status_request = status_type;
3853#endif
3854 }
3855
3856 return 0;
3857}
3858
3859int TLSX_CSR_InitRequest_ex(TLSX* extensions, DecodedCert* cert,
3860 void* heap, int idx)
3861{
3862 TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
3863 CertificateStatusRequest* csr = extension ?
3864 (CertificateStatusRequest*)extension->data : NULL;
3865 int ret = 0;
3866
3867 if (csr) {
3868 switch (csr->status_type) {
3869 case WOLFSSL_CSR_OCSP: {
3870 byte nonce[MAX_OCSP_NONCE_SZ];
3871 int req_cnt = idx == -1 ? csr->requests : idx;
3872 int nonceSz = csr->request.ocsp[0].nonceSz;
3873 OcspRequest* request;
3874
3875 request = &csr->request.ocsp[req_cnt];
3876 if (request->serial != NULL) {
3877 /* clear request contents before reuse */
3878 FreeOcspRequest(request);
3879 if (csr->requests > 0)
3880 csr->requests--;
3881 }
3882 /* preserve nonce */
3883 XMEMCPY(nonce, csr->request.ocsp->nonce, (size_t)nonceSz);
3884
3885 if (req_cnt < MAX_CERT_EXTENSIONS) {
3886 if ((ret = InitOcspRequest(request, cert, 0, heap)) != 0)
3887 return ret;
3888
3889 /* restore nonce */
3890 XMEMCPY(csr->request.ocsp->nonce, nonce, (size_t)nonceSz);
3891 request->nonceSz = nonceSz;
3892 csr->requests++;
3893 }
3894 else {
3895 WOLFSSL_ERROR_VERBOSE(MAX_CERT_EXTENSIONS_ERR);
3896 return MAX_CERT_EXTENSIONS_ERR;
3897 }
3898 }
3899 break;
3900 }
3901 }
3902
3903 return ret;
3904}
3905
3906int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert, void* heap)
3907{
3908 return TLSX_CSR_InitRequest_ex(extensions, cert, heap, -1);
3909}
3910
3911void* TLSX_CSR_GetRequest_ex(TLSX* extensions, int idx)
3912{
3913 TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
3914 CertificateStatusRequest* csr = extension ?
3915 (CertificateStatusRequest*)extension->data : NULL;
3916
3917 if (csr && csr->ssl) {
3918 switch (csr->status_type) {
3919 case WOLFSSL_CSR_OCSP:
3920 if (IsAtLeastTLSv1_3(csr->ssl->version)) {
3921 return idx < csr->requests ? &csr->request.ocsp[idx] : NULL;
3922 }
3923 else {
3924 return idx == 0 ? &csr->request.ocsp[0] : NULL;
3925 }
3926 }
3927 }
3928
3929 return NULL;
3930}
3931
3932void* TLSX_CSR_GetRequest(TLSX* extensions)
3933{
3934 return TLSX_CSR_GetRequest_ex(extensions, 0);
3935}
3936
3937int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
3938{
3939 TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
3940 CertificateStatusRequest* csr = extension ?
3941 (CertificateStatusRequest*)extension->data : NULL;
3942
3943 if (csr) {
3944 switch (csr->status_type) {
3945 case WOLFSSL_CSR_OCSP:
3946 if (SSL_CM(ssl)->ocspEnabled) {
3947 csr->request.ocsp[0].ssl = ssl;
3948 return CheckOcspRequest(SSL_CM(ssl)->ocsp,
3949 &csr->request.ocsp[0], NULL, NULL);
3950 }
3951 else {
3952 WOLFSSL_ERROR_VERBOSE(OCSP_LOOKUP_FAIL);
3953 return OCSP_LOOKUP_FAIL;
3954 }
3955 }
3956 }
3957
3958 return 0;
3959}
3960
3961int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type,
3962 byte options, WOLFSSL* ssl, void* heap,
3963 int devId)
3964{
3965 CertificateStatusRequest* csr = NULL;
3966 int ret = 0;
3967
3968 if (!extensions || status_type != WOLFSSL_CSR_OCSP)
3969 return BAD_FUNC_ARG;
3970
3971 csr = (CertificateStatusRequest*)
3972 XMALLOC(sizeof(CertificateStatusRequest), heap, DYNAMIC_TYPE_TLSX);
3973 if (!csr)
3974 return MEMORY_E;
3975
3976 ForceZero(csr, sizeof(CertificateStatusRequest));
3977#if defined(WOLFSSL_TLS13)
3978 XMEMSET(csr->responses, 0, sizeof(csr->responses));
3979#endif
3980 csr->status_type = status_type;
3981 csr->options = options;
3982 csr->ssl = ssl;
3983
3984 switch (csr->status_type) {
3985 case WOLFSSL_CSR_OCSP:
3986 if (options & WOLFSSL_CSR_OCSP_USE_NONCE) {
3987 WC_RNG rng;
3988
3989 #ifndef HAVE_FIPS
3990 ret = wc_InitRng_ex(&rng, heap, devId);
3991 #else
3992 ret = wc_InitRng(&rng);
3993 (void)devId;
3994 #endif
3995 if (ret == 0) {
3996 if (wc_RNG_GenerateBlock(&rng, csr->request.ocsp[0].nonce,
3997 MAX_OCSP_NONCE_SZ) == 0)
3998 csr->request.ocsp[0].nonceSz = MAX_OCSP_NONCE_SZ;
3999
4000 wc_FreeRng(&rng);
4001 }
4002 }
4003 break;
4004 }
4005
4006 if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr, heap)) != 0) {
4007 XFREE(csr, heap, DYNAMIC_TYPE_TLSX);
4008 return ret;
4009 }
4010
4011 return WOLFSSL_SUCCESS;
4012}
4013
4014#define CSR_FREE_ALL TLSX_CSR_Free
4015#define CSR_GET_SIZE TLSX_CSR_GetSize
4016#define CSR_WRITE TLSX_CSR_Write
4017#define CSR_PARSE TLSX_CSR_Parse
4018
4019#else
4020
4021#define CSR_FREE_ALL(data, heap) WC_DO_NOTHING
4022#define CSR_GET_SIZE(a, b) 0
4023#define CSR_WRITE(a, b, c) 0
4024#define CSR_PARSE(a, b, c, d) 0
4025
4026#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
4027
4028/******************************************************************************/
4029/* Certificate Status Request v2 */
4030/******************************************************************************/
4031
4032#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
4033
4034static void TLSX_CSR2_FreePendingSigners(Signer *s, void* heap)
4035{
4036 Signer* next;
4037 while(s) {
4038 next = s->next;
4039 FreeSigner(s, heap);
4040 s = next;
4041 }
4042}
4043static void TLSX_CSR2_FreeAll(CertificateStatusRequestItemV2* csr2, void* heap)
4044{
4045 CertificateStatusRequestItemV2* next;
4046
4047 TLSX_CSR2_FreePendingSigners(csr2->pendingSigners, heap);
4048 for (; csr2; csr2 = next) {
4049 next = csr2->next;
4050
4051 switch (csr2->status_type) {
4052 case WOLFSSL_CSR2_OCSP:
4053 case WOLFSSL_CSR2_OCSP_MULTI:
4054 while(csr2->requests--)
4055 FreeOcspRequest(&csr2->request.ocsp[csr2->requests]);
4056 break;
4057 }
4058
4059 XFREE(csr2, heap, DYNAMIC_TYPE_TLSX);
4060 }
4061 (void)heap;
4062}
4063
4064static word16 TLSX_CSR2_GetSize(CertificateStatusRequestItemV2* csr2,
4065 byte isRequest)
4066{
4067 word32 size = 0;
4068
4069 /* shut up compiler warnings */
4070 (void) csr2; (void) isRequest;
4071
4072#ifndef NO_WOLFSSL_CLIENT
4073 if (isRequest) {
4074 CertificateStatusRequestItemV2* next;
4075
4076 for (size = OPAQUE16_LEN; csr2; csr2 = next) {
4077 next = csr2->next;
4078
4079 switch (csr2->status_type) {
4080 case WOLFSSL_CSR2_OCSP:
4081 case WOLFSSL_CSR2_OCSP_MULTI:
4082 size += ENUM_LEN + 3 * OPAQUE16_LEN;
4083
4084 if (csr2->request.ocsp[0].nonceSz)
4085 size += OCSP_NONCE_EXT_SZ;
4086 break;
4087 }
4088
4089 if (size > WOLFSSL_MAX_16BIT) {
4090 return 0;
4091 }
4092 }
4093 }
4094#endif
4095
4096 return (word16)size;
4097}
4098
4099static int TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2,
4100 byte* output, byte isRequest)
4101{
4102 /* shut up compiler warnings */
4103 (void) csr2; (void) output; (void) isRequest;
4104
4105#ifndef NO_WOLFSSL_CLIENT
4106 if (isRequest) {
4107 int ret = 0;
4108 word16 offset;
4109 word16 length;
4110
4111 for (offset = OPAQUE16_LEN; csr2 != NULL; csr2 = csr2->next) {
4112 /* status_type */
4113 output[offset++] = csr2->status_type;
4114
4115 /* request */
4116 switch (csr2->status_type) {
4117 case WOLFSSL_CSR2_OCSP:
4118 case WOLFSSL_CSR2_OCSP_MULTI:
4119 /* request_length */
4120 length = 2 * OPAQUE16_LEN;
4121
4122 if (csr2->request.ocsp[0].nonceSz)
4123 length += OCSP_NONCE_EXT_SZ;
4124
4125 c16toa(length, output + offset);
4126 offset += OPAQUE16_LEN;
4127
4128 /* responder id list */
4129 c16toa(0, output + offset);
4130 offset += OPAQUE16_LEN;
4131
4132 /* request extensions */
4133 length = 0;
4134
4135 if (csr2->request.ocsp[0].nonceSz) {
4136 ret = (int)EncodeOcspRequestExtensions(
4137 &csr2->request.ocsp[0],
4138 output + offset + OPAQUE16_LEN,
4139 OCSP_NONCE_EXT_SZ);
4140
4141 if (ret > 0) {
4142 length = (word16)ret;
4143 }
4144 else {
4145 return ret;
4146 }
4147 }
4148
4149 c16toa(length, output + offset);
4150 offset += OPAQUE16_LEN + length;
4151 break;
4152 }
4153 }
4154
4155 /* list size */
4156 c16toa(offset - OPAQUE16_LEN, output);
4157
4158 return (int)offset;
4159 }
4160#endif
4161
4162 return 0;
4163}
4164
4165static int TLSX_CSR2_Parse(WOLFSSL* ssl, const byte* input, word16 length,
4166 byte isRequest)
4167{
4168 int ret;
4169
4170 /* shut up compiler warnings */
4171 (void) ssl; (void) input;
4172
4173 if (!isRequest) {
4174#ifndef NO_WOLFSSL_CLIENT
4175 TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
4176 CertificateStatusRequestItemV2* csr2 = extension ?
4177 (CertificateStatusRequestItemV2*)extension->data : NULL;
4178
4179 if (!csr2) {
4180 /* look at context level */
4181 extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST_V2);
4182 csr2 = extension ?
4183 (CertificateStatusRequestItemV2*)extension->data : NULL;
4184
4185 if (!csr2) /* unexpected extension */
4186 return TLSX_HandleUnsupportedExtension(ssl);
4187
4188 /* enable extension at ssl level */
4189 for (; csr2; csr2 = csr2->next) {
4190 ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
4191 csr2->status_type, csr2->options, ssl->heap,
4192 ssl->devId);
4193 if (ret != WOLFSSL_SUCCESS)
4194 return ret;
4195
4196 switch (csr2->status_type) {
4197 case WOLFSSL_CSR2_OCSP:
4198 /* followed by */
4199 case WOLFSSL_CSR2_OCSP_MULTI:
4200 /* propagate nonce */
4201 if (csr2->request.ocsp[0].nonceSz) {
4202 OcspRequest* request =
4203 (OcspRequest*)TLSX_CSR2_GetRequest(ssl->extensions,
4204 csr2->status_type, 0);
4205
4206 if (request) {
4207 XMEMCPY(request->nonce,
4208 csr2->request.ocsp[0].nonce,
4209 (size_t)csr2->request.ocsp[0].nonceSz);
4210
4211 request->nonceSz =
4212 csr2->request.ocsp[0].nonceSz;
4213 }
4214 }
4215 break;
4216 }
4217 }
4218 }
4219
4220 ssl->status_request_v2 = 1;
4221
4222 return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
4223#endif
4224 }
4225 else {
4226#ifndef NO_WOLFSSL_SERVER
4227 byte status_type;
4228 word16 request_length;
4229 word16 offset = 0;
4230 word16 size = 0;
4231
4232 /* list size */
4233 if (offset + OPAQUE16_LEN >= length) {
4234 return BUFFER_E;
4235 }
4236
4237 ato16(input + offset, &request_length);
4238 offset += OPAQUE16_LEN;
4239
4240 if (length - OPAQUE16_LEN != request_length)
4241 return BUFFER_ERROR;
4242
4243 while (length > offset) {
4244 if ((int)(length - offset) < ENUM_LEN + OPAQUE16_LEN)
4245 return BUFFER_ERROR;
4246
4247 status_type = input[offset++];
4248
4249 ato16(input + offset, &request_length);
4250 offset += OPAQUE16_LEN;
4251
4252 if (length - offset < request_length)
4253 return BUFFER_ERROR;
4254
4255 switch (status_type) {
4256 case WOLFSSL_CSR2_OCSP:
4257 case WOLFSSL_CSR2_OCSP_MULTI:
4258 /* skip responder_id_list */
4259 if ((int)(length - offset) < OPAQUE16_LEN)
4260 return BUFFER_ERROR;
4261
4262 ato16(input + offset, &size);
4263 if (length - offset - OPAQUE16_LEN < size)
4264 return BUFFER_ERROR;
4265
4266 offset += OPAQUE16_LEN + size;
4267 /* skip request_extensions */
4268 if ((int)(length - offset) < OPAQUE16_LEN)
4269 return BUFFER_ERROR;
4270
4271 ato16(input + offset, &size);
4272 if (length - offset < size)
4273 return BUFFER_ERROR;
4274
4275 offset += OPAQUE16_LEN + size;
4276 if (offset > length)
4277 return BUFFER_ERROR;
4278
4279 /* is able to send OCSP response? */
4280 if (SSL_CM(ssl) == NULL
4281 || !SSL_CM(ssl)->ocspStaplingEnabled)
4282 continue;
4283 break;
4284
4285 default:
4286 /* unknown status type, skipping! */
4287 offset += request_length;
4288 continue;
4289 }
4290
4291 /* if using status_request and already sending it, remove it
4292 * and prefer to use the v2 version */
4293 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
4294 if (ssl->status_request) {
4295 ssl->status_request = 0;
4296 TLSX_Remove(&ssl->extensions, TLSX_STATUS_REQUEST, ssl->heap);
4297 }
4298 #endif
4299
4300 /* TLS 1.3 servers MUST NOT act upon presence or information in
4301 * this extension (RFC 8448 Section 4.4.2.1).
4302 */
4303 if (!IsAtLeastTLSv1_3(ssl->version)) {
4304 /* accept the first good status_type and return */
4305 ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
4306 status_type, 0, ssl->heap, ssl->devId);
4307 if (ret != WOLFSSL_SUCCESS)
4308 return ret; /* throw error */
4309
4310 TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST_V2);
4311 ssl->status_request_v2 = status_type;
4312 }
4313
4314 return 0;
4315 }
4316#endif
4317 }
4318
4319 return 0;
4320}
4321
4322static CertificateStatusRequestItemV2* TLSX_CSR2_GetMulti(TLSX *extensions)
4323{
4324 TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
4325 CertificateStatusRequestItemV2* csr2 = extension ?
4326 (CertificateStatusRequestItemV2*)extension->data : NULL;
4327
4328 for (; csr2; csr2 = csr2->next) {
4329 if (csr2->status_type == WOLFSSL_CSR2_OCSP_MULTI)
4330 return csr2;
4331 }
4332 return NULL;
4333}
4334
4335int TLSX_CSR2_IsMulti(TLSX *extensions)
4336{
4337 return TLSX_CSR2_GetMulti(extensions) != NULL;
4338}
4339
4340int TLSX_CSR2_AddPendingSigner(TLSX *extensions, Signer *s)
4341{
4342 CertificateStatusRequestItemV2* csr2;
4343
4344 csr2 = TLSX_CSR2_GetMulti(extensions);
4345 if (!csr2)
4346 return WOLFSSL_FATAL_ERROR;
4347
4348 s->next = csr2->pendingSigners;
4349 csr2->pendingSigners = s;
4350 return 0;
4351}
4352
4353Signer* TLSX_CSR2_GetPendingSigners(TLSX *extensions)
4354{
4355 CertificateStatusRequestItemV2* csr2;
4356
4357 csr2 = TLSX_CSR2_GetMulti(extensions);
4358 if (!csr2)
4359 return NULL;
4360
4361 return csr2->pendingSigners;
4362}
4363
4364int TLSX_CSR2_ClearPendingCA(WOLFSSL *ssl)
4365{
4366 CertificateStatusRequestItemV2* csr2;
4367
4368 csr2 = TLSX_CSR2_GetMulti(ssl->extensions);
4369 if (csr2 == NULL)
4370 return 0;
4371
4372 TLSX_CSR2_FreePendingSigners(csr2->pendingSigners, SSL_CM(ssl)->heap);
4373 csr2->pendingSigners = NULL;
4374 return 0;
4375}
4376
4377int TLSX_CSR2_MergePendingCA(WOLFSSL* ssl)
4378{
4379 CertificateStatusRequestItemV2* csr2;
4380 Signer *s, *next;
4381 int r = 0;
4382
4383 csr2 = TLSX_CSR2_GetMulti(ssl->extensions);
4384 if (csr2 == NULL)
4385 return 0;
4386
4387 s = csr2->pendingSigners;
4388 while (s != NULL) {
4389 next = s->next;
4390 r = AddSigner(SSL_CM(ssl), s);
4391 if (r != 0)
4392 FreeSigner(s, SSL_CM(ssl)->heap);
4393 s = next;
4394 }
4395 csr2->pendingSigners = NULL;
4396 return r;
4397}
4398
4399int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer,
4400 void* heap)
4401{
4402 TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
4403 CertificateStatusRequestItemV2* csr2 = extension ?
4404 (CertificateStatusRequestItemV2*)extension->data : NULL;
4405 int ret = 0;
4406
4407 for (; csr2; csr2 = csr2->next) {
4408 switch (csr2->status_type) {
4409 case WOLFSSL_CSR2_OCSP:
4410 if (!isPeer || csr2->requests != 0)
4411 break;
4412
4413 FALL_THROUGH; /* followed by */
4414
4415 case WOLFSSL_CSR2_OCSP_MULTI: {
4416 if (csr2->requests < 1 + MAX_CHAIN_DEPTH) {
4417 byte nonce[MAX_OCSP_NONCE_SZ];
4418 int nonceSz = csr2->request.ocsp[0].nonceSz;
4419
4420 /* preserve nonce, replicating nonce of ocsp[0] */
4421 XMEMCPY(nonce, csr2->request.ocsp[0].nonce,
4422 (size_t)nonceSz);
4423
4424 if ((ret = InitOcspRequest(
4425 &csr2->request.ocsp[csr2->requests], cert,
4426 0, heap)) != 0)
4427 return ret;
4428
4429 /* restore nonce */
4430 XMEMCPY(csr2->request.ocsp[csr2->requests].nonce,
4431 nonce, (size_t)nonceSz);
4432 csr2->request.ocsp[csr2->requests].nonceSz = nonceSz;
4433 csr2->requests++;
4434 }
4435 }
4436 break;
4437 }
4438 }
4439
4440 (void)cert;
4441 return ret;
4442}
4443
4444void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type, byte idx)
4445{
4446 TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
4447 CertificateStatusRequestItemV2* csr2 = extension ?
4448 (CertificateStatusRequestItemV2*)extension->data : NULL;
4449
4450 for (; csr2; csr2 = csr2->next) {
4451 if (csr2->status_type == status_type) {
4452 switch (csr2->status_type) {
4453 case WOLFSSL_CSR2_OCSP:
4454 /* followed by */
4455
4456 case WOLFSSL_CSR2_OCSP_MULTI:
4457 /* requests are initialized in the reverse order */
4458 return idx < csr2->requests
4459 ? &csr2->request.ocsp[csr2->requests - idx - 1]
4460 : NULL;
4461 }
4462 }
4463 }
4464
4465 return NULL;
4466}
4467
4468int TLSX_CSR2_ForceRequest(WOLFSSL* ssl)
4469{
4470 TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
4471 CertificateStatusRequestItemV2* csr2 = extension ?
4472 (CertificateStatusRequestItemV2*)extension->data : NULL;
4473
4474 /* forces only the first one */
4475 if (csr2) {
4476 switch (csr2->status_type) {
4477 case WOLFSSL_CSR2_OCSP:
4478 /* followed by */
4479
4480 case WOLFSSL_CSR2_OCSP_MULTI:
4481 if (SSL_CM(ssl)->ocspEnabled && csr2->requests >= 1) {
4482 csr2->request.ocsp[csr2->requests-1].ssl = ssl;
4483 return CheckOcspRequest(SSL_CM(ssl)->ocsp,
4484 &csr2->request.ocsp[csr2->requests-1], NULL, NULL);
4485 }
4486 else {
4487 WOLFSSL_ERROR_VERBOSE(OCSP_LOOKUP_FAIL);
4488 return OCSP_LOOKUP_FAIL;
4489 }
4490 }
4491 }
4492
4493 return 0;
4494}
4495
4496int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
4497 byte options, void* heap, int devId)
4498{
4499 TLSX* extension = NULL;
4500 CertificateStatusRequestItemV2* csr2 = NULL;
4501 int ret = 0;
4502
4503 if (!extensions)
4504 return BAD_FUNC_ARG;
4505
4506 if (status_type != WOLFSSL_CSR2_OCSP
4507 && status_type != WOLFSSL_CSR2_OCSP_MULTI)
4508 return BAD_FUNC_ARG;
4509
4510 csr2 = (CertificateStatusRequestItemV2*)
4511 XMALLOC(sizeof(CertificateStatusRequestItemV2), heap, DYNAMIC_TYPE_TLSX);
4512 if (!csr2)
4513 return MEMORY_E;
4514
4515 ForceZero(csr2, sizeof(CertificateStatusRequestItemV2));
4516
4517 csr2->status_type = status_type;
4518 csr2->options = options;
4519 csr2->next = NULL;
4520
4521 switch (csr2->status_type) {
4522 case WOLFSSL_CSR2_OCSP:
4523 case WOLFSSL_CSR2_OCSP_MULTI:
4524 if (options & WOLFSSL_CSR2_OCSP_USE_NONCE) {
4525 WC_RNG rng;
4526
4527 #ifndef HAVE_FIPS
4528 ret = wc_InitRng_ex(&rng, heap, devId);
4529 #else
4530 ret = wc_InitRng(&rng);
4531 (void)devId;
4532 #endif
4533 if (ret == 0) {
4534 if (wc_RNG_GenerateBlock(&rng, csr2->request.ocsp[0].nonce,
4535 MAX_OCSP_NONCE_SZ) == 0)
4536 csr2->request.ocsp[0].nonceSz = MAX_OCSP_NONCE_SZ;
4537
4538 wc_FreeRng(&rng);
4539 }
4540 }
4541 break;
4542 }
4543
4544 /* append new item */
4545 if ((extension = TLSX_Find(*extensions, TLSX_STATUS_REQUEST_V2))) {
4546 CertificateStatusRequestItemV2* last =
4547 (CertificateStatusRequestItemV2*)extension->data;
4548
4549 if (last == NULL) {
4550 XFREE(csr2, heap, DYNAMIC_TYPE_TLSX);
4551 return BAD_FUNC_ARG;
4552 }
4553
4554 for (; last->next; last = last->next);
4555
4556 last->next = csr2;
4557 }
4558 else if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST_V2, csr2,heap))) {
4559 XFREE(csr2, heap, DYNAMIC_TYPE_TLSX);
4560 return ret;
4561 }
4562
4563 return WOLFSSL_SUCCESS;
4564}
4565
4566#define CSR2_FREE_ALL TLSX_CSR2_FreeAll
4567#define CSR2_GET_SIZE TLSX_CSR2_GetSize
4568#define CSR2_WRITE TLSX_CSR2_Write
4569#define CSR2_PARSE TLSX_CSR2_Parse
4570
4571#else
4572
4573#define CSR2_FREE_ALL(data, heap) WC_DO_NOTHING
4574#define CSR2_GET_SIZE(a, b) 0
4575#define CSR2_WRITE(a, b, c) 0
4576#define CSR2_PARSE(a, b, c, d) 0
4577
4578#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
4579
4580#if defined(HAVE_SUPPORTED_CURVES) || \
4581 (defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES))
4582
4583/* Returns whether this group is supported.
4584 *
4585 * namedGroup The named group to check.
4586 * returns 1 when supported or 0 otherwise.
4587 */
4588int TLSX_IsGroupSupported(int namedGroup)
4589{
4590 switch (namedGroup) {
4591 #ifdef HAVE_FFDHE_2048
4592 case WOLFSSL_FFDHE_2048:
4593 break;
4594 #endif
4595 #ifdef HAVE_FFDHE_3072
4596 case WOLFSSL_FFDHE_3072:
4597 break;
4598 #endif
4599 #ifdef HAVE_FFDHE_4096
4600 case WOLFSSL_FFDHE_4096:
4601 break;
4602 #endif
4603 #ifdef HAVE_FFDHE_6144
4604 case WOLFSSL_FFDHE_6144:
4605 break;
4606 #endif
4607 #ifdef HAVE_FFDHE_8192
4608 case WOLFSSL_FFDHE_8192:
4609 break;
4610 #endif
4611 #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
4612 #ifdef HAVE_ECC_KOBLITZ
4613 case WOLFSSL_ECC_SECP256K1:
4614 break;
4615 #endif
4616 #ifndef NO_ECC_SECP
4617 case WOLFSSL_ECC_SECP256R1:
4618 break;
4619 #endif /* !NO_ECC_SECP */
4620 #ifdef HAVE_ECC_BRAINPOOL
4621 case WOLFSSL_ECC_BRAINPOOLP256R1:
4622 case WOLFSSL_ECC_BRAINPOOLP256R1TLS13:
4623 break;
4624 #endif
4625 #ifdef WOLFSSL_SM2
4626 case WOLFSSL_ECC_SM2P256V1:
4627 break;
4628 #endif /* WOLFSSL_SM2 */
4629 #endif
4630 #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
4631 case WOLFSSL_ECC_X25519:
4632 break;
4633 #endif
4634 #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
4635 case WOLFSSL_ECC_X448:
4636 break;
4637 #endif
4638 #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
4639 #ifndef NO_ECC_SECP
4640 case WOLFSSL_ECC_SECP384R1:
4641 break;
4642 #endif /* !NO_ECC_SECP */
4643 #ifdef HAVE_ECC_BRAINPOOL
4644 case WOLFSSL_ECC_BRAINPOOLP384R1:
4645 case WOLFSSL_ECC_BRAINPOOLP384R1TLS13:
4646 break;
4647 #endif
4648 #endif
4649 #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
4650 #ifndef NO_ECC_SECP
4651 case WOLFSSL_ECC_SECP521R1:
4652 break;
4653 #endif /* !NO_ECC_SECP */
4654 #endif
4655 #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
4656 #ifdef HAVE_ECC_KOBLITZ
4657 case WOLFSSL_ECC_SECP160K1:
4658 break;
4659 #endif
4660 #ifndef NO_ECC_SECP
4661 case WOLFSSL_ECC_SECP160R1:
4662 break;
4663 #endif
4664 #ifdef HAVE_ECC_SECPR2
4665 case WOLFSSL_ECC_SECP160R2:
4666 break;
4667 #endif
4668 #endif
4669 #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
4670 #ifdef HAVE_ECC_KOBLITZ
4671 case WOLFSSL_ECC_SECP192K1:
4672 break;
4673 #endif
4674 #ifndef NO_ECC_SECP
4675 case WOLFSSL_ECC_SECP192R1:
4676 break;
4677 #endif
4678 #endif
4679 #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
4680 #ifdef HAVE_ECC_KOBLITZ
4681 case WOLFSSL_ECC_SECP224K1:
4682 break;
4683 #endif
4684 #ifndef NO_ECC_SECP
4685 case WOLFSSL_ECC_SECP224R1:
4686 break;
4687 #endif
4688 #endif
4689 #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
4690 #ifdef HAVE_ECC_BRAINPOOL
4691 case WOLFSSL_ECC_BRAINPOOLP512R1:
4692 case WOLFSSL_ECC_BRAINPOOLP512R1TLS13:
4693 break;
4694 #endif
4695 #endif
4696#ifdef WOLFSSL_HAVE_MLKEM
4697#ifndef WOLFSSL_NO_ML_KEM
4698 #ifndef WOLFSSL_NO_ML_KEM_512
4699 #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
4700 case WOLFSSL_ML_KEM_512:
4701 break;
4702 #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
4703 #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
4704 case WOLFSSL_SECP256R1MLKEM512:
4705 #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
4706 case WOLFSSL_X25519MLKEM512:
4707 #endif /* HAVE_CURVE25519 */
4708 break;
4709 #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
4710 #endif /* WOLFSSL_NO_ML_KEM_512 */
4711 #ifndef WOLFSSL_NO_ML_KEM_768
4712 #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
4713 case WOLFSSL_ML_KEM_768:
4714 #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
4715 #ifdef WOLFSSL_PQC_HYBRIDS
4716 case WOLFSSL_SECP256R1MLKEM768:
4717 #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
4718 case WOLFSSL_X25519MLKEM768:
4719 #endif /* HAVE_CURVE25519 */
4720 #endif /* WOLFSSL_PQC_HYBRIDS */
4721 #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
4722 case WOLFSSL_SECP384R1MLKEM768:
4723 #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
4724 case WOLFSSL_X448MLKEM768:
4725 #endif /* HAVE_CURVE448 */
4726 #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
4727 break;
4728 #endif /* WOLFSSL_NO_ML_KEM_768 */
4729 #ifndef WOLFSSL_NO_ML_KEM_1024
4730 #ifndef WOLFSSL_TLS_NO_MLKEM_STANDALONE
4731 case WOLFSSL_ML_KEM_1024:
4732 #endif /* !WOLFSSL_TLS_NO_MLKEM_STANDALONE */
4733 #ifdef WOLFSSL_PQC_HYBRIDS
4734 case WOLFSSL_SECP384R1MLKEM1024:
4735 #endif /* WOLFSSL_PQC_HYBRIDS */
4736 #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
4737 case WOLFSSL_SECP521R1MLKEM1024:
4738 #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
4739 break;
4740 #endif
4741 #if defined(WOLFSSL_ML_KEM_USE_OLD_IDS) && \
4742 defined (WOLFSSL_EXTRA_PQC_HYBRIDS)
4743 case WOLFSSL_P256_ML_KEM_512_OLD:
4744 case WOLFSSL_P384_ML_KEM_768_OLD:
4745 case WOLFSSL_P521_ML_KEM_1024_OLD:
4746 break;
4747 #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS && WOLFSSL_EXTRA_PQC_HYBRIDS */
4748#endif /* WOLFSSL_NO_ML_KEM */
4749#ifdef WOLFSSL_MLKEM_KYBER
4750 #ifdef WOLFSSL_KYBER512
4751 case WOLFSSL_KYBER_LEVEL1:
4752 case WOLFSSL_P256_KYBER_LEVEL1:
4753 #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
4754 case WOLFSSL_X25519_KYBER_LEVEL1:
4755 #endif
4756 #endif
4757 #ifdef WOLFSSL_KYBER768
4758 case WOLFSSL_KYBER_LEVEL3:
4759 case WOLFSSL_P384_KYBER_LEVEL3:
4760 case WOLFSSL_P256_KYBER_LEVEL3:
4761 #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
4762 case WOLFSSL_X25519_KYBER_LEVEL3:
4763 #endif
4764 #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
4765 case WOLFSSL_X448_KYBER_LEVEL3:
4766 #endif
4767 #endif
4768 #ifdef WOLFSSL_KYBER1024
4769 case WOLFSSL_KYBER_LEVEL5:
4770 case WOLFSSL_P521_KYBER_LEVEL5:
4771 #endif
4772 break;
4773#endif
4774#endif /* WOLFSSL_HAVE_MLKEM */
4775 default:
4776 return 0;
4777 }
4778
4779 return 1;
4780}
4781#endif
4782
4783/******************************************************************************/
4784/* Supported Elliptic Curves */
4785/******************************************************************************/
4786
4787#ifdef HAVE_SUPPORTED_CURVES
4788
4789#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448) \
4790 && !defined(HAVE_FFDHE) && !defined(WOLFSSL_HAVE_MLKEM)
4791#error Elliptic Curves Extension requires Elliptic Curve Cryptography or liboqs groups. \
4792 Use --enable-ecc and/or --enable-liboqs in the configure script or \
4793 define HAVE_ECC. Alternatively use FFDHE for DH cipher suites.
4794#endif
4795
4796static int TLSX_SupportedCurve_New(SupportedCurve** curve, word16 name,
4797 void* heap)
4798{
4799 if (curve == NULL)
4800 return BAD_FUNC_ARG;
4801
4802 (void)heap;
4803
4804 *curve = (SupportedCurve*)XMALLOC(sizeof(SupportedCurve), heap,
4805 DYNAMIC_TYPE_TLSX);
4806 if (*curve == NULL)
4807 return MEMORY_E;
4808
4809 (*curve)->name = name;
4810 (*curve)->next = NULL;
4811
4812 return 0;
4813}
4814
4815static int TLSX_PointFormat_New(PointFormat** point, byte format, void* heap)
4816{
4817 if (point == NULL)
4818 return BAD_FUNC_ARG;
4819
4820 (void)heap;
4821
4822 *point = (PointFormat*)XMALLOC(sizeof(PointFormat), heap,
4823 DYNAMIC_TYPE_TLSX);
4824 if (*point == NULL)
4825 return MEMORY_E;
4826
4827 (*point)->format = format;
4828 (*point)->next = NULL;
4829
4830 return 0;
4831}
4832
4833static void TLSX_SupportedCurve_FreeAll(SupportedCurve* list, void* heap)
4834{
4835 SupportedCurve* curve;
4836
4837 while ((curve = list)) {
4838 list = curve->next;
4839 XFREE(curve, heap, DYNAMIC_TYPE_TLSX);
4840 }
4841 (void)heap;
4842}
4843
4844static void TLSX_PointFormat_FreeAll(PointFormat* list, void* heap)
4845{
4846 PointFormat* point;
4847
4848 while ((point = list)) {
4849 list = point->next;
4850 XFREE(point, heap, DYNAMIC_TYPE_TLSX);
4851 }
4852 (void)heap;
4853}
4854
4855static int TLSX_SupportedCurve_Append(SupportedCurve* list, word16 name,
4856 void* heap)
4857{
4858 int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
4859
4860 while (list) {
4861 if (list->name == name) {
4862 ret = 0; /* curve already in use */
4863 break;
4864 }
4865
4866 if (list->next == NULL) {
4867 ret = TLSX_SupportedCurve_New(&list->next, name, heap);
4868 break;
4869 }
4870
4871 list = list->next;
4872 }
4873
4874 return ret;
4875}
4876
4877static int TLSX_PointFormat_Append(PointFormat* list, byte format, void* heap)
4878{
4879 int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
4880
4881 while (list) {
4882 if (list->format == format) {
4883 ret = 0; /* format already in use */
4884 break;
4885 }
4886
4887 if (list->next == NULL) {
4888 ret = TLSX_PointFormat_New(&list->next, format, heap);
4889 break;
4890 }
4891
4892 list = list->next;
4893 }
4894
4895 return ret;
4896}
4897
4898#if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
4899
4900#if defined(HAVE_FFDHE) && (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
4901 defined(HAVE_CURVE448))
4902static void TLSX_SupportedCurve_ValidateRequest(const WOLFSSL* ssl,
4903 const byte* semaphore)
4904{
4905 /* If all pre-defined parameter types for key exchange are supported then
4906 * always send SupportedGroups extension.
4907 */
4908 (void)ssl;
4909 (void)semaphore;
4910}
4911#else
4912static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
4913{
4914 word16 i;
4915 const Suites* suites = WOLFSSL_SUITES(ssl);
4916
4917 for (i = 0; i < suites->suiteSz; i += 2) {
4918 if (suites->suites[i] == TLS13_BYTE)
4919 return;
4920 #ifdef BUILD_TLS_SM4_GCM_SM3
4921 if ((suites->suites[i] == CIPHER_BYTE) &&
4922 (suites->suites[i+1] == TLS_SM4_GCM_SM3))
4923 return;
4924 #endif
4925 #ifdef BUILD_TLS_SM4_CCM_SM3
4926 if ((suites->suites[i] == CIPHER_BYTE) &&
4927 (suites->suites[i+1] == TLS_SM4_CCM_SM3))
4928 return;
4929 #endif
4930 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3
4931 if ((suites->suites[i] == SM_BYTE) &&
4932 (suites->suites[i+1] == TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3))
4933 return;
4934 #endif
4935 if ((suites->suites[i] == ECC_BYTE) ||
4936 (suites->suites[i] == ECDHE_PSK_BYTE) ||
4937 (suites->suites[i] == CHACHA_BYTE)) {
4938 #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
4939 defined(HAVE_CURVE448)
4940 return;
4941 #endif
4942 }
4943 #ifdef HAVE_FFDHE
4944 else {
4945 return;
4946 }
4947 #endif
4948 }
4949
4950 /* turns semaphore on to avoid sending this extension. */
4951 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
4952}
4953#endif
4954
4955/* Only send PointFormats if TLSv13, ECC or CHACHA cipher suite present.
4956 */
4957static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
4958{
4959#ifdef HAVE_FFDHE
4960 (void)ssl;
4961 (void)semaphore;
4962#else
4963 word16 i;
4964 const Suites* suites = WOLFSSL_SUITES(ssl);
4965
4966 if (suites == NULL)
4967 return;
4968
4969 for (i = 0; i < suites->suiteSz; i += 2) {
4970 if (suites->suites[i] == TLS13_BYTE)
4971 return;
4972 #ifdef BUILD_TLS_SM4_GCM_SM3
4973 if ((suites->suites[i] == CIPHER_BYTE) &&
4974 (suites->suites[i+1] == TLS_SM4_GCM_SM3))
4975 return;
4976 #endif
4977 #ifdef BUILD_TLS_SM4_CCM_SM3
4978 if ((suites->suites[i] == CIPHER_BYTE) &&
4979 (suites->suites[i+1] == TLS_SM4_CCM_SM3))
4980 return;
4981 #endif
4982 #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3
4983 if ((suites->suites[i] == SM_BYTE) &&
4984 (suites->suites[i+1] == TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3))
4985 return;
4986 #endif
4987 if ((suites->suites[i] == ECC_BYTE) ||
4988 (suites->suites[i] == ECDHE_PSK_BYTE) ||
4989 (suites->suites[i] == CHACHA_BYTE)) {
4990 #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
4991 defined(HAVE_CURVE448)
4992 return;
4993 #endif
4994 }
4995 }
4996 /* turns semaphore on to avoid sending this extension. */
4997 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
4998#endif
4999}
5000
5001#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
5002
5003#ifndef NO_WOLFSSL_SERVER
5004
5005static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore)
5006{
5007#if defined(HAVE_FFDHE) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
5008 defined(HAVE_CURVE448)
5009 (void)semaphore;
5010#endif
5011
5012 if (ssl->options.cipherSuite0 == TLS13_BYTE)
5013 return;
5014#ifdef BUILD_TLS_SM4_GCM_SM3
5015 if ((ssl->options.cipherSuite0 == CIPHER_BYTE) &&
5016 (ssl->options.cipherSuite == TLS_SM4_GCM_SM3))
5017 return;
5018#endif
5019#ifdef BUILD_TLS_SM4_CCM_SM3
5020 if ((ssl->options.cipherSuite0 == CIPHER_BYTE) &&
5021 (ssl->options.cipherSuite == TLS_SM4_CCM_SM3))
5022 return;
5023#endif
5024#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3
5025 if ((ssl->options.cipherSuite0 == SM_BYTE) &&
5026 (ssl->options.cipherSuite == TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3))
5027 return;
5028#endif
5029#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
5030 if (ssl->options.cipherSuite0 == ECC_BYTE ||
5031 ssl->options.cipherSuite0 == ECDHE_PSK_BYTE ||
5032 ssl->options.cipherSuite0 == CHACHA_BYTE) {
5033 return;
5034 }
5035#endif
5036
5037 /* turns semaphore on to avoid sending this extension. */
5038 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
5039}
5040
5041#endif /* !NO_WOLFSSL_SERVER */
5042
5043#if !defined(NO_WOLFSSL_CLIENT) || defined(WOLFSSL_TLS13)
5044
5045static word16 TLSX_SupportedCurve_GetSize(SupportedCurve* list)
5046{
5047 SupportedCurve* curve;
5048 word16 length = OPAQUE16_LEN; /* list length */
5049
5050 while ((curve = list)) {
5051 list = curve->next;
5052 length += OPAQUE16_LEN; /* curve length */
5053 }
5054
5055 return length;
5056}
5057
5058#endif
5059
5060static word16 TLSX_PointFormat_GetSize(PointFormat* list)
5061{
5062 PointFormat* point;
5063 word16 length = ENUM_LEN; /* list length */
5064
5065 while ((point = list)) {
5066 list = point->next;
5067 length += ENUM_LEN; /* format length */
5068 }
5069
5070 return length;
5071}
5072
5073#if !defined(NO_WOLFSSL_CLIENT) || defined(WOLFSSL_TLS13)
5074
5075static word16 TLSX_SupportedCurve_Write(SupportedCurve* list, byte* output)
5076{
5077 word16 offset = OPAQUE16_LEN;
5078
5079 while (list) {
5080 c16toa(list->name, output + offset);
5081 offset += OPAQUE16_LEN;
5082 list = list->next;
5083 }
5084
5085 c16toa(offset - OPAQUE16_LEN, output); /* writing list length */
5086
5087 return offset;
5088}
5089
5090#endif
5091
5092static word16 TLSX_PointFormat_Write(PointFormat* list, byte* output)
5093{
5094 word16 offset = ENUM_LEN;
5095
5096 while (list) {
5097 output[offset++] = list->format;
5098 list = list->next;
5099 }
5100
5101 output[0] = (byte)(offset - ENUM_LEN);
5102
5103 return offset;
5104}
5105
5106#if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \
5107 !defined(WOLFSSL_NO_SERVER_GROUPS_EXT))
5108
5109int TLSX_SupportedCurve_Parse(const WOLFSSL* ssl, const byte* input,
5110 word16 length, byte isRequest, TLSX** extensions)
5111{
5112 word16 offset;
5113 word16 name;
5114 int ret = 0;
5115 TLSX* extension;
5116
5117 if(!isRequest && !IsAtLeastTLSv1_3(ssl->version)) {
5118#ifdef WOLFSSL_ALLOW_SERVER_SC_EXT
5119 return 0;
5120#else
5121 return BUFFER_ERROR; /* servers doesn't send this extension. */
5122#endif
5123 }
5124 if (OPAQUE16_LEN > length || length % OPAQUE16_LEN)
5125 return BUFFER_ERROR;
5126 ato16(input, &offset);
5127 /* validating curve list length */
5128 if (length != OPAQUE16_LEN + offset)
5129 return BUFFER_ERROR;
5130 offset = OPAQUE16_LEN;
5131 if (offset == length)
5132 return 0;
5133
5134 extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
5135 if (extension == NULL) {
5136 /* Just accept what the peer wants to use */
5137 for (; offset < length; offset += OPAQUE16_LEN) {
5138 ato16(input + offset, &name);
5139
5140 ret = TLSX_UseSupportedCurve(extensions, name, ssl->heap);
5141 /* If it is BAD_FUNC_ARG then it is a group we do not support, but
5142 * that is fine. */
5143 if (ret != WOLFSSL_SUCCESS &&
5144 ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
5145 break;
5146 ret = 0;
5147 }
5148 }
5149 else {
5150 /* Find the intersection with what the user has set */
5151 SupportedCurve* commonCurves = NULL;
5152 for (; offset < length; offset += OPAQUE16_LEN) {
5153 SupportedCurve* foundCurve = (SupportedCurve*)extension->data;
5154 ato16(input + offset, &name);
5155
5156 while (foundCurve != NULL && foundCurve->name != name)
5157 foundCurve = foundCurve->next;
5158
5159 if (foundCurve != NULL) {
5160 ret = commonCurves == NULL ?
5161 TLSX_SupportedCurve_New(&commonCurves, name, ssl->heap) :
5162 TLSX_SupportedCurve_Append(commonCurves, name, ssl->heap);
5163 if (ret != 0)
5164 break;
5165 }
5166 }
5167 /* If no common curves return error. In TLS 1.3 we can still try to save
5168 * this by using HRR. */
5169 if (ret == 0 && commonCurves == NULL &&
5170 !IsAtLeastTLSv1_3(ssl->version))
5171 ret = ECC_CURVE_ERROR;
5172 if (ret == 0) {
5173 /* Now swap out the curves in the extension */
5174 TLSX_SupportedCurve_FreeAll((SupportedCurve*)extension->data,
5175 ssl->heap);
5176 extension->data = commonCurves;
5177 commonCurves = NULL;
5178 }
5179 TLSX_SupportedCurve_FreeAll(commonCurves, ssl->heap);
5180 }
5181
5182 return ret;
5183}
5184#endif
5185
5186#if !defined(NO_WOLFSSL_SERVER)
5187
5188#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
5189
5190/* Checks the priority of the groups on the server and set the supported groups
5191 * response if there is a group not advertised by the client that is preferred.
5192 *
5193 * ssl SSL/TLS object.
5194 * returns 0 on success, otherwise an error.
5195 */
5196int TLSX_SupportedCurve_CheckPriority(WOLFSSL* ssl)
5197{
5198 int ret;
5199 TLSX* extension;
5200 TLSX* priority = NULL;
5201 TLSX* ext = NULL;
5202 word16 name;
5203 SupportedCurve* curve;
5204
5205 extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
5206 /* May be doing PSK with no key exchange. */
5207 if (extension == NULL)
5208 return 0;
5209
5210 ret = TLSX_PopulateSupportedGroups(ssl, &priority);
5211 if (ret != WOLFSSL_SUCCESS) {
5212 TLSX_FreeAll(priority, ssl->heap);
5213 return ret;
5214 }
5215
5216 ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS);
5217 if (ext == NULL) {
5218 WOLFSSL_MSG("Could not find supported groups extension");
5219 TLSX_FreeAll(priority, ssl->heap);
5220 return 0;
5221 }
5222
5223 curve = (SupportedCurve*)ext->data;
5224 name = curve->name;
5225
5226 curve = (SupportedCurve*)extension->data;
5227 while (curve != NULL) {
5228 if (curve->name == name)
5229 break;
5230 curve = curve->next;
5231 }
5232
5233 if (curve == NULL) {
5234 /* Couldn't find the preferred group in client list. */
5235 extension->resp = 1;
5236
5237 /* Send server list back and free client list. */
5238 curve = (SupportedCurve*)extension->data;
5239 extension->data = ext->data;
5240 ext->data = curve;
5241 }
5242
5243 TLSX_FreeAll(priority, ssl->heap);
5244
5245 return 0;
5246}
5247
5248#endif /* WOLFSSL_TLS13 && !WOLFSSL_NO_SERVER_GROUPS_EXT */
5249
5250#if defined(HAVE_FFDHE) && !defined(WOLFSSL_NO_TLS12)
5251#ifdef HAVE_PUBLIC_FFDHE
5252static int tlsx_ffdhe_find_group(WOLFSSL* ssl, SupportedCurve* clientGroup,
5253 SupportedCurve* serverGroup)
5254{
5255 int ret = 0;
5256 SupportedCurve* group;
5257 const DhParams* params = NULL;
5258
5259 for (; serverGroup != NULL; serverGroup = serverGroup->next) {
5260 if (!WOLFSSL_NAMED_GROUP_IS_FFDHE(serverGroup->name))
5261 continue;
5262
5263 for (group = clientGroup; group != NULL; group = group->next) {
5264 if (serverGroup->name != group->name)
5265 continue;
5266
5267 switch (serverGroup->name) {
5268 #ifdef HAVE_FFDHE_2048
5269 case WOLFSSL_FFDHE_2048:
5270 params = wc_Dh_ffdhe2048_Get();
5271 break;
5272 #endif
5273 #ifdef HAVE_FFDHE_3072
5274 case WOLFSSL_FFDHE_3072:
5275 params = wc_Dh_ffdhe3072_Get();
5276 break;
5277 #endif
5278 #ifdef HAVE_FFDHE_4096
5279 case WOLFSSL_FFDHE_4096:
5280 params = wc_Dh_ffdhe4096_Get();
5281 break;
5282 #endif
5283 #ifdef HAVE_FFDHE_6144
5284 case WOLFSSL_FFDHE_6144:
5285 params = wc_Dh_ffdhe6144_Get();
5286 break;
5287 #endif
5288 #ifdef HAVE_FFDHE_8192
5289 case WOLFSSL_FFDHE_8192:
5290 params = wc_Dh_ffdhe8192_Get();
5291 break;
5292 #endif
5293 default:
5294 break;
5295 }
5296 if (params == NULL) {
5297 ret = BAD_FUNC_ARG;
5298 break;
5299 }
5300 if (params->p_len >= ssl->options.minDhKeySz &&
5301 params->p_len <= ssl->options.maxDhKeySz) {
5302 break;
5303 }
5304 }
5305
5306 if (ret != 0)
5307 break;
5308 if ((group != NULL) && (serverGroup->name == group->name))
5309 break;
5310 }
5311
5312 if ((ret == 0) && (serverGroup != NULL) && (params != NULL)) {
5313 ssl->buffers.serverDH_P.buffer = (unsigned char *)params->p;
5314 ssl->buffers.serverDH_P.length = params->p_len;
5315 ssl->buffers.serverDH_G.buffer = (unsigned char *)params->g;
5316 ssl->buffers.serverDH_G.length = params->g_len;
5317
5318 ssl->namedGroup = serverGroup->name;
5319 #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \
5320 !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
5321 ssl->options.dhDoKeyTest = 0;
5322 #endif
5323 ssl->options.haveDH = 1;
5324 }
5325
5326 return ret;
5327}
5328#else
5329static int tlsx_ffdhe_find_group(WOLFSSL* ssl, SupportedCurve* clientGroup,
5330 SupportedCurve* serverGroup)
5331{
5332 int ret = 0;
5333 SupportedCurve* group;
5334 word32 p_len;
5335
5336 for (; serverGroup != NULL; serverGroup = serverGroup->next) {
5337 if (!WOLFSSL_NAMED_GROUP_IS_FFDHE(serverGroup->name))
5338 continue;
5339
5340 for (group = clientGroup; group != NULL; group = group->next) {
5341 if (serverGroup->name != group->name)
5342 continue;
5343
5344 ret = wc_DhGetNamedKeyParamSize(serverGroup->name, &p_len, NULL, NULL);
5345 if (ret == 0) {
5346 if (p_len == 0) {
5347 ret = BAD_FUNC_ARG;
5348 break;
5349 }
5350 if (p_len >= ssl->options.minDhKeySz &&
5351 p_len <= ssl->options.maxDhKeySz) {
5352 break;
5353 }
5354 }
5355 }
5356
5357 if (ret != 0)
5358 break;
5359 if ((group != NULL) && (serverGroup->name == group->name))
5360 break;
5361 }
5362
5363 if ((ret == 0) && (serverGroup != NULL)) {
5364 word32 pSz, gSz;
5365
5366 ssl->buffers.serverDH_P.buffer = NULL;
5367 ssl->buffers.serverDH_G.buffer = NULL;
5368 ret = wc_DhGetNamedKeyParamSize(serverGroup->name, &pSz, &gSz, NULL);
5369 if (ret == 0) {
5370 ssl->buffers.serverDH_P.buffer =
5371 (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5372 if (ssl->buffers.serverDH_P.buffer == NULL)
5373 ret = MEMORY_E;
5374 else
5375 ssl->buffers.serverDH_P.length = pSz;
5376 }
5377 if (ret == 0) {
5378 ssl->buffers.serverDH_G.buffer =
5379 (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
5380 if (ssl->buffers.serverDH_G.buffer == NULL) {
5381 ret = MEMORY_E;
5382 } else
5383 ssl->buffers.serverDH_G.length = gSz;
5384 }
5385 if (ret == 0) {
5386 ret = wc_DhCopyNamedKey(serverGroup->name,
5387 ssl->buffers.serverDH_P.buffer, &pSz,
5388 ssl->buffers.serverDH_G.buffer, &gSz,
5389 NULL, NULL);
5390 }
5391 if (ret == 0) {
5392 ssl->buffers.weOwnDH = 1;
5393
5394 ssl->namedGroup = serverGroup->name;
5395 #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \
5396 !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
5397 ssl->options.dhDoKeyTest = 0;
5398 #endif
5399 ssl->options.haveDH = 1;
5400 }
5401 else {
5402 if (ssl->buffers.serverDH_P.buffer != NULL) {
5403 XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
5404 DYNAMIC_TYPE_PUBLIC_KEY);
5405 ssl->buffers.serverDH_P.length = 0;
5406 ssl->buffers.serverDH_P.buffer = NULL;
5407 }
5408 if (ssl->buffers.serverDH_G.buffer != NULL) {
5409 XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
5410 DYNAMIC_TYPE_PUBLIC_KEY);
5411 ssl->buffers.serverDH_G.length = 0;
5412 ssl->buffers.serverDH_G.buffer = NULL;
5413 }
5414 }
5415 }
5416
5417 return ret;
5418}
5419#endif
5420
5421/* Set the highest priority common FFDHE group on the server as compared to
5422 * client extensions.
5423 *
5424 * ssl SSL/TLS object.
5425 * returns 0 on success, otherwise an error.
5426 */
5427int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl)
5428{
5429 int ret;
5430 TLSX* priority = NULL;
5431 TLSX* ext = NULL;
5432 TLSX* extension;
5433 SupportedCurve* clientGroup;
5434 SupportedCurve* group;
5435 int found = 0;
5436
5437 extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
5438 /* May be doing PSK with no key exchange. */
5439 if (extension == NULL)
5440 return 0;
5441 clientGroup = (SupportedCurve*)extension->data;
5442 for (group = clientGroup; group != NULL; group = group->next) {
5443 if (WOLFSSL_NAMED_GROUP_IS_FFDHE(group->name)) {
5444 found = 1;
5445 break;
5446 }
5447 }
5448 if (!found)
5449 return 0;
5450
5451 if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
5452 XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
5453 DYNAMIC_TYPE_PUBLIC_KEY);
5454 }
5455 if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
5456 XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
5457 DYNAMIC_TYPE_PUBLIC_KEY);
5458 }
5459 ssl->buffers.serverDH_P.buffer = NULL;
5460 ssl->buffers.serverDH_G.buffer = NULL;
5461 ssl->buffers.weOwnDH = 0;
5462 ssl->options.haveDH = 0;
5463
5464 ret = TLSX_PopulateSupportedGroups(ssl, &priority);
5465 if (ret == WOLFSSL_SUCCESS) {
5466 SupportedCurve* serverGroup;
5467
5468 ext = TLSX_Find(priority, TLSX_SUPPORTED_GROUPS);
5469 if (ext == NULL) {
5470 WOLFSSL_MSG("Could not find supported groups extension");
5471 ret = 0;
5472 }
5473 else {
5474 serverGroup = (SupportedCurve*)ext->data;
5475 ret = tlsx_ffdhe_find_group(ssl, clientGroup, serverGroup);
5476 }
5477 }
5478
5479 TLSX_FreeAll(priority, ssl->heap);
5480
5481 return ret;
5482}
5483#endif /* HAVE_FFDHE && !WOLFSSL_NO_TLS12 */
5484#endif /* !NO_WOLFSSL_SERVER */
5485
5486/* Check if the given curve is present in the supported groups extension.
5487 *
5488 * ssl SSL/TLS object.
5489 * name The curve name to check.
5490 * returns 1 if present, 0 otherwise.
5491 */
5492int TLSX_SupportedCurve_IsSupported(WOLFSSL* ssl, word16 name)
5493{
5494 TLSX* extension;
5495 SupportedCurve* curve;
5496
5497 extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
5498 if (extension == NULL)
5499 return 0;
5500
5501 curve = (SupportedCurve*)extension->data;
5502 while (curve != NULL) {
5503 if (curve->name == name)
5504 return 1;
5505 curve = curve->next;
5506 }
5507
5508 return 0;
5509}
5510
5511#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)
5512/* Return the preferred group.
5513 *
5514 * ssl SSL/TLS object.
5515 * checkSupported Whether to check for the first supported group.
5516 * returns BAD_FUNC_ARG if no group found, otherwise the group.
5517 */
5518int TLSX_SupportedCurve_Preferred(WOLFSSL* ssl, int checkSupported)
5519{
5520 TLSX* extension;
5521 SupportedCurve* curve;
5522
5523 extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
5524 if (extension == NULL)
5525 return BAD_FUNC_ARG;
5526
5527 curve = (SupportedCurve*)extension->data;
5528 while (curve != NULL) {
5529 if (!checkSupported || TLSX_IsGroupSupported(curve->name))
5530 return curve->name;
5531 curve = curve->next;
5532 }
5533
5534 return BAD_FUNC_ARG;
5535}
5536
5537#endif /* HAVE_SUPPORTED_CURVES */
5538
5539#ifndef NO_WOLFSSL_SERVER
5540
5541static int TLSX_PointFormat_Parse(WOLFSSL* ssl, const byte* input,
5542 word16 length, byte isRequest)
5543{
5544 int ret;
5545
5546 /* validating formats list length */
5547 if (ENUM_LEN > length || length != (word16)ENUM_LEN + input[0])
5548 return BUFFER_ERROR;
5549
5550 if (isRequest) {
5551 /* adding uncompressed point format to response */
5552 ret = TLSX_UsePointFormat(&ssl->extensions, WOLFSSL_EC_PF_UNCOMPRESSED,
5553 ssl->heap);
5554 if (ret != WOLFSSL_SUCCESS)
5555 return ret; /* throw error */
5556
5557 TLSX_SetResponse(ssl, TLSX_EC_POINT_FORMATS);
5558 }
5559
5560 return 0;
5561}
5562
5563#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
5564int TLSX_ValidateSupportedCurves(const WOLFSSL* ssl, byte first, byte second,
5565 word32* ecdhCurveOID) {
5566 TLSX* extension = NULL;
5567 SupportedCurve* curve = NULL;
5568 word32 oid = 0;
5569 word32 defOid = 0;
5570 word32 defSz = 80; /* Maximum known curve size is 66. */
5571 word32 nextOid = 0;
5572 word32 nextSz = 80; /* Maximum known curve size is 66. */
5573 word32 currOid = ssl->ecdhCurveOID;
5574 int ephmSuite = 0;
5575 word16 octets = 0; /* according to 'ecc_set_type ecc_sets[];' */
5576 int key = 0; /* validate key */
5577 int foundCurve = 0; /* Found at least one supported curve */
5578
5579 (void)oid;
5580
5581 if (first == CHACHA_BYTE) {
5582 switch (second) {
5583 case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
5584 case TLS_PSK_WITH_CHACHA20_POLY1305_SHA256:
5585 case TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
5586 case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256:
5587 return 1; /* no suite restriction */
5588 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
5589 case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256:
5590 case TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
5591 break;
5592 }
5593 }
5594 if (first == ECC_BYTE || first == ECDHE_PSK_BYTE || first == CHACHA_BYTE)
5595 extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS);
5596 if (!extension)
5597 return 1; /* no suite restriction */
5598
5599 for (curve = (SupportedCurve*)extension->data;
5600 curve && !key;
5601 curve = curve->next) {
5602
5603 #ifdef OPENSSL_EXTRA
5604 /* skip if name is not in supported ECC range
5605 * or disabled by user */
5606 if (wolfSSL_curve_is_disabled(ssl, curve->name))
5607 continue;
5608 #endif
5609
5610 /* find supported curve */
5611 switch (curve->name) {
5612#ifdef HAVE_ECC
5613 #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
5614 #ifndef NO_ECC_SECP
5615 case WOLFSSL_ECC_SECP160R1:
5616 oid = ECC_SECP160R1_OID;
5617 octets = 20;
5618 break;
5619 #endif /* !NO_ECC_SECP */
5620 #ifdef HAVE_ECC_SECPR2
5621 case WOLFSSL_ECC_SECP160R2:
5622 oid = ECC_SECP160R2_OID;
5623 octets = 20;
5624 break;
5625 #endif /* HAVE_ECC_SECPR2 */
5626 #ifdef HAVE_ECC_KOBLITZ
5627 case WOLFSSL_ECC_SECP160K1:
5628 oid = ECC_SECP160K1_OID;
5629 octets = 20;
5630 break;
5631 #endif /* HAVE_ECC_KOBLITZ */
5632 #endif
5633 #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
5634 #ifndef NO_ECC_SECP
5635 case WOLFSSL_ECC_SECP192R1:
5636 oid = ECC_SECP192R1_OID;
5637 octets = 24;
5638 break;
5639 #endif /* !NO_ECC_SECP */
5640 #ifdef HAVE_ECC_KOBLITZ
5641 case WOLFSSL_ECC_SECP192K1:
5642 oid = ECC_SECP192K1_OID;
5643 octets = 24;
5644 break;
5645 #endif /* HAVE_ECC_KOBLITZ */
5646 #endif
5647 #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
5648 #ifndef NO_ECC_SECP
5649 case WOLFSSL_ECC_SECP224R1:
5650 oid = ECC_SECP224R1_OID;
5651 octets = 28;
5652 break;
5653 #endif /* !NO_ECC_SECP */
5654 #ifdef HAVE_ECC_KOBLITZ
5655 case WOLFSSL_ECC_SECP224K1:
5656 oid = ECC_SECP224K1_OID;
5657 octets = 28;
5658 break;
5659 #endif /* HAVE_ECC_KOBLITZ */
5660 #endif
5661 #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
5662 #ifndef NO_ECC_SECP
5663 case WOLFSSL_ECC_SECP256R1:
5664 oid = ECC_SECP256R1_OID;
5665 octets = 32;
5666 break;
5667 #endif /* !NO_ECC_SECP */
5668 #endif /* !NO_ECC256 || HAVE_ALL_CURVES */
5669#endif
5670 #if (defined(HAVE_CURVE25519) || defined(HAVE_ED25519)) && ECC_MIN_KEY_SZ <= 256
5671 case WOLFSSL_ECC_X25519:
5672 oid = ECC_X25519_OID;
5673 octets = 32;
5674 break;
5675 #endif /* HAVE_CURVE25519 */
5676#ifdef HAVE_ECC
5677 #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
5678 #ifdef HAVE_ECC_KOBLITZ
5679 case WOLFSSL_ECC_SECP256K1:
5680 oid = ECC_SECP256K1_OID;
5681 octets = 32;
5682 break;
5683 #endif /* HAVE_ECC_KOBLITZ */
5684 #ifdef HAVE_ECC_BRAINPOOL
5685 case WOLFSSL_ECC_BRAINPOOLP256R1:
5686 oid = ECC_BRAINPOOLP256R1_OID;
5687 octets = 32;
5688 break;
5689 #endif /* HAVE_ECC_BRAINPOOL */
5690 #ifdef WOLFSSL_SM2
5691 case WOLFSSL_ECC_SM2P256V1:
5692 oid = ECC_SM2P256V1_OID;
5693 octets = 32;
5694 break;
5695 #endif /* WOLFSSL_SM2 */
5696 #endif
5697 #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
5698 #ifndef NO_ECC_SECP
5699 case WOLFSSL_ECC_SECP384R1:
5700 oid = ECC_SECP384R1_OID;
5701 octets = 48;
5702 break;
5703 #endif /* !NO_ECC_SECP */
5704 #ifdef HAVE_ECC_BRAINPOOL
5705 case WOLFSSL_ECC_BRAINPOOLP384R1:
5706 oid = ECC_BRAINPOOLP384R1_OID;
5707 octets = 48;
5708 break;
5709 #endif /* HAVE_ECC_BRAINPOOL */
5710 #endif
5711#endif
5712 #if (defined(HAVE_CURVE448) || defined(HAVE_ED448)) && ECC_MIN_KEY_SZ <= 448
5713 case WOLFSSL_ECC_X448:
5714 oid = ECC_X448_OID;
5715 octets = 57;
5716 break;
5717 #endif /* HAVE_CURVE448 */
5718#ifdef HAVE_ECC
5719 #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
5720 #ifdef HAVE_ECC_BRAINPOOL
5721 case WOLFSSL_ECC_BRAINPOOLP512R1:
5722 oid = ECC_BRAINPOOLP512R1_OID;
5723 octets = 64;
5724 break;
5725 #endif /* HAVE_ECC_BRAINPOOL */
5726 #endif
5727 #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
5728 #ifndef NO_ECC_SECP
5729 case WOLFSSL_ECC_SECP521R1:
5730 oid = ECC_SECP521R1_OID;
5731 octets = 66;
5732 break;
5733 #endif /* !NO_ECC_SECP */
5734 #endif
5735#endif
5736 default: continue; /* unsupported curve */
5737 }
5738
5739 foundCurve = 1;
5740
5741 #ifdef HAVE_ECC
5742 /* Set default Oid */
5743 if (defOid == 0 && ssl->eccTempKeySz <= octets && defSz > octets) {
5744 defOid = oid;
5745 defSz = octets;
5746 }
5747
5748 /* The eccTempKeySz is the preferred ephemeral key size */
5749 if (currOid == 0 && ssl->eccTempKeySz == octets)
5750 currOid = oid;
5751 if ((nextOid == 0 || nextSz > octets) && ssl->eccTempKeySz <= octets) {
5752 nextOid = oid;
5753 nextSz = octets;
5754 }
5755 #else
5756 if (defOid == 0 && defSz > octets) {
5757 defOid = oid;
5758 defSz = octets;
5759 }
5760
5761 if (currOid == 0)
5762 currOid = oid;
5763 if (nextOid == 0 || nextSz > octets) {
5764 nextOid = oid;
5765 nextSz = octets;
5766 }
5767 #endif
5768
5769 if (first == ECC_BYTE) {
5770 switch (second) {
5771#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
5772 /* ECDHE_ECDSA */
5773 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
5774 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
5775 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
5776 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
5777 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
5778 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
5779 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
5780 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
5781 case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
5782 case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8:
5783 key |= ssl->ecdhCurveOID == oid;
5784 ephmSuite = 1;
5785 break;
5786
5787 #ifdef WOLFSSL_STATIC_DH
5788 /* ECDH_ECDSA */
5789 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
5790 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
5791 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
5792 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
5793 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
5794 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
5795 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
5796 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
5797 if (oid == ECC_X25519_OID && defOid == oid) {
5798 defOid = 0;
5799 defSz = 80;
5800 }
5801 if (oid == ECC_X448_OID && defOid == oid) {
5802 defOid = 0;
5803 defSz = 80;
5804 }
5805 key |= ssl->pkCurveOID == oid;
5806 break;
5807 #endif /* WOLFSSL_STATIC_DH */
5808#endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
5809#ifndef NO_RSA
5810 /* ECDHE_RSA */
5811 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
5812 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
5813 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
5814 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
5815 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
5816 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
5817 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
5818 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
5819 key |= ssl->ecdhCurveOID == oid;
5820 ephmSuite = 1;
5821 break;
5822
5823 #if defined(HAVE_ECC) && defined(WOLFSSL_STATIC_DH)
5824 /* ECDH_RSA */
5825 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
5826 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
5827 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
5828 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
5829 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
5830 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
5831 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
5832 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
5833 if (oid == ECC_X25519_OID && defOid == oid) {
5834 defOid = 0;
5835 defSz = 80;
5836 }
5837 if (oid == ECC_X448_OID && defOid == oid) {
5838 defOid = 0;
5839 defSz = 80;
5840 }
5841 key |= ssl->pkCurveOID == oid;
5842 break;
5843 #endif /* HAVE_ECC && WOLFSSL_STATIC_DH */
5844#endif
5845 default:
5846 if (oid == ECC_X25519_OID && defOid == oid) {
5847 defOid = 0;
5848 defSz = 80;
5849 }
5850 if (oid == ECC_X448_OID && defOid == oid) {
5851 defOid = 0;
5852 defSz = 80;
5853 }
5854 key = 1;
5855 break;
5856 }
5857 }
5858
5859 /* ChaCha20-Poly1305 ECC cipher suites */
5860 if (first == CHACHA_BYTE) {
5861 switch (second) {
5862#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
5863 /* ECDHE_ECDSA */
5864 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 :
5865 case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
5866 key |= ssl->ecdhCurveOID == oid;
5867 ephmSuite = 1;
5868 break;
5869#endif /* HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */
5870#ifndef NO_RSA
5871 /* ECDHE_RSA */
5872 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 :
5873 case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 :
5874 key |= ssl->ecdhCurveOID == oid;
5875 ephmSuite = 1;
5876 break;
5877#endif
5878 default:
5879 key = 1;
5880 break;
5881 }
5882 }
5883 }
5884
5885 /* Check we found at least one supported curve */
5886 if (!foundCurve)
5887 return 0;
5888
5889 *ecdhCurveOID = ssl->ecdhCurveOID;
5890 /* Choose the default if it is at the required strength. */
5891#ifdef HAVE_ECC
5892 if (*ecdhCurveOID == 0 && defSz == ssl->eccTempKeySz)
5893#else
5894 if (*ecdhCurveOID == 0)
5895#endif
5896 {
5897 key = 1;
5898 *ecdhCurveOID = defOid;
5899 }
5900 /* Choose any curve at the required strength. */
5901 if (*ecdhCurveOID == 0) {
5902 key = 1;
5903 *ecdhCurveOID = currOid;
5904 }
5905 /* Choose the default if it is at the next highest strength. */
5906 if (*ecdhCurveOID == 0 && defSz == nextSz)
5907 *ecdhCurveOID = defOid;
5908 /* Choose any curve at the next highest strength. */
5909 if (*ecdhCurveOID == 0)
5910 *ecdhCurveOID = nextOid;
5911 /* No curve and ephemeral ECC suite requires a matching curve. */
5912 if (*ecdhCurveOID == 0 && ephmSuite)
5913 key = 0;
5914
5915 return key;
5916}
5917#endif
5918
5919#endif /* NO_WOLFSSL_SERVER */
5920
5921
5922int TLSX_SupportedCurve_Copy(TLSX* src, TLSX** dst, void* heap)
5923{
5924 TLSX* extension;
5925 int ret;
5926
5927 extension = TLSX_Find(src, TLSX_SUPPORTED_GROUPS);
5928 if (extension != NULL) {
5929 SupportedCurve* curve;
5930 for (curve = (SupportedCurve*)extension->data; curve != NULL;
5931 curve = curve->next) {
5932 ret = TLSX_UseSupportedCurve(dst, curve->name, heap);
5933 if (ret != WOLFSSL_SUCCESS)
5934 return MEMORY_E;
5935 }
5936 }
5937
5938 return 0;
5939}
5940
5941int TLSX_UseSupportedCurve(TLSX** extensions, word16 name, void* heap)
5942{
5943 TLSX* extension = NULL;
5944 SupportedCurve* curve = NULL;
5945 int ret;
5946
5947 if (extensions == NULL) {
5948 return BAD_FUNC_ARG;
5949 }
5950
5951 if (! TLSX_IsGroupSupported(name)) {
5952 return BAD_FUNC_ARG;
5953 }
5954
5955 extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
5956
5957 if (!extension) {
5958 ret = TLSX_SupportedCurve_New(&curve, name, heap);
5959 if (ret != 0)
5960 return ret;
5961
5962 ret = TLSX_Push(extensions, TLSX_SUPPORTED_GROUPS, curve, heap);
5963 if (ret != 0) {
5964 XFREE(curve, heap, DYNAMIC_TYPE_TLSX);
5965 return ret;
5966 }
5967 }
5968 else {
5969 ret = TLSX_SupportedCurve_Append((SupportedCurve*)extension->data, name,
5970 heap);
5971 if (ret != 0)
5972 return ret;
5973 #if defined(WOLFSSL_ML_KEM_USE_OLD_IDS) && \
5974 defined (WOLFSSL_EXTRA_PQC_HYBRIDS)
5975 if (name == WOLFSSL_SECP256R1MLKEM512) {
5976 ret = TLSX_SupportedCurve_Append((SupportedCurve*)extension->data,
5977 WOLFSSL_P256_ML_KEM_512_OLD, heap);
5978 }
5979 else if (name == WOLFSSL_SECP384R1MLKEM768) {
5980 ret = TLSX_SupportedCurve_Append((SupportedCurve*)extension->data,
5981 WOLFSSL_P384_ML_KEM_768_OLD, heap);
5982 }
5983 else if (name == WOLFSSL_SECP521R1MLKEM1024) {
5984 ret = TLSX_SupportedCurve_Append((SupportedCurve*)extension->data,
5985 WOLFSSL_P521_ML_KEM_1024_OLD, heap);
5986 }
5987 if (ret != 0) {
5988 return ret;
5989 }
5990 #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS && WOLFSSL_EXTRA_PQC_HYBRIDS */
5991 }
5992
5993 return WOLFSSL_SUCCESS;
5994}
5995
5996int TLSX_UsePointFormat(TLSX** extensions, byte format, void* heap)
5997{
5998 TLSX* extension = NULL;
5999 PointFormat* point = NULL;
6000 int ret = 0;
6001
6002 if (extensions == NULL)
6003 return BAD_FUNC_ARG;
6004
6005 extension = TLSX_Find(*extensions, TLSX_EC_POINT_FORMATS);
6006
6007 if (!extension) {
6008 ret = TLSX_PointFormat_New(&point, format, heap);
6009 if (ret != 0)
6010 return ret;
6011
6012 ret = TLSX_Push(extensions, TLSX_EC_POINT_FORMATS, point, heap);
6013 if (ret != 0) {
6014 XFREE(point, heap, DYNAMIC_TYPE_TLSX);
6015 return ret;
6016 }
6017 }
6018 else {
6019 ret = TLSX_PointFormat_Append((PointFormat*)extension->data, format,
6020 heap);
6021 if (ret != 0)
6022 return ret;
6023 }
6024
6025 return WOLFSSL_SUCCESS;
6026}
6027
6028#define EC_FREE_ALL TLSX_SupportedCurve_FreeAll
6029#define EC_VALIDATE_REQUEST TLSX_SupportedCurve_ValidateRequest
6030
6031/* In TLS 1.2 the server never sends supported curve extension, but in TLS 1.3
6032 * the server can send supported groups extension to indicate what it will
6033 * support for later connections. */
6034#if !defined(NO_WOLFSSL_CLIENT) || defined(WOLFSSL_TLS13)
6035#define EC_GET_SIZE TLSX_SupportedCurve_GetSize
6036#define EC_WRITE TLSX_SupportedCurve_Write
6037#else
6038#define EC_GET_SIZE(list) 0
6039#define EC_WRITE(a, b) 0
6040#endif
6041
6042#if !defined(NO_WOLFSSL_SERVER) || (defined(WOLFSSL_TLS13) && \
6043 !defined(WOLFSSL_NO_SERVER_GROUPS_EXT))
6044#define EC_PARSE TLSX_SupportedCurve_Parse
6045#else
6046#define EC_PARSE(a, b, c, d, e) 0
6047#endif
6048
6049#define PF_FREE_ALL TLSX_PointFormat_FreeAll
6050#define PF_VALIDATE_REQUEST TLSX_PointFormat_ValidateRequest
6051#define PF_VALIDATE_RESPONSE TLSX_PointFormat_ValidateResponse
6052
6053#define PF_GET_SIZE TLSX_PointFormat_GetSize
6054#define PF_WRITE TLSX_PointFormat_Write
6055
6056#ifndef NO_WOLFSSL_SERVER
6057#define PF_PARSE TLSX_PointFormat_Parse
6058#else
6059#define PF_PARSE(a, b, c, d) 0
6060#endif
6061
6062#else
6063
6064#define EC_FREE_ALL(list, heap) WC_DO_NOTHING
6065#define EC_GET_SIZE(list) 0
6066#define EC_WRITE(a, b) 0
6067#define EC_PARSE(a, b, c, d, e) 0
6068#define EC_VALIDATE_REQUEST(a, b) WC_DO_NOTHING
6069
6070#define PF_FREE_ALL(list, heap) WC_DO_NOTHING
6071#define PF_GET_SIZE(list) 0
6072#define PF_WRITE(a, b) 0
6073#define PF_PARSE(a, b, c, d) 0
6074#define PF_VALIDATE_REQUEST(a, b) WC_DO_NOTHING
6075#define PF_VALIDATE_RESPONSE(a, b) WC_DO_NOTHING
6076
6077#endif /* HAVE_SUPPORTED_CURVES */
6078
6079/******************************************************************************/
6080/* Renegotiation Indication */
6081/******************************************************************************/
6082
6083#if defined(HAVE_SECURE_RENEGOTIATION) \
6084 || defined(HAVE_SERVER_RENEGOTIATION_INFO)
6085
6086static byte TLSX_SecureRenegotiation_GetSize(SecureRenegotiation* data,
6087 int isRequest)
6088{
6089 byte length = OPAQUE8_LEN; /* empty info length */
6090
6091 /* data will be NULL for HAVE_SERVER_RENEGOTIATION_INFO only */
6092 if (data && data->enabled && data->verifySet) {
6093 /* client sends client_verify_data only */
6094 length += TLS_FINISHED_SZ;
6095
6096 /* server also sends server_verify_data */
6097 if (!isRequest)
6098 length += TLS_FINISHED_SZ;
6099 }
6100
6101 return length;
6102}
6103
6104static word16 TLSX_SecureRenegotiation_Write(SecureRenegotiation* data,
6105 byte* output, int isRequest)
6106{
6107 word16 offset = OPAQUE8_LEN; /* RenegotiationInfo length */
6108 if (data && data->enabled && data->verifySet) {
6109 /* client sends client_verify_data only */
6110 XMEMCPY(output + offset, data->client_verify_data, TLS_FINISHED_SZ);
6111 offset += TLS_FINISHED_SZ;
6112
6113 /* server also sends server_verify_data */
6114 if (!isRequest) {
6115 XMEMCPY(output + offset, data->server_verify_data, TLS_FINISHED_SZ);
6116 offset += TLS_FINISHED_SZ;
6117 }
6118 }
6119
6120 output[0] = (byte)(offset - 1); /* info length - self */
6121
6122 return offset;
6123}
6124
6125static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, const byte* input,
6126 word16 length, byte isRequest)
6127{
6128 int ret = WC_NO_ERR_TRACE(SECURE_RENEGOTIATION_E);
6129
6130 if (length >= OPAQUE8_LEN) {
6131 if (isRequest) {
6132 #ifndef NO_WOLFSSL_SERVER
6133 if (ssl->secure_renegotiation == NULL) {
6134 ret = wolfSSL_UseSecureRenegotiation(ssl);
6135 if (ret == WOLFSSL_SUCCESS)
6136 ret = 0;
6137 }
6138 if (ret != 0 && ret != WC_NO_ERR_TRACE(SECURE_RENEGOTIATION_E)) {
6139 }
6140 else if (ssl->secure_renegotiation == NULL) {
6141 }
6142 else if (!ssl->secure_renegotiation->enabled) {
6143 if (*input == 0) {
6144 input++; /* get past size */
6145
6146 ssl->secure_renegotiation->enabled = 1;
6147 TLSX_SetResponse(ssl, TLSX_RENEGOTIATION_INFO);
6148 ret = 0;
6149 }
6150 else {
6151 /* already in error state */
6152 WOLFSSL_MSG("SCR client verify data present");
6153 }
6154 }
6155 else if (*input == TLS_FINISHED_SZ) {
6156 if (length < TLS_FINISHED_SZ + 1) {
6157 WOLFSSL_MSG("SCR malformed buffer");
6158 ret = BUFFER_E;
6159 }
6160 else {
6161 input++; /* get past size */
6162
6163 /* validate client verify data */
6164 if (ConstantCompare(input,
6165 ssl->secure_renegotiation->client_verify_data,
6166 TLS_FINISHED_SZ) == 0) {
6167 WOLFSSL_MSG("SCR client verify data match");
6168 TLSX_SetResponse(ssl, TLSX_RENEGOTIATION_INFO);
6169 ret = 0; /* verified */
6170 }
6171 else {
6172 /* already in error state */
6173 WOLFSSL_MSG("SCR client verify data Failure");
6174 }
6175 }
6176 }
6177 #endif
6178 }
6179 else if (ssl->secure_renegotiation != NULL) {
6180 #ifndef NO_WOLFSSL_CLIENT
6181 if (!ssl->secure_renegotiation->enabled) {
6182 if (*input == 0) {
6183 ssl->secure_renegotiation->enabled = 1;
6184 ret = 0;
6185 }
6186 }
6187 else if (*input == 2 * TLS_FINISHED_SZ &&
6188 length == 2 * TLS_FINISHED_SZ + OPAQUE8_LEN) {
6189 int cmpRes = 0;
6190 input++; /* get past size */
6191 cmpRes |= ConstantCompare(input,
6192 ssl->secure_renegotiation->client_verify_data,
6193 TLS_FINISHED_SZ);
6194 cmpRes |= ConstantCompare(input + TLS_FINISHED_SZ,
6195 ssl->secure_renegotiation->server_verify_data,
6196 TLS_FINISHED_SZ);
6197 /* validate client and server verify data */
6198 if (cmpRes == 0) {
6199 WOLFSSL_MSG("SCR client and server verify data match");
6200 ret = 0; /* verified */
6201 }
6202 else {
6203 /* already in error state */
6204 WOLFSSL_MSG("SCR client and server verify data Failure");
6205 }
6206 }
6207 #endif
6208 }
6209 else {
6210 ret = SECURE_RENEGOTIATION_E;
6211 }
6212 }
6213 else {
6214 ret = SECURE_RENEGOTIATION_E;
6215 }
6216
6217 if (ret != 0) {
6218 WOLFSSL_ERROR_VERBOSE(ret);
6219 SendAlert(ssl, alert_fatal, handshake_failure);
6220 }
6221
6222 return ret;
6223}
6224
6225int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap)
6226{
6227 int ret = 0;
6228 SecureRenegotiation* data;
6229
6230 data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), heap,
6231 DYNAMIC_TYPE_TLSX);
6232 if (data == NULL)
6233 return MEMORY_E;
6234
6235 XMEMSET(data, 0, sizeof(SecureRenegotiation));
6236
6237 ret = TLSX_Push(extensions, TLSX_RENEGOTIATION_INFO, data, heap);
6238 if (ret != 0) {
6239 XFREE(data, heap, DYNAMIC_TYPE_TLSX);
6240 return ret;
6241 }
6242
6243 return WOLFSSL_SUCCESS;
6244}
6245
6246#ifdef HAVE_SERVER_RENEGOTIATION_INFO
6247
6248int TLSX_AddEmptyRenegotiationInfo(TLSX** extensions, void* heap)
6249{
6250 int ret;
6251
6252 /* send empty renegotiation_info extension */
6253 TLSX* ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO);
6254 if (ext == NULL) {
6255 ret = TLSX_UseSecureRenegotiation(extensions, heap);
6256 if (ret != WOLFSSL_SUCCESS)
6257 return ret;
6258
6259 ext = TLSX_Find(*extensions, TLSX_RENEGOTIATION_INFO);
6260 }
6261 if (ext)
6262 ext->resp = 1;
6263
6264 return WOLFSSL_SUCCESS;
6265}
6266
6267#endif /* HAVE_SERVER_RENEGOTIATION_INFO */
6268
6269
6270#define SCR_FREE_ALL(data, heap) XFREE(data, (heap), DYNAMIC_TYPE_TLSX)
6271#define SCR_GET_SIZE TLSX_SecureRenegotiation_GetSize
6272#define SCR_WRITE TLSX_SecureRenegotiation_Write
6273#define SCR_PARSE TLSX_SecureRenegotiation_Parse
6274
6275#else
6276
6277#define SCR_FREE_ALL(a, heap) WC_DO_NOTHING
6278#define SCR_GET_SIZE(a, b) 0
6279#define SCR_WRITE(a, b, c) 0
6280#define SCR_PARSE(a, b, c, d) 0
6281
6282#endif /* HAVE_SECURE_RENEGOTIATION || HAVE_SERVER_RENEGOTIATION_INFO */
6283
6284/******************************************************************************/
6285/* Session Tickets */
6286/******************************************************************************/
6287
6288#ifdef HAVE_SESSION_TICKET
6289
6290static word16 TLSX_SessionTicket_GetSize(SessionTicket* ticket, int isRequest)
6291{
6292 (void)isRequest;
6293 return ticket ? ticket->size : 0;
6294}
6295
6296static word16 TLSX_SessionTicket_Write(SessionTicket* ticket, byte* output,
6297 int isRequest)
6298{
6299 word16 offset = 0; /* empty ticket */
6300
6301 if (isRequest && ticket) {
6302 XMEMCPY(output + offset, ticket->data, ticket->size);
6303 offset += ticket->size;
6304 }
6305
6306 return offset;
6307}
6308
6309
6310static int TLSX_SessionTicket_Parse(WOLFSSL* ssl, const byte* input,
6311 word16 length, byte isRequest)
6312{
6313 int ret = 0;
6314
6315 (void) input; /* avoid unused parameter if NO_WOLFSSL_SERVER defined */
6316
6317 if (!isRequest) {
6318 if (TLSX_CheckUnsupportedExtension(ssl, TLSX_SESSION_TICKET))
6319 return TLSX_HandleUnsupportedExtension(ssl);
6320
6321 if (length != 0)
6322 return BUFFER_ERROR;
6323
6324#ifndef NO_WOLFSSL_CLIENT
6325 ssl->expect_session_ticket = 1;
6326#endif
6327 }
6328#ifndef NO_WOLFSSL_SERVER
6329 else {
6330 /* server side */
6331 if (ssl->ctx->ticketEncCb == NULL) {
6332 WOLFSSL_MSG("Client sent session ticket, server has no callback");
6333 return 0;
6334 }
6335
6336#ifdef HAVE_SECURE_RENEGOTIATION
6337 if (IsSCR(ssl)) {
6338 WOLFSSL_MSG("Client sent session ticket during SCR. Ignoring.");
6339 return 0;
6340 }
6341#endif
6342
6343 if (length > SESSION_TICKET_LEN) {
6344 ret = BAD_TICKET_MSG_SZ;
6345 WOLFSSL_ERROR_VERBOSE(ret);
6346 } else if (IsAtLeastTLSv1_3(ssl->version)) {
6347 WOLFSSL_MSG("Process client ticket rejected, TLS 1.3 no support");
6348 ssl->options.rejectTicket = 1;
6349 ret = 0; /* not fatal */
6350 } else if (ssl->options.noTicketTls12) {
6351 /* ignore ticket request */
6352 } else if (length == 0) {
6353 /* blank ticket */
6354 ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
6355 if (ret == WOLFSSL_SUCCESS) {
6356 ret = 0;
6357 /* send blank ticket */
6358 TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
6359 ssl->options.createTicket = 1; /* will send ticket msg */
6360 ssl->options.useTicket = 1;
6361 ssl->options.resuming = 0; /* no standard resumption */
6362 ssl->arrays->sessionIDSz = 0; /* no echo on blank ticket */
6363 }
6364 } else {
6365 /* got actual ticket from client */
6366 ret = DoClientTicket(ssl, input, length);
6367 if (ret == WOLFSSL_TICKET_RET_OK) { /* use ticket to resume */
6368 WOLFSSL_MSG("Using existing client ticket");
6369 ssl->options.useTicket = 1;
6370 ssl->options.resuming = 1;
6371 /* SERVER: ticket is peer auth. */
6372 ssl->options.peerAuthGood = 1;
6373 } else if (ret == WOLFSSL_TICKET_RET_CREATE) {
6374 WOLFSSL_MSG("Using existing client ticket, creating new one");
6375 ret = TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
6376 if (ret == WOLFSSL_SUCCESS) {
6377 ret = 0;
6378 TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
6379 /* send blank ticket */
6380 ssl->options.createTicket = 1; /* will send ticket msg */
6381 ssl->options.useTicket = 1;
6382 ssl->options.resuming = 1;
6383 /* SERVER: ticket is peer auth. */
6384 ssl->options.peerAuthGood = 1;
6385 }
6386 } else if (ret == WOLFSSL_TICKET_RET_REJECT ||
6387 ret == WC_NO_ERR_TRACE(VERSION_ERROR)) {
6388 WOLFSSL_MSG("Process client ticket rejected, not using");
6389 if (ret == WC_NO_ERR_TRACE(VERSION_ERROR))
6390 WOLFSSL_MSG("\tbad TLS version");
6391 ret = 0; /* not fatal */
6392
6393 ssl->options.rejectTicket = 1;
6394 /* If we have session tickets enabled then send a new ticket */
6395 if (!TLSX_CheckUnsupportedExtension(ssl, TLSX_SESSION_TICKET)) {
6396 ret = TLSX_UseSessionTicket(&ssl->extensions, NULL,
6397 ssl->heap);
6398 if (ret == WOLFSSL_SUCCESS) {
6399 ret = 0;
6400 TLSX_SetResponse(ssl, TLSX_SESSION_TICKET);
6401 ssl->options.createTicket = 1;
6402 ssl->options.useTicket = 1;
6403 }
6404 }
6405 } else if (ret == WOLFSSL_TICKET_RET_FATAL) {
6406 WOLFSSL_MSG("Process client ticket fatal error, not using");
6407 } else if (ret < 0) {
6408 WOLFSSL_MSG("Process client ticket unknown error, not using");
6409 }
6410 }
6411 }
6412#endif /* NO_WOLFSSL_SERVER */
6413
6414#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER)
6415 (void)ssl;
6416#endif
6417
6418 return ret;
6419}
6420
6421WOLFSSL_TEST_VIS SessionTicket* TLSX_SessionTicket_Create(word32 lifetime,
6422 byte* data, word16 size, void* heap)
6423{
6424 SessionTicket* ticket = (SessionTicket*)XMALLOC(sizeof(SessionTicket),
6425 heap, DYNAMIC_TYPE_TLSX);
6426 if (ticket) {
6427 ticket->data = (byte*)XMALLOC(size, heap, DYNAMIC_TYPE_TLSX);
6428 if (ticket->data == NULL) {
6429 XFREE(ticket, heap, DYNAMIC_TYPE_TLSX);
6430 return NULL;
6431 }
6432
6433 XMEMCPY(ticket->data, data, size);
6434 ticket->size = size;
6435 ticket->lifetime = lifetime;
6436 }
6437
6438 (void)heap;
6439
6440 return ticket;
6441}
6442WOLFSSL_TEST_VIS void TLSX_SessionTicket_Free(SessionTicket* ticket, void* heap)
6443{
6444 if (ticket) {
6445 XFREE(ticket->data, heap, DYNAMIC_TYPE_TLSX);
6446 XFREE(ticket, heap, DYNAMIC_TYPE_TLSX);
6447 }
6448
6449 (void)heap;
6450}
6451
6452int TLSX_UseSessionTicket(TLSX** extensions, SessionTicket* ticket, void* heap)
6453{
6454 int ret = 0;
6455
6456 if (extensions == NULL)
6457 return BAD_FUNC_ARG;
6458
6459 /* If the ticket is NULL, the client will request a new ticket from the
6460 server. Otherwise, the client will use it in the next client hello. */
6461 if ((ret = TLSX_Push(extensions, TLSX_SESSION_TICKET, (void*)ticket, heap))
6462 != 0)
6463 return ret;
6464
6465 return WOLFSSL_SUCCESS;
6466}
6467
6468#define WOLF_STK_GET_SIZE TLSX_SessionTicket_GetSize
6469#define WOLF_STK_WRITE TLSX_SessionTicket_Write
6470#define WOLF_STK_PARSE TLSX_SessionTicket_Parse
6471#define WOLF_STK_FREE(stk, heap) TLSX_SessionTicket_Free((SessionTicket*)(stk),(heap))
6472
6473#else
6474
6475#define WOLF_STK_FREE(a, b) WC_DO_NOTHING
6476#define WOLF_STK_VALIDATE_REQUEST(a) WC_DO_NOTHING
6477#define WOLF_STK_GET_SIZE(a, b) 0
6478#define WOLF_STK_WRITE(a, b, c) 0
6479#define WOLF_STK_PARSE(a, b, c, d) 0
6480
6481#endif /* HAVE_SESSION_TICKET */
6482
6483#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
6484/******************************************************************************/
6485/* Encrypt-then-MAC */
6486/******************************************************************************/
6487
6488#ifndef WOLFSSL_NO_TLS12
6489static int TLSX_EncryptThenMac_Use(WOLFSSL* ssl);
6490
6491/**
6492 * Get the size of the Encrypt-Then-MAC extension.
6493 *
6494 * msgType Type of message to put extension into.
6495 * pSz Size of extension data.
6496 * return SANITY_MSG_E when the message is not allowed to have extension and
6497 * 0 otherwise.
6498 */
6499static int TLSX_EncryptThenMac_GetSize(byte msgType, word16* pSz)
6500{
6501 (void)pSz;
6502
6503 if (msgType != client_hello && msgType != server_hello) {
6504 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
6505 return SANITY_MSG_E;
6506 }
6507
6508 /* Empty extension */
6509
6510 return 0;
6511}
6512
6513/**
6514 * Write the Encrypt-Then-MAC extension.
6515 *
6516 * data Unused
6517 * output Extension data buffer. Unused.
6518 * msgType Type of message to put extension into.
6519 * pSz Size of extension data.
6520 * return SANITY_MSG_E when the message is not allowed to have extension and
6521 * 0 otherwise.
6522 */
6523static int TLSX_EncryptThenMac_Write(void* data, byte* output, byte msgType,
6524 word16* pSz)
6525{
6526 (void)data;
6527 (void)output;
6528 (void)pSz;
6529
6530 if (msgType != client_hello && msgType != server_hello) {
6531 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
6532 return SANITY_MSG_E;
6533 }
6534
6535 /* Empty extension */
6536
6537 return 0;
6538}
6539
6540/**
6541 * Parse the Encrypt-Then-MAC extension.
6542 *
6543 * ssl SSL object
6544 * input Extension data buffer.
6545 * length Length of this extension's data.
6546 * msgType Type of message to extension appeared in.
6547 * return SANITY_MSG_E when the message is not allowed to have extension,
6548 * BUFFER_ERROR when the extension's data is invalid,
6549 * MEMORY_E when unable to allocate memory and
6550 * 0 otherwise.
6551 */
6552static int TLSX_EncryptThenMac_Parse(WOLFSSL* ssl, const byte* input,
6553 word16 length, byte msgType)
6554{
6555 int ret;
6556
6557 (void)input;
6558
6559 if (msgType != client_hello && msgType != server_hello) {
6560 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
6561 return SANITY_MSG_E;
6562 }
6563
6564 /* Empty extension */
6565 if (length != 0)
6566 return BUFFER_ERROR;
6567
6568 if (msgType == client_hello) {
6569 /* Check the user hasn't disallowed use of Encrypt-Then-Mac. */
6570 if (!ssl->options.disallowEncThenMac) {
6571 ssl->options.encThenMac = 1;
6572 /* Set the extension reply. */
6573 ret = TLSX_EncryptThenMac_Use(ssl);
6574 if (ret != 0)
6575 return ret;
6576 }
6577 return 0;
6578 }
6579
6580 /* Server Hello */
6581 if (ssl->options.disallowEncThenMac) {
6582 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
6583 return SANITY_MSG_E;
6584 }
6585
6586 ssl->options.encThenMac = 1;
6587 return 0;
6588
6589}
6590
6591/**
6592 * Add the Encrypt-Then-MAC extension to list.
6593 *
6594 * ssl SSL object
6595 * return MEMORY_E when unable to allocate memory and 0 otherwise.
6596 */
6597static int TLSX_EncryptThenMac_Use(WOLFSSL* ssl)
6598{
6599 int ret = 0;
6600 TLSX* extension;
6601
6602 /* Find the Encrypt-Then-Mac extension if it exists. */
6603 extension = TLSX_Find(ssl->extensions, TLSX_ENCRYPT_THEN_MAC);
6604 if (extension == NULL) {
6605 /* Push new Encrypt-Then-Mac extension. */
6606 ret = TLSX_Push(&ssl->extensions, TLSX_ENCRYPT_THEN_MAC, NULL,
6607 ssl->heap);
6608 if (ret != 0)
6609 return ret;
6610 }
6611
6612 return 0;
6613}
6614
6615/**
6616 * Set the Encrypt-Then-MAC extension as one to respond too.
6617 *
6618 * ssl SSL object
6619 * return EXT_MISSING when EncryptThenMac extension not in list.
6620 */
6621int TLSX_EncryptThenMac_Respond(WOLFSSL* ssl)
6622{
6623 TLSX* extension;
6624
6625 extension = TLSX_Find(ssl->extensions, TLSX_ENCRYPT_THEN_MAC);
6626 if (extension == NULL)
6627 return EXT_MISSING;
6628 extension->resp = 1;
6629
6630 return 0;
6631}
6632
6633#define ETM_GET_SIZE TLSX_EncryptThenMac_GetSize
6634#define ETM_WRITE TLSX_EncryptThenMac_Write
6635#define ETM_PARSE TLSX_EncryptThenMac_Parse
6636
6637#else
6638
6639#define ETM_GET_SIZE(a, b) 0
6640#define ETM_WRITE(a, b, c, d) 0
6641#define ETM_PARSE(a, b, c, d) 0
6642
6643#endif /* !WOLFSSL_NO_TLS12 */
6644
6645#endif /* HAVE_ENCRYPT_THEN_MAC && !WOLFSSL_AEAD_ONLY */
6646
6647
6648#ifdef WOLFSSL_SRTP
6649
6650/******************************************************************************/
6651/* DTLS SRTP (Secure Real-time Transport Protocol) */
6652/******************************************************************************/
6653
6654/* Only support single SRTP profile */
6655typedef struct TlsxSrtp {
6656 word16 profileCount;
6657 word16 ids; /* selected bits */
6658} TlsxSrtp;
6659
6660#ifndef NO_WOLFSSL_SERVER
6661static int TLSX_UseSRTP_GetSize(TlsxSrtp *srtp)
6662{
6663 /* SRTP Profile Len (2)
6664 * SRTP Profiles (2)
6665 * MKI (master key id) Length */
6666 return (OPAQUE16_LEN + (srtp->profileCount * OPAQUE16_LEN) + 1);
6667}
6668#endif
6669
6670static TlsxSrtp* TLSX_UseSRTP_New(word16 ids, void* heap)
6671{
6672 TlsxSrtp* srtp;
6673 int i;
6674
6675 srtp = (TlsxSrtp*)XMALLOC(sizeof(TlsxSrtp), heap, DYNAMIC_TYPE_TLSX);
6676 if (srtp == NULL) {
6677 WOLFSSL_MSG("TLSX SRTP Memory failure");
6678 return NULL;
6679 }
6680
6681 /* count and test each bit set */
6682 srtp->profileCount = 0;
6683 for (i=0; i<16; i++) {
6684 if (ids & (1 << i)) {
6685 srtp->profileCount++;
6686 }
6687 }
6688 srtp->ids = ids;
6689
6690 return srtp;
6691}
6692
6693static void TLSX_UseSRTP_Free(TlsxSrtp *srtp, void* heap)
6694{
6695 XFREE(srtp, heap, DYNAMIC_TYPE_TLSX);
6696 (void)heap;
6697}
6698
6699#ifndef NO_WOLFSSL_SERVER
6700static int TLSX_UseSRTP_Parse(WOLFSSL* ssl, const byte* input, word16 length,
6701 byte isRequest)
6702{
6703 int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
6704 word16 profile_len = 0;
6705 word16 profile_value = 0;
6706 word16 offset = 0;
6707 int i;
6708 TlsxSrtp* srtp = NULL;
6709
6710 if (length < OPAQUE16_LEN) {
6711 return BUFFER_ERROR;
6712 }
6713
6714 /* reset selected DTLS SRTP profile ID */
6715 ssl->dtlsSrtpId = 0;
6716
6717 /* total length, not include itself */
6718 ato16(input, &profile_len);
6719 offset += OPAQUE16_LEN;
6720 /* Check profile length is not bigger than remaining length. */
6721 if (profile_len > length - offset) {
6722 return BUFFER_ERROR;
6723 }
6724 /* Protection profiles are 2 bytes long - ensure not an odd no. bytes. */
6725 if ((profile_len & 1) == 1) {
6726 return BUFFER_ERROR;
6727 }
6728 /* Ignoring srtp_mki field - SRTP Make Key Identifier.
6729 * Defined to be 0..255 bytes long.
6730 */
6731 if ((length - profile_len - offset) > 255) {
6732 return BUFFER_ERROR;
6733 }
6734
6735 if (!isRequest) {
6736#ifndef NO_WOLFSSL_CLIENT
6737 /* Only one SRTP Protection Profile can be chosen. */
6738 if (profile_len != OPAQUE16_LEN) {
6739 return BUFFER_ERROR;
6740 }
6741
6742 ato16(input + offset, &profile_value);
6743
6744 /* check that the profile received was in the ones we support */
6745 if (profile_value < 16 &&
6746 (ssl->dtlsSrtpProfiles & (1 << profile_value))) {
6747 ssl->dtlsSrtpId = profile_value;
6748 ret = 0; /* success */
6749 }
6750#endif
6751 }
6752 else {
6753 /* parse remainder one profile at a time, looking for match in CTX */
6754 ret = 0;
6755 for (i = 0; i < profile_len; i += OPAQUE16_LEN) {
6756 ato16(input + offset + i, &profile_value);
6757 /* find first match */
6758 if (profile_value < 16 &&
6759 ssl->dtlsSrtpProfiles & (1 << profile_value)) {
6760 ssl->dtlsSrtpId = profile_value;
6761
6762 /* make sure we respond with selected SRTP id selected */
6763 srtp = TLSX_UseSRTP_New((1 << profile_value), ssl->heap);
6764 if (srtp != NULL) {
6765 ret = TLSX_Push(&ssl->extensions, TLSX_USE_SRTP,
6766 (void*)srtp, ssl->heap);
6767 if (ret == 0) {
6768 TLSX_SetResponse(ssl, TLSX_USE_SRTP);
6769 /* successfully set extension */
6770 }
6771 }
6772 else {
6773 ret = MEMORY_E;
6774 }
6775 break;
6776 }
6777 }
6778 }
6779
6780 if (ret == 0 && ssl->dtlsSrtpId == 0) {
6781 WOLFSSL_MSG("TLSX_UseSRTP_Parse profile not found!");
6782 /* not fatal */
6783 }
6784 else if (ret != 0) {
6785 ssl->dtlsSrtpId = 0;
6786 TLSX_UseSRTP_Free(srtp, ssl->heap);
6787 }
6788
6789 return ret;
6790}
6791
6792static word16 TLSX_UseSRTP_Write(TlsxSrtp* srtp, byte* output)
6793{
6794 word16 offset = 0;
6795 int i, j;
6796
6797 c16toa(srtp->profileCount * 2, output + offset);
6798 offset += OPAQUE16_LEN;
6799 j = 0;
6800 for (i = 0; i < srtp->profileCount; i++) {
6801 for (; j < 16; j++) {
6802 if (srtp->ids & (1 << j)) {
6803 c16toa(j, output + offset);
6804 offset += OPAQUE16_LEN;
6805 }
6806 }
6807 }
6808 output[offset++] = 0x00; /* MKI Length */
6809
6810 return offset;
6811}
6812#endif
6813
6814static int TLSX_UseSRTP(TLSX** extensions, word16 profiles, void* heap)
6815{
6816 int ret = 0;
6817 TLSX* extension;
6818
6819 if (extensions == NULL) {
6820 return BAD_FUNC_ARG;
6821 }
6822
6823 extension = TLSX_Find(*extensions, TLSX_USE_SRTP);
6824 if (extension == NULL) {
6825 TlsxSrtp* srtp = TLSX_UseSRTP_New(profiles, heap);
6826 if (srtp == NULL) {
6827 return MEMORY_E;
6828 }
6829
6830 ret = TLSX_Push(extensions, TLSX_USE_SRTP, (void*)srtp, heap);
6831 if (ret != 0) {
6832 TLSX_UseSRTP_Free(srtp, heap);
6833 }
6834 }
6835
6836 return ret;
6837}
6838
6839#ifndef NO_WOLFSSL_SERVER
6840 #define SRTP_FREE TLSX_UseSRTP_Free
6841 #define SRTP_PARSE TLSX_UseSRTP_Parse
6842 #define SRTP_WRITE TLSX_UseSRTP_Write
6843 #define SRTP_GET_SIZE TLSX_UseSRTP_GetSize
6844#else
6845 #define SRTP_FREE(a, b) WC_DO_NOTHING
6846 #define SRTP_PARSE(a, b, c, d) 0
6847 #define SRTP_WRITE(a, b) 0
6848 #define SRTP_GET_SIZE(a) 0
6849#endif
6850
6851#endif /* WOLFSSL_SRTP */
6852
6853
6854/******************************************************************************/
6855/* Supported Versions */
6856/******************************************************************************/
6857
6858#ifdef WOLFSSL_TLS13
6859static WC_INLINE int versionIsGreater(byte isDtls, byte a, byte b)
6860{
6861 (void)isDtls;
6862
6863#ifdef WOLFSSL_DTLS
6864 /* DTLS version increases backwards (-1,-2,-3,etc) */
6865 if (isDtls)
6866 return a < b;
6867#endif /* WOLFSSL_DTLS */
6868
6869 return a > b;
6870}
6871
6872static WC_INLINE int versionIsLesser(byte isDtls, byte a, byte b)
6873{
6874 (void)isDtls;
6875
6876#ifdef WOLFSSL_DTLS
6877 /* DTLS version increases backwards (-1,-2,-3,etc) */
6878 if (isDtls)
6879 return a > b;
6880#endif /* WOLFSSL_DTLS */
6881
6882 return a < b;
6883}
6884
6885static WC_INLINE int versionIsAtLeast(byte isDtls, byte a, byte b)
6886{
6887 (void)isDtls;
6888
6889#ifdef WOLFSSL_DTLS
6890 /* DTLS version increases backwards (-1,-2,-3,etc) */
6891 if (isDtls)
6892 return a <= b;
6893#endif /* WOLFSSL_DTLS */
6894
6895 return a >= b;
6896}
6897
6898static WC_INLINE int versionIsLessEqual(byte isDtls, byte a, byte b)
6899{
6900 (void)isDtls;
6901
6902#ifdef WOLFSSL_DTLS
6903 /* DTLS version increases backwards (-1,-2,-3,etc) */
6904 if (isDtls)
6905 return a >= b;
6906#endif /* WOLFSSL_DTLS */
6907
6908 return a <= b;
6909}
6910
6911/* Return the size of the SupportedVersions extension's data.
6912 *
6913 * data The SSL/TLS object.
6914 * msgType The type of the message this extension is being written into.
6915 * returns the length of data that will be in the extension.
6916 */
6917static int TLSX_SupportedVersions_GetSize(void* data, byte msgType, word16* pSz)
6918{
6919 WOLFSSL* ssl = (WOLFSSL*)data;
6920 byte tls13Minor, tls12Minor, tls11Minor, isDtls;
6921
6922 isDtls = !!ssl->options.dtls;
6923 tls13Minor = (byte)(isDtls ? DTLSv1_3_MINOR : TLSv1_3_MINOR);
6924 tls12Minor = (byte)(isDtls ? DTLSv1_2_MINOR : TLSv1_2_MINOR);
6925 tls11Minor = (byte)(isDtls ? DTLS_MINOR : TLSv1_1_MINOR);
6926
6927 /* unused on some configuration */
6928 (void)tls12Minor;
6929 (void)tls13Minor;
6930 (void)tls11Minor;
6931
6932 if (msgType == client_hello) {
6933 /* TLS v1.2 and TLS v1.3 */
6934 int cnt = 0;
6935
6936 if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13Minor)
6937 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
6938 defined(WOLFSSL_WPAS_SMALL)
6939 && (ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3) == 0
6940 #endif
6941 ) {
6942 cnt++;
6943 }
6944
6945 if (ssl->options.downgrade) {
6946 #ifndef WOLFSSL_NO_TLS12
6947 if (versionIsLessEqual(
6948 isDtls, ssl->options.minDowngrade, tls12Minor)
6949#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
6950 defined(WOLFSSL_WPAS_SMALL)
6951 && (ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2) == 0
6952#endif
6953 ) {
6954 cnt++;
6955 }
6956#endif
6957 #ifndef NO_OLD_TLS
6958 if (versionIsLessEqual(
6959 isDtls, ssl->options.minDowngrade, tls11Minor)
6960 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
6961 defined(WOLFSSL_WPAS_SMALL)
6962 && (ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1) == 0
6963 #endif
6964 ) {
6965 cnt++;
6966 }
6967 #ifdef WOLFSSL_ALLOW_TLSV10
6968 if (!ssl->options.dtls && (ssl->options.minDowngrade <= TLSv1_MINOR)
6969 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
6970 defined(WOLFSSL_WPAS_SMALL)
6971 && (ssl->options.mask & WOLFSSL_OP_NO_TLSv1) == 0
6972 #endif
6973 ) {
6974 cnt++;
6975 }
6976 #endif
6977 #endif
6978 }
6979
6980 *pSz += (word16)(OPAQUE8_LEN + cnt * OPAQUE16_LEN);
6981 }
6982 else if (msgType == server_hello || msgType == hello_retry_request) {
6983 *pSz += OPAQUE16_LEN;
6984 }
6985 else {
6986 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
6987 return SANITY_MSG_E;
6988 }
6989
6990 return 0;
6991}
6992
6993/* Writes the SupportedVersions extension into the buffer.
6994 *
6995 * data The SSL/TLS object.
6996 * output The buffer to write the extension into.
6997 * msgType The type of the message this extension is being written into.
6998 * returns the length of data that was written.
6999 */
7000static int TLSX_SupportedVersions_Write(void* data, byte* output,
7001 byte msgType, word16* pSz)
7002{
7003 WOLFSSL* ssl = (WOLFSSL*)data;
7004 byte tls13minor, tls12minor, tls11minor, isDtls = 0;
7005
7006 tls13minor = (byte)TLSv1_3_MINOR;
7007 tls12minor = (byte)TLSv1_2_MINOR;
7008 tls11minor = (byte)TLSv1_1_MINOR;
7009
7010 /* unused in some configuration */
7011 (void)tls11minor;
7012 (void)tls12minor;
7013
7014#ifdef WOLFSSL_DTLS13
7015 if (ssl->options.dtls) {
7016 tls13minor = (byte)DTLSv1_3_MINOR;
7017 #ifndef WOLFSSL_NO_TLS12
7018 tls12minor = (byte)DTLSv1_2_MINOR;
7019 #endif
7020 #ifndef NO_OLD_TLS
7021 tls11minor = (byte)DTLS_MINOR;
7022 #endif
7023 isDtls = 1;
7024 }
7025#endif /* WOLFSSL_DTLS13 */
7026
7027 if (msgType == client_hello) {
7028 byte major = ssl->ctx->method->version.major;
7029
7030 byte* cnt = output++;
7031 *cnt = 0;
7032
7033 if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls13minor)
7034#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
7035 defined(WOLFSSL_WPAS_SMALL)
7036 && (ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3) == 0
7037#endif
7038 ) {
7039 *cnt += OPAQUE16_LEN;
7040 #ifdef WOLFSSL_TLS13_DRAFT
7041 /* The TLS draft major number. */
7042 *(output++) = TLS_DRAFT_MAJOR;
7043 /* Version of draft supported. */
7044 *(output++) = TLS_DRAFT_MINOR;
7045 #else
7046 *(output++) = major;
7047 *(output++) = tls13minor;
7048 #endif
7049 }
7050
7051 if (ssl->options.downgrade) {
7052 #ifndef WOLFSSL_NO_TLS12
7053 if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls12minor)
7054#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
7055 defined(WOLFSSL_WPAS_SMALL)
7056 && (ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2) == 0
7057 #endif
7058 ) {
7059 *cnt += OPAQUE16_LEN;
7060 *(output++) = major;
7061 *(output++) = tls12minor;
7062 }
7063 #endif
7064
7065 #ifndef NO_OLD_TLS
7066 if (versionIsLessEqual(isDtls, ssl->options.minDowngrade, tls11minor)
7067 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
7068 defined(WOLFSSL_WPAS_SMALL)
7069 && (ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1) == 0
7070 #endif
7071 ) {
7072 *cnt += OPAQUE16_LEN;
7073 *(output++) = major;
7074 *(output++) = tls11minor;
7075 }
7076 #ifdef WOLFSSL_ALLOW_TLSV10
7077 if (!ssl->options.dtls && (ssl->options.minDowngrade <= TLSv1_MINOR)
7078 #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
7079 defined(WOLFSSL_WPAS_SMALL)
7080 && (ssl->options.mask & WOLFSSL_OP_NO_TLSv1) == 0
7081 #endif
7082 ) {
7083 *cnt += OPAQUE16_LEN;
7084 *(output++) = major;
7085 *(output++) = (byte)TLSv1_MINOR;
7086 }
7087 #endif
7088 #endif
7089 }
7090
7091 *pSz += (word16)(OPAQUE8_LEN + *cnt);
7092 }
7093 else if (msgType == server_hello || msgType == hello_retry_request) {
7094 output[0] = ssl->version.major;
7095 output[1] = ssl->version.minor;
7096
7097 *pSz += OPAQUE16_LEN;
7098 }
7099 else {
7100 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
7101 return SANITY_MSG_E;
7102 }
7103
7104 return 0;
7105}
7106
7107/* Parse the SupportedVersions extension.
7108 *
7109 * ssl The SSL/TLS object.
7110 * input The buffer with the extension data.
7111 * length The length of the extension data.
7112 * msgType The type of the message this extension is being parsed from.
7113 * pv The output ProtocolVersion for the negotiated version
7114 * opts The output options structure. Can be NULL.
7115 * exts The output extensions list. Can be NULL.
7116 * returns 0 on success, otherwise failure.
7117 */
7118int TLSX_SupportedVersions_Parse(const WOLFSSL* ssl, const byte* input,
7119 word16 length, byte msgType, ProtocolVersion* pv, Options* opts,
7120 TLSX** exts)
7121{
7122 /* The client's greatest minor version that we support */
7123 byte clientGreatestMinor = SSLv3_MINOR;
7124 int ret;
7125 byte major, minor;
7126 byte tls13minor, tls12minor;
7127 byte isDtls;
7128
7129 tls13minor = TLSv1_3_MINOR;
7130 tls12minor = TLSv1_2_MINOR;
7131 isDtls = ssl->options.dtls == 1;
7132
7133#ifdef WOLFSSL_DTLS13
7134 if (ssl->options.dtls) {
7135 tls13minor = DTLSv1_3_MINOR;
7136 tls12minor = DTLSv1_2_MINOR;
7137 clientGreatestMinor = DTLS_MINOR;
7138 }
7139#endif /* WOLFSSL_DTLS13 */
7140
7141 if (msgType == client_hello) {
7142 int i;
7143 int len;
7144 int set = 0;
7145
7146 /* Must contain a length and at least one version. */
7147 if (length < OPAQUE8_LEN + OPAQUE16_LEN || (length & 1) != 1
7148 || length > MAX_SV_EXT_LEN) {
7149 return BUFFER_ERROR;
7150 }
7151
7152 len = *input;
7153
7154 /* Protocol version array must fill rest of data. */
7155 if (length != (word16)OPAQUE8_LEN + len)
7156 return BUFFER_ERROR;
7157
7158 input++;
7159
7160 /* Find first match. */
7161 for (i = 0; i < len; i += OPAQUE16_LEN) {
7162 major = input[i];
7163 minor = input[i + OPAQUE8_LEN];
7164
7165#ifdef WOLFSSL_TLS13_DRAFT
7166 if (major == TLS_DRAFT_MAJOR && minor == TLS_DRAFT_MINOR) {
7167 major = SSLv3_MAJOR;
7168 minor = TLSv1_3_MINOR;
7169 }
7170#else
7171 if (major == TLS_DRAFT_MAJOR)
7172 continue;
7173#endif
7174
7175 if (major != ssl->ctx->method->version.major)
7176 continue;
7177
7178 /* No upgrade allowed. */
7179 if (versionIsGreater(isDtls, minor, ssl->version.minor))
7180 continue;
7181
7182 /* Check downgrade. */
7183 if (versionIsLesser(isDtls, minor, ssl->version.minor)) {
7184 if (!ssl->options.downgrade)
7185 continue;
7186
7187 if (versionIsLesser(isDtls, minor, ssl->options.minDowngrade))
7188 continue;
7189 }
7190 if (versionIsGreater(isDtls, minor, clientGreatestMinor))
7191 clientGreatestMinor = minor;
7192
7193 set = 1;
7194 }
7195 if (!set) {
7196 /* No common supported version was negotiated */
7197 SendAlert((WOLFSSL*)ssl, alert_fatal,
7198 wolfssl_alert_protocol_version);
7199 WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
7200 return VERSION_ERROR;
7201 }
7202 pv->minor = clientGreatestMinor;
7203 if (versionIsAtLeast(isDtls, clientGreatestMinor, tls13minor)) {
7204 if (opts != NULL)
7205 opts->tls1_3 = 1;
7206
7207 /* TLS v1.3 requires supported version extension */
7208 if (exts != NULL &&
7209 TLSX_Find(*exts, TLSX_SUPPORTED_VERSIONS) == NULL) {
7210 ret = TLSX_Push(exts,
7211 TLSX_SUPPORTED_VERSIONS, ssl, ssl->heap);
7212 if (ret != 0) {
7213 return ret;
7214 }
7215 /* *exts should be pointing to the TLSX_SUPPORTED_VERSIONS
7216 * ext in the list since it was pushed. */
7217 (*exts)->resp = 1;
7218 }
7219 }
7220
7221 }
7222 else if (msgType == server_hello || msgType == hello_retry_request) {
7223 /* Must contain one version. */
7224 if (length != OPAQUE16_LEN)
7225 return BUFFER_ERROR;
7226
7227 major = input[0];
7228 minor = input[OPAQUE8_LEN];
7229
7230 if (major != ssl->ctx->method->version.major) {
7231 WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
7232 return VERSION_ERROR;
7233 }
7234
7235 /* Can't downgrade with this extension below TLS v1.3. */
7236 if (versionIsLesser(isDtls, minor, tls13minor)) {
7237 WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
7238 return VERSION_ERROR;
7239 }
7240
7241 /* Version is TLS v1.2 to handle downgrading from TLS v1.3+. */
7242 if (ssl->options.downgrade && ssl->version.minor == tls12minor) {
7243 /* Set minor version back to TLS v1.3+ */
7244 pv->minor = ssl->ctx->method->version.minor;
7245 }
7246
7247 /* No upgrade allowed. */
7248 if (versionIsLesser(isDtls, ssl->version.minor, minor)) {
7249 WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
7250 return VERSION_ERROR;
7251 }
7252
7253 /* Check downgrade. */
7254 if (versionIsGreater(isDtls, ssl->version.minor, minor)) {
7255 if (!ssl->options.downgrade) {
7256 WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
7257 return VERSION_ERROR;
7258 }
7259
7260 if (versionIsLesser(
7261 isDtls, minor, ssl->options.minDowngrade)) {
7262 WOLFSSL_ERROR_VERBOSE(VERSION_ERROR);
7263 return VERSION_ERROR;
7264 }
7265
7266 /* Downgrade the version. */
7267 pv->minor = minor;
7268 }
7269 }
7270 else {
7271 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
7272 return SANITY_MSG_E;
7273 }
7274
7275 return 0;
7276}
7277
7278/* Sets a new SupportedVersions extension into the extension list.
7279 *
7280 * extensions The list of extensions.
7281 * data The extensions specific data.
7282 * heap The heap used for allocation.
7283 * returns 0 on success, otherwise failure.
7284 */
7285static int TLSX_SetSupportedVersions(TLSX** extensions, const void* data,
7286 void* heap)
7287{
7288 if (extensions == NULL || data == NULL)
7289 return BAD_FUNC_ARG;
7290
7291 return TLSX_Push(extensions, TLSX_SUPPORTED_VERSIONS, data, heap);
7292}
7293
7294#define SV_GET_SIZE TLSX_SupportedVersions_GetSize
7295#define SV_WRITE TLSX_SupportedVersions_Write
7296#define SV_PARSE TLSX_SupportedVersions_Parse
7297
7298#else
7299
7300#define SV_GET_SIZE(a, b, c) 0
7301#define SV_WRITE(a, b, c, d) 0
7302#define SV_PARSE(a, b, c, d, e, f, g) 0
7303
7304#endif /* WOLFSSL_TLS13 */
7305
7306#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
7307
7308/******************************************************************************/
7309/* Cookie */
7310/******************************************************************************/
7311
7312/* Free the cookie data.
7313 *
7314 * cookie Cookie data.
7315 * heap The heap used for allocation.
7316 */
7317static void TLSX_Cookie_FreeAll(Cookie* cookie, void* heap)
7318{
7319 (void)heap;
7320
7321 XFREE(cookie, heap, DYNAMIC_TYPE_TLSX);
7322}
7323
7324/* Get the size of the encoded Cookie extension.
7325 * In messages: ClientHello and HelloRetryRequest.
7326 *
7327 * cookie The cookie to write.
7328 * msgType The type of the message this extension is being written into.
7329 * returns the number of bytes of the encoded Cookie extension.
7330 */
7331static int TLSX_Cookie_GetSize(Cookie* cookie, byte msgType, word16* pSz)
7332{
7333 if (msgType == client_hello || msgType == hello_retry_request) {
7334 *pSz += OPAQUE16_LEN + cookie->len;
7335 }
7336 else {
7337 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
7338 return SANITY_MSG_E;
7339 }
7340 return 0;
7341}
7342
7343/* Writes the Cookie extension into the output buffer.
7344 * Assumes that the the output buffer is big enough to hold data.
7345 * In messages: ClientHello and HelloRetryRequest.
7346 *
7347 * cookie The cookie to write.
7348 * output The buffer to write into.
7349 * msgType The type of the message this extension is being written into.
7350 * returns the number of bytes written into the buffer.
7351 */
7352static int TLSX_Cookie_Write(Cookie* cookie, byte* output, byte msgType,
7353 word16* pSz)
7354{
7355 if (msgType == client_hello || msgType == hello_retry_request) {
7356 c16toa(cookie->len, output);
7357 output += OPAQUE16_LEN;
7358 XMEMCPY(output, cookie->data, cookie->len);
7359 *pSz += OPAQUE16_LEN + cookie->len;
7360 }
7361 else {
7362 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
7363 return SANITY_MSG_E;
7364 }
7365 return 0;
7366}
7367
7368/* Parse the Cookie extension.
7369 * In messages: ClientHello and HelloRetryRequest.
7370 *
7371 * ssl The SSL/TLS object.
7372 * input The extension data.
7373 * length The length of the extension data.
7374 * msgType The type of the message this extension is being parsed from.
7375 * returns 0 on success and other values indicate failure.
7376 */
7377static int TLSX_Cookie_Parse(WOLFSSL* ssl, const byte* input, word16 length,
7378 byte msgType)
7379{
7380 word16 len;
7381 word16 idx = 0;
7382 TLSX* extension;
7383 Cookie* cookie;
7384
7385 if (msgType != client_hello && msgType != hello_retry_request) {
7386 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
7387 return SANITY_MSG_E;
7388 }
7389
7390 /* Message contains length and Cookie which must be at least one byte
7391 * in length.
7392 */
7393 if (length < OPAQUE16_LEN + 1)
7394 return BUFFER_E;
7395 ato16(input + idx, &len);
7396 idx += OPAQUE16_LEN;
7397 if (length - idx != len)
7398 return BUFFER_E;
7399
7400 if (msgType == hello_retry_request) {
7401 ssl->options.hrrSentCookie = 1;
7402 return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 1,
7403 &ssl->extensions);
7404 }
7405
7406 /* client_hello */
7407 extension = TLSX_Find(ssl->extensions, TLSX_COOKIE);
7408 if (extension == NULL) {
7409#ifdef WOLFSSL_DTLS13
7410 if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version))
7411 /* Allow a cookie extension with DTLS 1.3 because it is possible
7412 * that a different SSL instance sent the cookie but we are now
7413 * receiving it. */
7414 return TLSX_Cookie_Use(ssl, input + idx, len, NULL, 0, 0,
7415 &ssl->extensions);
7416 else
7417#endif
7418 {
7419 WOLFSSL_ERROR_VERBOSE(HRR_COOKIE_ERROR);
7420 return HRR_COOKIE_ERROR;
7421 }
7422 }
7423
7424 cookie = (Cookie*)extension->data;
7425 if (cookie->len != len || XMEMCMP(cookie->data, input + idx, len) != 0) {
7426 WOLFSSL_ERROR_VERBOSE(HRR_COOKIE_ERROR);
7427 return HRR_COOKIE_ERROR;
7428 }
7429
7430 /* Request seen. */
7431 extension->resp = 0;
7432
7433 return 0;
7434}
7435
7436/* Use the data to create a new Cookie object in the extensions.
7437 *
7438 * ssl SSL/TLS object.
7439 * data Cookie data.
7440 * len Length of cookie data in bytes.
7441 * mac MAC data.
7442 * macSz Length of MAC data in bytes.
7443 * resp Indicates the extension will go into a response (HelloRetryRequest).
7444 * returns 0 on success and other values indicate failure.
7445 */
7446int TLSX_Cookie_Use(const WOLFSSL* ssl, const byte* data, word16 len, byte* mac,
7447 byte macSz, int resp, TLSX** exts)
7448{
7449 int ret = 0;
7450 TLSX* extension;
7451 Cookie* cookie;
7452
7453 /* Find the cookie extension if it exists. */
7454 extension = TLSX_Find(*exts, TLSX_COOKIE);
7455 if (extension == NULL) {
7456 /* Push new cookie extension. */
7457 ret = TLSX_Push(exts, TLSX_COOKIE, NULL, ssl->heap);
7458 if (ret != 0)
7459 return ret;
7460
7461 extension = TLSX_Find(*exts, TLSX_COOKIE);
7462 if (extension == NULL)
7463 return MEMORY_E;
7464 }
7465
7466 cookie = (Cookie*)XMALLOC(sizeof(Cookie) + len + macSz, ssl->heap,
7467 DYNAMIC_TYPE_TLSX);
7468 if (cookie == NULL)
7469 return MEMORY_E;
7470
7471 cookie->len = len + macSz;
7472 XMEMCPY(cookie->data, data, len);
7473 if (mac != NULL)
7474 XMEMCPY(cookie->data + len, mac, macSz);
7475
7476 XFREE(extension->data, ssl->heap, DYNAMIC_TYPE_TLSX);
7477
7478 extension->data = (void*)cookie;
7479 extension->resp = (byte)resp;
7480
7481 return 0;
7482}
7483
7484#define CKE_FREE_ALL TLSX_Cookie_FreeAll
7485#define CKE_GET_SIZE TLSX_Cookie_GetSize
7486#define CKE_WRITE TLSX_Cookie_Write
7487#define CKE_PARSE TLSX_Cookie_Parse
7488
7489#else
7490
7491#define CKE_FREE_ALL(a, b) WC_DO_NOTHING
7492#define CKE_GET_SIZE(a, b, c) 0
7493#define CKE_WRITE(a, b, c, d) 0
7494#define CKE_PARSE(a, b, c, d) 0
7495
7496#endif
7497
7498#if defined(WOLFSSL_TLS13) && !defined(NO_CERTS) && \
7499 !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
7500/* Currently only settable through compatibility API */
7501/******************************************************************************/
7502/* Certificate Authorities */
7503/******************************************************************************/
7504
7505static word16 TLSX_CA_Names_GetSize(void* data)
7506{
7507 WOLFSSL* ssl = (WOLFSSL*)data;
7508 WOLF_STACK_OF(WOLFSSL_X509_NAME)* names;
7509 word32 size = 0;
7510
7511 /* Length of names */
7512 size += OPAQUE16_LEN;
7513 for (names = SSL_PRIORITY_CA_NAMES(ssl); names != NULL; names = names->next) {
7514 byte seq[MAX_SEQ_SZ];
7515 WOLFSSL_X509_NAME* name = names->data.name;
7516
7517 if (name != NULL) {
7518 /* 16-bit length | SEQ | Len | DER of name */
7519 size += (word32)(OPAQUE16_LEN + SetSequence(name->rawLen, seq) +
7520 name->rawLen);
7521 if (size > WOLFSSL_MAX_16BIT) {
7522 return 0;
7523 }
7524 }
7525 }
7526 return (word16)size;
7527}
7528
7529static word16 TLSX_CA_Names_Write(void* data, byte* output)
7530{
7531 WOLFSSL* ssl = (WOLFSSL*)data;
7532 WOLF_STACK_OF(WOLFSSL_X509_NAME)* names;
7533 byte* len;
7534
7535 /* Reserve space for the length value */
7536 len = output;
7537 output += OPAQUE16_LEN;
7538 for (names = SSL_PRIORITY_CA_NAMES(ssl); names != NULL; names = names->next) {
7539 byte seq[MAX_SEQ_SZ];
7540 WOLFSSL_X509_NAME* name = names->data.name;
7541
7542 if (name != NULL) {
7543 c16toa((word16)name->rawLen +
7544 (word16)SetSequence(name->rawLen, seq), output);
7545 output += OPAQUE16_LEN;
7546 output += SetSequence(name->rawLen, output);
7547 XMEMCPY(output, name->raw, name->rawLen);
7548 output += name->rawLen;
7549 }
7550 }
7551 /* Write the total length */
7552 c16toa((word16)(output - len - OPAQUE16_LEN), len);
7553 return (word16)(output - len);
7554}
7555
7556static int TLSX_CA_Names_Parse(WOLFSSL *ssl, const byte* input,
7557 word16 length, byte isRequest)
7558{
7559 word16 extLen;
7560
7561 (void)isRequest;
7562
7563 wolfSSL_sk_X509_NAME_pop_free(ssl->peer_ca_names, NULL);
7564 ssl->peer_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
7565 if (ssl->peer_ca_names == NULL)
7566 return MEMORY_ERROR;
7567
7568 if (length < OPAQUE16_LEN)
7569 return BUFFER_ERROR;
7570
7571 ato16(input, &extLen);
7572 input += OPAQUE16_LEN;
7573 length -= OPAQUE16_LEN;
7574 if (extLen != length)
7575 return BUFFER_ERROR;
7576
7577 while (length) {
7578 word16 idx = 0;
7579 WOLFSSL_X509_NAME* name = NULL;
7580 int ret = 0;
7581 int didInit = FALSE;
7582 /* Use a DecodedCert struct to get access to GetName to
7583 * parse DN name */
7584#ifdef WOLFSSL_SMALL_STACK
7585 DecodedCert *cert = (DecodedCert *)XMALLOC(
7586 sizeof(*cert), ssl->heap, DYNAMIC_TYPE_DCERT);
7587 if (cert == NULL)
7588 return MEMORY_ERROR;
7589#else
7590 DecodedCert cert[1];
7591#endif
7592
7593 if (length < OPAQUE16_LEN) {
7594 ret = BUFFER_ERROR;
7595 }
7596
7597 if (ret == 0) {
7598 ato16(input, &extLen);
7599 idx += OPAQUE16_LEN;
7600
7601 if (extLen > length - idx)
7602 ret = BUFFER_ERROR;
7603 }
7604
7605 if (ret == 0) {
7606 InitDecodedCert(cert, input + idx, extLen, ssl->heap);
7607 didInit = TRUE;
7608 idx += extLen;
7609 ret = GetName(cert, ASN_SUBJECT, extLen);
7610 }
7611
7612 if (ret == 0 && (name = wolfSSL_X509_NAME_new()) == NULL)
7613 ret = MEMORY_ERROR;
7614
7615 if (ret == 0) {
7616 CopyDecodedName(name, cert, ASN_SUBJECT);
7617 if (wolfSSL_sk_X509_NAME_push(ssl->peer_ca_names, name) <= 0) {
7618 wolfSSL_X509_NAME_free(name);
7619 ret = MEMORY_ERROR;
7620 }
7621 }
7622
7623 if (didInit)
7624 FreeDecodedCert(cert);
7625
7626 WC_FREE_VAR_EX(cert, ssl->heap, DYNAMIC_TYPE_DCERT);
7627 if (ret != 0)
7628 return ret;
7629
7630 input += idx;
7631 length -= idx;
7632 }
7633 return 0;
7634}
7635
7636#define CAN_GET_SIZE(data) TLSX_CA_Names_GetSize(data)
7637#define CAN_WRITE(data, output) TLSX_CA_Names_Write(data, output)
7638#define CAN_PARSE(ssl, input, length, isRequest) \
7639 TLSX_CA_Names_Parse(ssl, input, length, isRequest)
7640
7641#else
7642
7643#define CAN_GET_SIZE(data) 0
7644#define CAN_WRITE(data, output) 0
7645#define CAN_PARSE(ssl, input, length, isRequest) 0
7646
7647#endif
7648
7649#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
7650/******************************************************************************/
7651/* Signature Algorithms */
7652/******************************************************************************/
7653
7654/* Return the size of the SignatureAlgorithms extension's data.
7655 *
7656 * data Unused
7657 * returns the length of data that will be in the extension.
7658 */
7659
7660static word16 TLSX_SignatureAlgorithms_GetSize(void* data)
7661{
7662 SignatureAlgorithms* sa = (SignatureAlgorithms*)data;
7663
7664 if (sa->hashSigAlgoSz == 0)
7665 return OPAQUE16_LEN + WOLFSSL_SUITES(sa->ssl)->hashSigAlgoSz;
7666 else
7667 return OPAQUE16_LEN + sa->hashSigAlgoSz;
7668}
7669
7670/* Creates a bit string of supported hash algorithms with RSA PSS.
7671 * The bit string is used when determining which signature algorithm to use
7672 * when creating the CertificateVerify message.
7673 * Note: Valid data has an even length as each signature algorithm is two bytes.
7674 *
7675 * ssl The SSL/TLS object.
7676 * input The buffer with the list of supported signature algorithms.
7677 * length The length of the list in bytes.
7678 * returns 0 on success, BUFFER_ERROR when the length is not even.
7679 */
7680static int TLSX_SignatureAlgorithms_MapPss(WOLFSSL *ssl, const byte* input,
7681 word16 length)
7682{
7683 word16 i;
7684
7685 if ((length & 1) == 1)
7686 return BUFFER_ERROR;
7687
7688 ssl->pssAlgo = 0;
7689 for (i = 0; i < length; i += 2) {
7690 if (input[i] == rsa_pss_sa_algo && input[i + 1] <= sha512_mac)
7691 ssl->pssAlgo |= 1 << input[i + 1];
7692 #ifdef WOLFSSL_TLS13
7693 if (input[i] == rsa_pss_sa_algo && input[i + 1] >= pss_sha256 &&
7694 input[i + 1] <= pss_sha512) {
7695 ssl->pssAlgo |= 1 << input[i + 1];
7696 }
7697 #endif
7698 }
7699
7700 return 0;
7701}
7702
7703/* Writes the SignatureAlgorithms extension into the buffer.
7704 *
7705 * data Unused
7706 * output The buffer to write the extension into.
7707 * returns the length of data that was written.
7708 */
7709static word16 TLSX_SignatureAlgorithms_Write(void* data, byte* output)
7710{
7711 SignatureAlgorithms* sa = (SignatureAlgorithms*)data;
7712 const Suites* suites = WOLFSSL_SUITES(sa->ssl);
7713 word16 hashSigAlgoSz;
7714
7715 if (sa->hashSigAlgoSz == 0) {
7716 c16toa(suites->hashSigAlgoSz, output);
7717 XMEMCPY(output + OPAQUE16_LEN, suites->hashSigAlgo,
7718 suites->hashSigAlgoSz);
7719 hashSigAlgoSz = suites->hashSigAlgoSz;
7720 }
7721 else {
7722 c16toa(sa->hashSigAlgoSz, output);
7723 XMEMCPY(output + OPAQUE16_LEN, sa->hashSigAlgo,
7724 sa->hashSigAlgoSz);
7725 hashSigAlgoSz = sa->hashSigAlgoSz;
7726 }
7727
7728#ifndef NO_RSA
7729 TLSX_SignatureAlgorithms_MapPss(sa->ssl, output + OPAQUE16_LEN,
7730 hashSigAlgoSz);
7731#endif
7732
7733 return OPAQUE16_LEN + hashSigAlgoSz;
7734}
7735
7736/* Parse the SignatureAlgorithms extension.
7737 *
7738 * ssl The SSL/TLS object.
7739 * input The buffer with the extension data.
7740 * length The length of the extension data.
7741 * returns 0 on success, otherwise failure.
7742 */
7743static int TLSX_SignatureAlgorithms_Parse(WOLFSSL *ssl, const byte* input,
7744 word16 length, byte isRequest, Suites* suites)
7745{
7746 word16 len;
7747
7748 if (!isRequest)
7749 return BUFFER_ERROR;
7750
7751 /* Must contain a length and at least algorithm. */
7752 if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0)
7753 return BUFFER_ERROR;
7754
7755 ato16(input, &len);
7756 input += OPAQUE16_LEN;
7757
7758 /* Algorithm array must fill rest of data. */
7759 if (length != OPAQUE16_LEN + len)
7760 return BUFFER_ERROR;
7761
7762 /* Truncate hashSigAlgo list if too long. */
7763 suites->hashSigAlgoSz = len;
7764 /* Sig Algo list size must be even. */
7765 if (suites->hashSigAlgoSz % 2 != 0)
7766 return BUFFER_ERROR;
7767 if (suites->hashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
7768 WOLFSSL_MSG("TLSX SigAlgo list exceeds max, truncating");
7769 suites->hashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
7770 }
7771 XMEMCPY(suites->hashSigAlgo, input, suites->hashSigAlgoSz);
7772
7773 return TLSX_SignatureAlgorithms_MapPss(ssl, input, suites->hashSigAlgoSz);
7774}
7775
7776/* Sets a new SignatureAlgorithms extension into the extension list.
7777 *
7778 * extensions The list of extensions.
7779 * data The extensions specific data.
7780 * heap The heap used for allocation.
7781 * returns 0 on success, otherwise failure.
7782 */
7783static int TLSX_SetSignatureAlgorithms(TLSX** extensions, WOLFSSL* ssl,
7784 void* heap)
7785{
7786 SignatureAlgorithms* sa;
7787 int ret;
7788
7789 if (extensions == NULL)
7790 return BAD_FUNC_ARG;
7791
7792 /* Already present */
7793 if (TLSX_Find(*extensions, TLSX_SIGNATURE_ALGORITHMS) != NULL)
7794 return 0;
7795
7796 sa = TLSX_SignatureAlgorithms_New(ssl, 0, heap);
7797 if (sa == NULL)
7798 return MEMORY_ERROR;
7799
7800 ret = TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS, sa, heap);
7801 if (ret != 0)
7802 TLSX_SignatureAlgorithms_FreeAll(sa, heap);
7803 return ret;
7804}
7805
7806SignatureAlgorithms* TLSX_SignatureAlgorithms_New(WOLFSSL* ssl,
7807 word16 hashSigAlgoSz, void* heap)
7808{
7809 SignatureAlgorithms* sa;
7810 (void)heap;
7811
7812 sa = (SignatureAlgorithms*)XMALLOC(sizeof(*sa) + hashSigAlgoSz, heap,
7813 DYNAMIC_TYPE_TLSX);
7814 if (sa != NULL) {
7815 XMEMSET(sa, 0, sizeof(*sa) + hashSigAlgoSz);
7816 sa->ssl = ssl;
7817 sa->hashSigAlgoSz = hashSigAlgoSz;
7818 }
7819 return sa;
7820}
7821
7822void TLSX_SignatureAlgorithms_FreeAll(SignatureAlgorithms* sa,
7823 void* heap)
7824{
7825 XFREE(sa, heap, DYNAMIC_TYPE_TLSX);
7826 (void)heap;
7827}
7828
7829#define SA_GET_SIZE TLSX_SignatureAlgorithms_GetSize
7830#define SA_WRITE TLSX_SignatureAlgorithms_Write
7831#define SA_PARSE TLSX_SignatureAlgorithms_Parse
7832#define SA_FREE_ALL TLSX_SignatureAlgorithms_FreeAll
7833#endif
7834/******************************************************************************/
7835/* Signature Algorithms Certificate */
7836/******************************************************************************/
7837
7838#if defined(WOLFSSL_TLS13) && !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
7839/* Return the size of the SignatureAlgorithms extension's data.
7840 *
7841 * data Unused
7842 * returns the length of data that will be in the extension.
7843 */
7844static word16 TLSX_SignatureAlgorithmsCert_GetSize(void* data)
7845{
7846 WOLFSSL* ssl = (WOLFSSL*)data;
7847
7848 return OPAQUE16_LEN + ssl->certHashSigAlgoSz;
7849}
7850
7851/* Writes the SignatureAlgorithmsCert extension into the buffer.
7852 *
7853 * data Unused
7854 * output The buffer to write the extension into.
7855 * returns the length of data that was written.
7856 */
7857static word16 TLSX_SignatureAlgorithmsCert_Write(void* data, byte* output)
7858{
7859 WOLFSSL* ssl = (WOLFSSL*)data;
7860
7861 c16toa(ssl->certHashSigAlgoSz, output);
7862 XMEMCPY(output + OPAQUE16_LEN, ssl->certHashSigAlgo,
7863 ssl->certHashSigAlgoSz);
7864
7865 return OPAQUE16_LEN + ssl->certHashSigAlgoSz;
7866}
7867
7868/* Parse the SignatureAlgorithmsCert extension.
7869 *
7870 * ssl The SSL/TLS object.
7871 * input The buffer with the extension data.
7872 * length The length of the extension data.
7873 * returns 0 on success, otherwise failure.
7874 */
7875static int TLSX_SignatureAlgorithmsCert_Parse(WOLFSSL *ssl, const byte* input,
7876 word16 length, byte isRequest)
7877{
7878 word16 len;
7879
7880 if (!isRequest)
7881 return BUFFER_ERROR;
7882
7883 /* Must contain a length and at least algorithm. */
7884 if (length < OPAQUE16_LEN + OPAQUE16_LEN || (length & 1) != 0)
7885 return BUFFER_ERROR;
7886
7887 ato16(input, &len);
7888 input += OPAQUE16_LEN;
7889
7890 /* Algorithm array must fill rest of data. */
7891 if (length != OPAQUE16_LEN + len)
7892 return BUFFER_ERROR;
7893
7894 /* truncate hashSigAlgo list if too long */
7895 ssl->certHashSigAlgoSz = len;
7896 if (ssl->certHashSigAlgoSz > WOLFSSL_MAX_SIGALGO) {
7897 WOLFSSL_MSG("TLSX SigAlgo list exceeds max, truncating");
7898 ssl->certHashSigAlgoSz = WOLFSSL_MAX_SIGALGO;
7899 }
7900 XMEMCPY(ssl->certHashSigAlgo, input, ssl->certHashSigAlgoSz);
7901
7902 return 0;
7903}
7904
7905/* Sets a new SignatureAlgorithmsCert extension into the extension list.
7906 *
7907 * extensions The list of extensions.
7908 * data The extensions specific data.
7909 * heap The heap used for allocation.
7910 * returns 0 on success, otherwise failure.
7911 */
7912static int TLSX_SetSignatureAlgorithmsCert(TLSX** extensions,
7913 const WOLFSSL* data, void* heap)
7914{
7915 if (extensions == NULL)
7916 return BAD_FUNC_ARG;
7917
7918 return TLSX_Push(extensions, TLSX_SIGNATURE_ALGORITHMS_CERT, data, heap);
7919}
7920
7921#define SAC_GET_SIZE TLSX_SignatureAlgorithmsCert_GetSize
7922#define SAC_WRITE TLSX_SignatureAlgorithmsCert_Write
7923#define SAC_PARSE TLSX_SignatureAlgorithmsCert_Parse
7924#endif /* WOLFSSL_TLS13 */
7925
7926
7927/******************************************************************************/
7928/* Key Share */
7929/******************************************************************************/
7930
7931#ifndef MAX_KEYSHARE_NAMED_GROUPS
7932 #if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_MAKE_KEY)
7933 #define MAX_KEYSHARE_NAMED_GROUPS 24
7934 #else
7935 #define MAX_KEYSHARE_NAMED_GROUPS 12
7936 #endif
7937#endif
7938
7939#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
7940/* Create a key share entry using named Diffie-Hellman parameters group.
7941 * Generates a key pair.
7942 *
7943 * ssl The SSL/TLS object.
7944 * kse The key share entry object.
7945 * returns 0 on success, otherwise failure.
7946 */
7947static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
7948{
7949 int ret = 0;
7950#if !defined(NO_DH) && (!defined(NO_CERTS) || !defined(NO_PSK))
7951 word32 pSz = 0, pvtSz = 0;
7952 DhKey* dhKey = (DhKey*)kse->key;
7953
7954 /* Pick the parameters from the named group. */
7955#ifdef HAVE_PUBLIC_FFDHE
7956 const DhParams* params = NULL;
7957 switch (kse->group) {
7958 #ifdef HAVE_FFDHE_2048
7959 case WOLFSSL_FFDHE_2048:
7960 params = wc_Dh_ffdhe2048_Get();
7961 pvtSz = 29;
7962 break;
7963 #endif
7964 #ifdef HAVE_FFDHE_3072
7965 case WOLFSSL_FFDHE_3072:
7966 params = wc_Dh_ffdhe3072_Get();
7967 pvtSz = 34;
7968 break;
7969 #endif
7970 #ifdef HAVE_FFDHE_4096
7971 case WOLFSSL_FFDHE_4096:
7972 params = wc_Dh_ffdhe4096_Get();
7973 pvtSz = 39;
7974 break;
7975 #endif
7976 #ifdef HAVE_FFDHE_6144
7977 case WOLFSSL_FFDHE_6144:
7978 params = wc_Dh_ffdhe6144_Get();
7979 pvtSz = 46;
7980 break;
7981 #endif
7982 #ifdef HAVE_FFDHE_8192
7983 case WOLFSSL_FFDHE_8192:
7984 params = wc_Dh_ffdhe8192_Get();
7985 pvtSz = 52;
7986 break;
7987 #endif
7988 default:
7989 break;
7990 }
7991 if (params == NULL)
7992 return BAD_FUNC_ARG;
7993 pSz = params->p_len;
7994#else
7995 pvtSz = wc_DhGetNamedKeyMinSize(kse->group);
7996 if (pvtSz == 0) {
7997 return BAD_FUNC_ARG;
7998 }
7999 ret = wc_DhGetNamedKeyParamSize(kse->group, &pSz, NULL, NULL);
8000 if (ret != 0) {
8001 return BAD_FUNC_ARG;
8002 }
8003#endif
8004
8005 /* Trigger Key Generation */
8006 if (kse->pubKey == NULL || kse->privKey == NULL) {
8007 if (kse->key == NULL) {
8008 kse->key = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap,
8009 DYNAMIC_TYPE_DH);
8010 if (kse->key == NULL)
8011 return MEMORY_E;
8012
8013 /* Setup Key */
8014 ret = wc_InitDhKey_ex((DhKey*)kse->key, ssl->heap, ssl->devId);
8015 if (ret == 0) {
8016 dhKey = (DhKey*)kse->key;
8017 #ifdef HAVE_PUBLIC_FFDHE
8018 ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g,
8019 params->g_len);
8020 #else
8021 ret = wc_DhSetNamedKey(dhKey, kse->group);
8022 #endif
8023 }
8024 #if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8025 defined(WC_ASYNC_ENABLE_DH)
8026 /* Only set non-blocking context when async device is active. With
8027 * INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
8028 * skip non-blocking setup and use blocking mode instead. */
8029 if (ret == 0 && ssl->devId != INVALID_DEVID) {
8030 DhNb* dhNb = (DhNb*)XMALLOC(sizeof(DhNb), ssl->heap,
8031 DYNAMIC_TYPE_TMP_BUFFER);
8032 if (dhNb == NULL) {
8033 ret = MEMORY_E;
8034 }
8035 else {
8036 ret = wc_DhSetNonBlock((DhKey*)kse->key, dhNb);
8037 if (ret != 0) {
8038 XFREE(dhNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8039 }
8040 }
8041 }
8042 #endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
8043 WC_ASYNC_ENABLE_DH */
8044 }
8045
8046 /* Allocate space for the private and public key */
8047 if (ret == 0 && kse->pubKey == NULL) {
8048 kse->pubKey = (byte*)XMALLOC(pSz, ssl->heap,
8049 DYNAMIC_TYPE_PUBLIC_KEY);
8050 if (kse->pubKey == NULL)
8051 ret = MEMORY_E;
8052 }
8053
8054 if (ret == 0 && kse->privKey == NULL) {
8055 kse->privKey = (byte*)XMALLOC(pvtSz, ssl->heap,
8056 DYNAMIC_TYPE_PRIVATE_KEY);
8057 if (kse->privKey == NULL)
8058 ret = MEMORY_E;
8059 }
8060
8061 if (ret == 0) {
8062 #if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA)
8063 ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_DH, kse->key);
8064 kse->pubKeyLen = pSz;
8065 kse->keyLen = pvtSz;
8066 if (ret == 0) {
8067 ret = wc_DhExportKeyPair(dhKey,
8068 (byte*)kse->privKey, &kse->keyLen, /* private */
8069 kse->pubKey, &kse->pubKeyLen /* public */
8070 );
8071 }
8072 else
8073 #endif
8074 {
8075 /* Generate a new key pair */
8076 /* For async this is called once and when event is done, the
8077 * provided buffers will be populated.
8078 * Final processing is zero pad below. */
8079 kse->pubKeyLen = pSz;
8080 kse->keyLen = pvtSz;
8081 ret = DhGenKeyPair(ssl, dhKey,
8082 (byte*)kse->privKey, &kse->keyLen, /* private */
8083 kse->pubKey, &kse->pubKeyLen /* public */
8084 );
8085 #ifdef WOLFSSL_ASYNC_CRYPT
8086 if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
8087 return ret;
8088 }
8089 #endif
8090 }
8091 }
8092 }
8093
8094 if (ret == 0) {
8095 if (pSz != kse->pubKeyLen) {
8096 /* Zero pad the front of the public key to match prime "p" size */
8097 XMEMMOVE(kse->pubKey + pSz - kse->pubKeyLen, kse->pubKey,
8098 kse->pubKeyLen);
8099 XMEMSET(kse->pubKey, 0, pSz - kse->pubKeyLen);
8100 kse->pubKeyLen = pSz;
8101 }
8102
8103 if (pvtSz != kse->keyLen) {
8104 /* Zero pad the front of the private key */
8105 XMEMMOVE(kse->privKey + pvtSz - kse->keyLen, kse->privKey,
8106 kse->keyLen);
8107 XMEMSET(kse->privKey, 0, pvtSz - kse->keyLen);
8108 kse->keyLen = pvtSz;
8109 }
8110
8111 #ifdef WOLFSSL_DEBUG_TLS
8112 WOLFSSL_MSG("Public DH Key");
8113 WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen);
8114 #endif
8115 }
8116
8117 /* Always release the DH key to free up memory.
8118 * The DhKey will be setup again in TLSX_KeyShare_ProcessDh */
8119 if (dhKey != NULL) {
8120 #if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8121 defined(WC_ASYNC_ENABLE_DH)
8122 if (dhKey->nb != NULL) {
8123 XFREE(dhKey->nb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8124 dhKey->nb = NULL;
8125 }
8126 #endif
8127 wc_FreeDhKey(dhKey);
8128 }
8129 XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_DH);
8130 kse->key = NULL;
8131
8132 if (ret != 0) {
8133 /* Cleanup on error, otherwise data owned by key share entry */
8134 if (kse->privKey) {
8135 ForceZero(kse->privKey, pvtSz);
8136 XFREE(kse->privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
8137 kse->privKey = NULL;
8138 }
8139 XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
8140 kse->pubKey = NULL;
8141 }
8142#else
8143 (void)ssl;
8144 (void)kse;
8145
8146 ret = NOT_COMPILED_IN;
8147 WOLFSSL_ERROR_VERBOSE(ret);
8148#endif
8149
8150 return ret;
8151}
8152
8153/* Create a key share entry using X25519 parameters group.
8154 * Generates a key pair.
8155 *
8156 * ssl The SSL/TLS object.
8157 * kse The key share entry object.
8158 * returns 0 on success, otherwise failure.
8159 */
8160static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
8161{
8162 int ret = 0;
8163#ifdef HAVE_CURVE25519
8164 curve25519_key* key = (curve25519_key*)kse->key;
8165
8166 if (kse->key == NULL) {
8167 /* Allocate a Curve25519 key to hold private key. */
8168 kse->key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap,
8169 DYNAMIC_TYPE_PRIVATE_KEY);
8170 if (kse->key == NULL) {
8171 WOLFSSL_MSG("GenX25519Key memory error");
8172 return MEMORY_E;
8173 }
8174
8175 /* Make an Curve25519 key. */
8176 ret = wc_curve25519_init_ex((curve25519_key*)kse->key, ssl->heap,
8177 ssl->devId);
8178 if (ret == 0) {
8179 /* setting "key" means okay to call wc_curve25519_free */
8180 key = (curve25519_key*)kse->key;
8181 kse->keyLen = CURVE25519_KEYSIZE;
8182 }
8183 #if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8184 defined(WC_ASYNC_ENABLE_X25519)
8185 /* Only set non-blocking context when async device is active. With
8186 * INVALID_DEVID there is no async loop to retry on FP_WOULDBLOCK, so
8187 * skip non-blocking setup and use blocking mode instead. */
8188 if (ret == 0 && ssl->devId != INVALID_DEVID) {
8189 x25519_nb_ctx_t* nb_ctx = (x25519_nb_ctx_t*)XMALLOC(
8190 sizeof(x25519_nb_ctx_t), ssl->heap,
8191 DYNAMIC_TYPE_TMP_BUFFER);
8192 if (nb_ctx == NULL) {
8193 ret = MEMORY_E;
8194 }
8195 else {
8196 ret = wc_curve25519_set_nonblock(key, nb_ctx);
8197 if (ret != 0) {
8198 XFREE(nb_ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8199 }
8200 }
8201 }
8202 #endif /* WC_X25519_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
8203 WC_ASYNC_ENABLE_X25519 */
8204 if (ret == 0) {
8205 #ifdef WOLFSSL_STATIC_EPHEMERAL
8206 ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE25519, kse->key);
8207 if (ret != 0) /* on failure, fallback to local key generation */
8208 #endif
8209 {
8210 #ifdef WOLFSSL_ASYNC_CRYPT
8211 /* initialize event */
8212 ret = wolfSSL_AsyncInit(ssl, &key->asyncDev,
8213 WC_ASYNC_FLAG_NONE);
8214 if (ret != 0)
8215 return ret;
8216 #endif
8217 ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
8218
8219 /* Handle async pending response */
8220 #ifdef WOLFSSL_ASYNC_CRYPT
8221 if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
8222 return wolfSSL_AsyncPush(ssl, &key->asyncDev);
8223 }
8224 #endif /* WOLFSSL_ASYNC_CRYPT */
8225 }
8226 }
8227 }
8228
8229 if (ret == 0 && kse->pubKey == NULL) {
8230 /* Allocate space for the public key. */
8231 kse->pubKey = (byte*)XMALLOC(CURVE25519_KEYSIZE, ssl->heap,
8232 DYNAMIC_TYPE_PUBLIC_KEY);
8233 if (kse->pubKey == NULL) {
8234 WOLFSSL_MSG("GenX25519Key pub memory error");
8235 ret = MEMORY_E;
8236 }
8237 }
8238
8239 if (ret == 0) {
8240 /* Export Curve25519 public key. */
8241 kse->pubKeyLen = CURVE25519_KEYSIZE;
8242 if (wc_curve25519_export_public_ex(key, kse->pubKey, &kse->pubKeyLen,
8243 EC25519_LITTLE_ENDIAN) != 0) {
8244 ret = ECC_EXPORT_ERROR;
8245 WOLFSSL_ERROR_VERBOSE(ret);
8246 }
8247 kse->pubKeyLen = CURVE25519_KEYSIZE; /* always CURVE25519_KEYSIZE */
8248 }
8249
8250#ifdef WOLFSSL_DEBUG_TLS
8251 if (ret == 0) {
8252 WOLFSSL_MSG("Public Curve25519 Key");
8253 WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen);
8254 }
8255#endif
8256
8257 if (ret != 0) {
8258 /* Data owned by key share entry otherwise. */
8259 XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
8260 kse->pubKey = NULL;
8261 if (key != NULL) {
8262 #if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW)
8263 if (key->nb_ctx != NULL) {
8264 XFREE(key->nb_ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8265 }
8266 #endif
8267 wc_curve25519_free(key);
8268 }
8269 XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
8270 kse->key = NULL;
8271 }
8272#else
8273 (void)ssl;
8274 (void)kse;
8275
8276 ret = NOT_COMPILED_IN;
8277 WOLFSSL_ERROR_VERBOSE(ret);
8278#endif /* HAVE_CURVE25519 */
8279
8280 return ret;
8281}
8282
8283/* Create a key share entry using X448 parameters group.
8284 * Generates a key pair.
8285 *
8286 * ssl The SSL/TLS object.
8287 * kse The key share entry object.
8288 * returns 0 on success, otherwise failure.
8289 */
8290static int TLSX_KeyShare_GenX448Key(WOLFSSL *ssl, KeyShareEntry* kse)
8291{
8292 int ret = 0;
8293#ifdef HAVE_CURVE448
8294 curve448_key* key = (curve448_key*)kse->key;
8295
8296 if (kse->key == NULL) {
8297 /* Allocate a Curve448 key to hold private key. */
8298 kse->key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap,
8299 DYNAMIC_TYPE_PRIVATE_KEY);
8300 if (kse->key == NULL) {
8301 WOLFSSL_MSG("GenX448Key memory error");
8302 return MEMORY_E;
8303 }
8304
8305 /* Make an Curve448 key. */
8306 ret = wc_curve448_init((curve448_key*)kse->key);
8307 if (ret == 0) {
8308 key = (curve448_key*)kse->key;
8309 kse->keyLen = CURVE448_KEY_SIZE;
8310
8311 #ifdef WOLFSSL_STATIC_EPHEMERAL
8312 ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE448, kse->key);
8313 if (ret != 0)
8314 #endif
8315 {
8316 ret = wc_curve448_make_key(ssl->rng, CURVE448_KEY_SIZE, key);
8317 }
8318 }
8319 }
8320
8321 if (ret == 0 && kse->pubKey == NULL) {
8322 /* Allocate space for the public key. */
8323 kse->pubKey = (byte*)XMALLOC(CURVE448_KEY_SIZE, ssl->heap,
8324 DYNAMIC_TYPE_PUBLIC_KEY);
8325 if (kse->pubKey == NULL) {
8326 WOLFSSL_MSG("GenX448Key pub memory error");
8327 ret = MEMORY_E;
8328 }
8329 }
8330
8331 if (ret == 0) {
8332 /* Export Curve448 public key. */
8333 kse->pubKeyLen = CURVE448_KEY_SIZE;
8334 if (wc_curve448_export_public_ex(key, kse->pubKey, &kse->pubKeyLen,
8335 EC448_LITTLE_ENDIAN) != 0) {
8336 ret = ECC_EXPORT_ERROR;
8337 }
8338 kse->pubKeyLen = CURVE448_KEY_SIZE; /* always CURVE448_KEY_SIZE */
8339 }
8340
8341#ifdef WOLFSSL_DEBUG_TLS
8342 if (ret == 0) {
8343 WOLFSSL_MSG("Public Curve448 Key");
8344 WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen);
8345 }
8346#endif
8347
8348 if (ret != 0) {
8349 /* Data owned by key share entry otherwise. */
8350 XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
8351 kse->pubKey = NULL;
8352 if (key != NULL)
8353 wc_curve448_free(key);
8354 XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
8355 kse->key = NULL;
8356 }
8357#else
8358 (void)ssl;
8359 (void)kse;
8360
8361 ret = NOT_COMPILED_IN;
8362 WOLFSSL_ERROR_VERBOSE(ret);
8363#endif /* HAVE_CURVE448 */
8364
8365 return ret;
8366}
8367
8368/* Create a key share entry using named elliptic curve parameters group.
8369 * Generates a key pair.
8370 *
8371 * ssl The SSL/TLS object.
8372 * kse The key share entry object.
8373 * returns 0 on success, otherwise failure.
8374 */
8375static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
8376{
8377 int ret = 0;
8378#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
8379 word32 keySize = 0;
8380 word16 curveId = (word16) ECC_CURVE_INVALID;
8381 ecc_key* eccKey = (ecc_key*)kse->key;
8382
8383 /* Translate named group to a curve id. */
8384 switch (kse->group) {
8385 #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
8386 #ifndef NO_ECC_SECP
8387 case WOLFSSL_ECC_SECP256R1:
8388 curveId = ECC_SECP256R1;
8389 break;
8390 #endif /* !NO_ECC_SECP */
8391 #ifdef WOLFSSL_SM2
8392 case WOLFSSL_ECC_SM2P256V1:
8393 curveId = ECC_SM2P256V1;
8394 break;
8395 #endif /* !WOLFSSL_SM2 */
8396 #ifdef HAVE_ECC_BRAINPOOL
8397 case WOLFSSL_ECC_BRAINPOOLP256R1TLS13:
8398 curveId = ECC_BRAINPOOLP256R1;
8399 break;
8400 #endif /* HAVE_ECC_BRAINPOOL */
8401 #endif
8402 #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
8403 #ifndef NO_ECC_SECP
8404 case WOLFSSL_ECC_SECP384R1:
8405 curveId = ECC_SECP384R1;
8406 break;
8407 #endif /* !NO_ECC_SECP */
8408 #ifdef HAVE_ECC_BRAINPOOL
8409 case WOLFSSL_ECC_BRAINPOOLP384R1TLS13:
8410 curveId = ECC_BRAINPOOLP384R1;
8411 break;
8412 #endif /* HAVE_ECC_BRAINPOOL */
8413 #endif
8414 #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
8415 #ifdef HAVE_ECC_BRAINPOOL
8416 case WOLFSSL_ECC_BRAINPOOLP512R1TLS13:
8417 curveId = ECC_BRAINPOOLP512R1;
8418 break;
8419 #endif /* HAVE_ECC_BRAINPOOL */
8420 #endif
8421 #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
8422 #ifndef NO_ECC_SECP
8423 case WOLFSSL_ECC_SECP521R1:
8424 curveId = ECC_SECP521R1;
8425 break;
8426 #endif /* !NO_ECC_SECP */
8427 #endif
8428 default:
8429 WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
8430 return BAD_FUNC_ARG;
8431 }
8432
8433 {
8434 int size = wc_ecc_get_curve_size_from_id(curveId);
8435 if (size < 0) {
8436 WOLFSSL_ERROR_VERBOSE(size);
8437 return size;
8438 }
8439 keySize = (word32)size;
8440 }
8441
8442 if (kse->key == NULL) {
8443 /* Allocate an ECC key to hold private key. */
8444 kse->key = (byte*)XMALLOC(sizeof(ecc_key), ssl->heap, DYNAMIC_TYPE_ECC);
8445 if (kse->key == NULL) {
8446 WOLFSSL_MSG_EX("Failed to allocate %d bytes, ssl->heap: %p",
8447 (int)sizeof(ecc_key), (wc_ptr_t)ssl->heap);
8448 WOLFSSL_MSG("EccTempKey Memory error!");
8449 return MEMORY_E;
8450 }
8451
8452 /* Initialize an ECC key struct for the ephemeral key */
8453 ret = wc_ecc_init_ex((ecc_key*)kse->key, ssl->heap, ssl->devId);
8454
8455 #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8456 defined(WC_ASYNC_ENABLE_ECC)
8457 /* Only set non-blocking context when async device is active. With
8458 * INVALID_DEVID there is no async loop to retry on FP_WOULDBLOCK, so
8459 * skip non-blocking setup and use blocking mode instead. */
8460 if (ret == 0 && ssl->devId != INVALID_DEVID) {
8461 ecc_nb_ctx_t* eccNbCtx = (ecc_nb_ctx_t*)XMALLOC(
8462 sizeof(ecc_nb_ctx_t), ssl->heap,
8463 DYNAMIC_TYPE_TMP_BUFFER);
8464 if (eccNbCtx == NULL) {
8465 ret = MEMORY_E;
8466 }
8467 else {
8468 ret = wc_ecc_set_nonblock((ecc_key*)kse->key, eccNbCtx);
8469 if (ret != 0) {
8470 XFREE(eccNbCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8471 }
8472 }
8473 }
8474 #endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
8475 WC_ASYNC_ENABLE_ECC */
8476
8477 if (ret == 0) {
8478 kse->keyLen = keySize;
8479 kse->pubKeyLen = keySize * 2 + 1;
8480
8481 #if defined(WOLFSSL_RENESAS_TSIP_TLS)
8482 ret = tsip_Tls13GenEccKeyPair(ssl, kse);
8483 if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
8484 return ret;
8485 }
8486 #endif
8487 /* setting eccKey means okay to call wc_ecc_free */
8488 eccKey = (ecc_key*)kse->key;
8489
8490 #ifdef WOLFSSL_STATIC_EPHEMERAL
8491 ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_ECDH, kse->key);
8492 if (ret != 0 || eccKey->dp->id != curveId)
8493 #endif
8494 {
8495 /* set curve info for EccMakeKey "peer" info */
8496 ret = wc_ecc_set_curve(eccKey, (int)kse->keyLen, curveId);
8497 if (ret == 0) {
8498 #ifdef WOLFSSL_ASYNC_CRYPT
8499 /* Detect when private key generation is done */
8500 if (ssl->error == WC_NO_ERR_TRACE(WC_PENDING_E) &&
8501 eccKey->type == ECC_PRIVATEKEY) {
8502 ret = 0; /* ECC Key Generation is done */
8503 }
8504 else
8505 #endif
8506 {
8507 /* Generate ephemeral ECC key */
8508 /* For async this is called once and when event is done, the
8509 * provided buffers in key be populated.
8510 * Final processing is x963 key export below. */
8511 ret = EccMakeKey(ssl, eccKey, eccKey);
8512 }
8513 }
8514 #ifdef WOLFSSL_ASYNC_CRYPT
8515 if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
8516 return ret;
8517 #endif
8518 }
8519 }
8520 }
8521
8522 if (ret == 0 && kse->pubKey == NULL) {
8523 /* Allocate space for the public key */
8524 kse->pubKey = (byte*)XMALLOC(kse->pubKeyLen, ssl->heap,
8525 DYNAMIC_TYPE_PUBLIC_KEY);
8526 if (kse->pubKey == NULL) {
8527 WOLFSSL_MSG("Key data Memory error");
8528 ret = MEMORY_E;
8529 }
8530 }
8531
8532 if (ret == 0) {
8533 XMEMSET(kse->pubKey, 0, kse->pubKeyLen);
8534
8535 /* Export public key. */
8536 PRIVATE_KEY_UNLOCK();
8537 if (wc_ecc_export_x963(eccKey, kse->pubKey, &kse->pubKeyLen) != 0) {
8538 ret = ECC_EXPORT_ERROR;
8539 WOLFSSL_ERROR_VERBOSE(ret);
8540 }
8541 PRIVATE_KEY_LOCK();
8542 }
8543#ifdef WOLFSSL_DEBUG_TLS
8544 if (ret == 0) {
8545 WOLFSSL_MSG("Public ECC Key");
8546 WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen);
8547 }
8548#endif
8549
8550 if (ret != 0) {
8551 /* Cleanup on error, otherwise data owned by key share entry */
8552 XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
8553 kse->pubKey = NULL;
8554 if (eccKey != NULL) {
8555 #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
8556 defined(WC_ASYNC_ENABLE_ECC)
8557 if (eccKey->nb_ctx != NULL) {
8558 XFREE(eccKey->nb_ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
8559 }
8560 #endif
8561 wc_ecc_free(eccKey);
8562 }
8563 XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
8564 kse->key = NULL;
8565 }
8566#else
8567 (void)ssl;
8568 (void)kse;
8569
8570 ret = NOT_COMPILED_IN;
8571 WOLFSSL_ERROR_VERBOSE(ret);
8572#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
8573
8574 return ret;
8575}
8576
8577#ifdef WOLFSSL_HAVE_MLKEM
8578#if (defined(WOLFSSL_MLKEM_CACHE_A) || \
8579 (defined(HAVE_PKCS11) && !defined(NO_PKCS11_MLKEM))) && \
8580 !defined(WOLFSSL_TLSX_PQC_MLKEM_STORE_PRIV_KEY)
8581 /* Store KyberKey object rather than private key bytes in key share entry.
8582 * Improves performance at cost of more dynamic memory being used. */
8583 #define WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
8584#endif
8585#if defined(WOLFSSL_TLSX_PQC_MLKEM_STORE_PRIV_KEY) && \
8586 defined(WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ)
8587 #error "Choose WOLFSSL_TLSX_PQC_MLKEM_STORE_PRIV_KEY or "
8588 "WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ"
8589#endif
8590
8591#if !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) || \
8592 !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \
8593 (!defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \
8594 !defined(WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ))
8595static int mlkem_id2type(int id, int *type)
8596{
8597 int ret = 0;
8598
8599 switch (id) {
8600#ifndef WOLFSSL_NO_ML_KEM
8601 #ifndef WOLFSSL_NO_ML_KEM_512
8602 case WOLFSSL_ML_KEM_512:
8603 *type = WC_ML_KEM_512;
8604 break;
8605 #endif
8606 #ifndef WOLFSSL_NO_ML_KEM_768
8607 case WOLFSSL_ML_KEM_768:
8608 *type = WC_ML_KEM_768;
8609 break;
8610 #endif
8611 #ifndef WOLFSSL_NO_ML_KEM_1024
8612 case WOLFSSL_ML_KEM_1024:
8613 *type = WC_ML_KEM_1024;
8614 break;
8615 #endif
8616#endif
8617#ifdef WOLFSSL_MLKEM_KYBER
8618 #ifdef WOLFSSL_KYBER512
8619 case WOLFSSL_KYBER_LEVEL1:
8620 *type = KYBER512;
8621 break;
8622 #endif
8623 #ifdef WOLFSSL_KYBER768
8624 case WOLFSSL_KYBER_LEVEL3:
8625 *type = KYBER768;
8626 break;
8627 #endif
8628 #ifdef WOLFSSL_KYBER1024
8629 case WOLFSSL_KYBER_LEVEL5:
8630 *type = KYBER1024;
8631 break;
8632 #endif
8633#endif
8634 default:
8635 ret = NOT_COMPILED_IN;
8636 break;
8637 }
8638
8639 return ret;
8640}
8641#endif
8642
8643#if defined(WOLFSSL_NO_ML_KEM_768) && defined(WOLFSSL_NO_ML_KEM_1024) && \
8644 defined(WOLFSSL_PQC_HYBRIDS)
8645 #error "PQC hybrid combinations require either ML-KEM 768 or ML-KEM 1024"
8646#endif
8647
8648/* Structures and objects needed for hybrid key exchanges using both classic
8649 * ECDHE and PQC KEM key material. */
8650typedef struct PqcHybridMapping {
8651 int hybrid;
8652 int ecc;
8653 int pqc;
8654 int pqc_first;
8655} PqcHybridMapping;
8656
8657static const PqcHybridMapping pqc_hybrid_mapping[] = {
8658#ifndef WOLFSSL_NO_ML_KEM
8659#ifdef WOLFSSL_PQC_HYBRIDS
8660 {WOLFSSL_SECP256R1MLKEM768, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_768, 0},
8661 {WOLFSSL_SECP384R1MLKEM1024, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_1024, 0},
8662#endif /* WOLFSSL_PQC_HYBRIDS */
8663#ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
8664 {WOLFSSL_SECP256R1MLKEM512, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_512, 0},
8665 {WOLFSSL_SECP384R1MLKEM768, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_768, 0},
8666 {WOLFSSL_SECP521R1MLKEM1024, WOLFSSL_ECC_SECP521R1, WOLFSSL_ML_KEM_1024, 0},
8667#ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
8668 {WOLFSSL_P256_ML_KEM_512_OLD, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_512, 0},
8669 {WOLFSSL_P384_ML_KEM_768_OLD, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_768, 0},
8670 {WOLFSSL_P521_ML_KEM_1024_OLD, WOLFSSL_ECC_SECP521R1, WOLFSSL_ML_KEM_1024, 0},
8671#endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
8672#endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
8673#ifdef HAVE_CURVE25519
8674#ifdef WOLFSSL_PQC_HYBRIDS
8675 {WOLFSSL_X25519MLKEM768, WOLFSSL_ECC_X25519, WOLFSSL_ML_KEM_768, 1},
8676#endif /* WOLFSSL_PQC_HYBRIDS */
8677#ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
8678 {WOLFSSL_X25519MLKEM512, WOLFSSL_ECC_X25519, WOLFSSL_ML_KEM_512, 1},
8679#endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
8680#endif /* HAVE_CURVE25519 */
8681#ifdef HAVE_CURVE448
8682#ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
8683 {WOLFSSL_X448MLKEM768, WOLFSSL_ECC_X448, WOLFSSL_ML_KEM_768, 1},
8684#endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
8685#endif /* HAVE_CURVE448 */
8686#endif /* WOLFSSL_NO_ML_KEM */
8687#ifdef WOLFSSL_MLKEM_KYBER
8688 {WOLFSSL_P256_KYBER_LEVEL1, WOLFSSL_ECC_SECP256R1, WOLFSSL_KYBER_LEVEL1, 0},
8689 {WOLFSSL_P384_KYBER_LEVEL3, WOLFSSL_ECC_SECP384R1, WOLFSSL_KYBER_LEVEL3, 0},
8690 {WOLFSSL_P256_KYBER_LEVEL3, WOLFSSL_ECC_SECP256R1, WOLFSSL_KYBER_LEVEL3, 0},
8691 {WOLFSSL_P521_KYBER_LEVEL5, WOLFSSL_ECC_SECP521R1, WOLFSSL_KYBER_LEVEL5, 0},
8692#ifdef HAVE_CURVE25519
8693 {WOLFSSL_X25519_KYBER_LEVEL1, WOLFSSL_ECC_X25519, WOLFSSL_KYBER_LEVEL1, 0},
8694 {WOLFSSL_X25519_KYBER_LEVEL3, WOLFSSL_ECC_X25519, WOLFSSL_KYBER_LEVEL3, 0},
8695#endif
8696#ifdef HAVE_CURVE448
8697 {WOLFSSL_X448_KYBER_LEVEL3, WOLFSSL_ECC_X448, WOLFSSL_KYBER_LEVEL3, 0},
8698#endif
8699#endif /* WOLFSSL_MLKEM_KYBER */
8700 {0, 0, 0, 0}
8701};
8702
8703/* Map an ecc-pqc hybrid group into its ecc group and pqc kem group. */
8704static void findEccPqc(int *ecc, int *pqc, int *pqc_first, int group)
8705{
8706 int i;
8707
8708 if (pqc != NULL)
8709 *pqc = 0;
8710 if (ecc != NULL)
8711 *ecc = 0;
8712 if (pqc_first != NULL)
8713 *pqc_first = 0;
8714
8715 for (i = 0; pqc_hybrid_mapping[i].hybrid != 0; i++) {
8716 if (pqc_hybrid_mapping[i].hybrid == group) {
8717 if (pqc != NULL)
8718 *pqc = pqc_hybrid_mapping[i].pqc;
8719 if (ecc != NULL)
8720 *ecc = pqc_hybrid_mapping[i].ecc;
8721 if (pqc_first != NULL)
8722 *pqc_first = pqc_hybrid_mapping[i].pqc_first;
8723 break;
8724 }
8725 }
8726}
8727
8728#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY
8729/* Create a key share entry using pqc parameters group on the client side.
8730 * Generates a key pair.
8731 *
8732 * ssl The SSL/TLS object.
8733 * kse The key share entry object.
8734 * returns 0 on success, otherwise failure.
8735 */
8736static int TLSX_KeyShare_GenPqcKeyClient(WOLFSSL *ssl, KeyShareEntry* kse)
8737{
8738 int ret = 0;
8739 int type = 0;
8740#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
8741 WC_DECLARE_VAR(kem, KyberKey, 1, 0);
8742 byte* privKey = NULL;
8743 word32 privSz = 0;
8744#else
8745 KyberKey* kem = NULL;
8746#endif
8747
8748 /* This gets called twice. Once during parsing of the key share and once
8749 * during the population of the extension. No need to do work the second
8750 * time. Just return success if its already been done. */
8751 if (kse->pubKey != NULL) {
8752 return ret;
8753 }
8754
8755 /* Get the type of key we need from the key share group. */
8756 ret = mlkem_id2type(kse->group, &type);
8757 if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
8758 WOLFSSL_MSG("Invalid Kyber algorithm specified.");
8759 ret = BAD_FUNC_ARG;
8760 }
8761
8762#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
8763
8764 #ifdef WOLFSSL_SMALL_STACK
8765 if (ret == 0) {
8766 kem = (KyberKey *)XMALLOC(sizeof(*kem), ssl->heap,
8767 DYNAMIC_TYPE_PRIVATE_KEY);
8768 if (kem == NULL) {
8769 WOLFSSL_MSG("KEM memory allocation failure");
8770 ret = MEMORY_ERROR;
8771 }
8772 }
8773 #endif /* WOLFSSL_SMALL_STACK */
8774
8775 if (ret == 0) {
8776 ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId);
8777 if (ret != 0) {
8778 WOLFSSL_MSG("Failed to initialize Kyber Key.");
8779 }
8780 }
8781
8782 if (ret == 0) {
8783 ret = wc_KyberKey_PrivateKeySize(kem, &privSz);
8784 }
8785 if (ret == 0) {
8786 ret = wc_KyberKey_PublicKeySize(kem, &kse->pubKeyLen);
8787 }
8788
8789 if (ret == 0) {
8790 privKey = (byte*)XMALLOC(privSz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
8791 if (privKey == NULL) {
8792 WOLFSSL_MSG("privkey memory allocation failure");
8793 ret = MEMORY_ERROR;
8794 }
8795 }
8796#else
8797 if (ret == 0) {
8798 /* Allocate a Kyber key to hold private key. */
8799 kem = (KyberKey*)XMALLOC(sizeof(KyberKey), ssl->heap,
8800 DYNAMIC_TYPE_PRIVATE_KEY);
8801 if (kem == NULL) {
8802 WOLFSSL_MSG("KEM memory allocation failure");
8803 ret = MEMORY_ERROR;
8804 }
8805 }
8806 if (ret == 0) {
8807 ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId);
8808 if (ret != 0) {
8809 WOLFSSL_MSG("Failed to initialize Kyber Key.");
8810 }
8811 }
8812 if (ret == 0) {
8813 ret = wc_KyberKey_PublicKeySize(kem, &kse->pubKeyLen);
8814 }
8815#endif
8816
8817 if (ret == 0) {
8818 kse->pubKey = (byte*)XMALLOC(kse->pubKeyLen, ssl->heap,
8819 DYNAMIC_TYPE_PUBLIC_KEY);
8820 if (kse->pubKey == NULL) {
8821 WOLFSSL_MSG("pubkey memory allocation failure");
8822 ret = MEMORY_ERROR;
8823 }
8824 }
8825
8826 if (ret == 0) {
8827 ret = wc_KyberKey_MakeKey(kem, ssl->rng);
8828 if (ret != 0) {
8829 WOLFSSL_MSG("Kyber keygen failure");
8830 }
8831 }
8832 if (ret == 0) {
8833 ret = wc_KyberKey_EncodePublicKey(kem, kse->pubKey,
8834 kse->pubKeyLen);
8835 }
8836
8837#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
8838 if (ret == 0) {
8839 PRIVATE_KEY_UNLOCK();
8840 ret = wc_KyberKey_EncodePrivateKey(kem, privKey, privSz);
8841 PRIVATE_KEY_LOCK();
8842 }
8843#endif
8844
8845#ifdef WOLFSSL_DEBUG_TLS
8846 WOLFSSL_MSG("Public Kyber Key");
8847 WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen );
8848#endif
8849
8850 if (ret != 0) {
8851 /* Data owned by key share entry otherwise. */
8852 wc_KyberKey_Free(kem);
8853 XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
8854 kse->pubKey = NULL;
8855 #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
8856 if (privKey) {
8857 ForceZero(privKey, privSz);
8858 XFREE(privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
8859 privKey = NULL;
8860 }
8861 #else
8862 XFREE(kem, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
8863 kse->key = NULL;
8864 #endif
8865 }
8866 else {
8867 #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
8868 wc_KyberKey_Free(kem);
8869 kse->privKey = (byte*)privKey;
8870 kse->privKeyLen = privSz;
8871 #else
8872 kse->key = kem;
8873 #endif
8874 }
8875
8876 #if !defined(WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ) && \
8877 defined(WOLFSSL_SMALL_STACK)
8878 XFREE(kem, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
8879 #endif
8880
8881 return ret;
8882}
8883
8884/* Create a key share entry using both ecdhe and pqc parameters groups.
8885 * Generates two key pairs on the client side.
8886 *
8887 * ssl The SSL/TLS object.
8888 * kse The key share entry object.
8889 * returns 0 on success, otherwise failure.
8890 */
8891static int TLSX_KeyShare_GenPqcHybridKeyClient(WOLFSSL *ssl, KeyShareEntry* kse)
8892{
8893 int ret = 0;
8894 KeyShareEntry *ecc_kse = NULL;
8895 KeyShareEntry *pqc_kse = NULL;
8896 int pqc_group = 0;
8897 int ecc_group = 0;
8898 int pqc_first = 0;
8899
8900 /* This gets called twice. Once during parsing of the key share and once
8901 * during the population of the extension. No need to do work the second
8902 * time. Just return success if its already been done. */
8903 if (kse->pubKey != NULL) {
8904 return ret;
8905 }
8906
8907 /* Determine the ECC and PQC group of the hybrid combination */
8908 findEccPqc(&ecc_group, &pqc_group, &pqc_first, kse->group);
8909 if (ecc_group == 0 || pqc_group == 0) {
8910 WOLFSSL_MSG("Invalid hybrid group");
8911 ret = BAD_FUNC_ARG;
8912 }
8913
8914 if (ret == 0) {
8915 ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap,
8916 DYNAMIC_TYPE_TLSX);
8917 if (ecc_kse == NULL) {
8918 WOLFSSL_MSG("kse memory allocation failure");
8919 ret = MEMORY_ERROR;
8920 }
8921 else {
8922 XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
8923 }
8924 }
8925 if (ret == 0) {
8926 pqc_kse = (KeyShareEntry*)XMALLOC(sizeof(*pqc_kse), ssl->heap,
8927 DYNAMIC_TYPE_TLSX);
8928 if (pqc_kse == NULL) {
8929 WOLFSSL_MSG("kse memory allocation failure");
8930 ret = MEMORY_ERROR;
8931 }
8932 else {
8933 XMEMSET(pqc_kse, 0, sizeof(*pqc_kse));
8934 }
8935 }
8936
8937 /* Generate ECC key share part */
8938 if (ret == 0) {
8939 ecc_kse->group = ecc_group;
8940
8941 #ifdef WOLFSSL_ASYNC_CRYPT
8942 /* Check if the provided kse already contains an ECC key and the
8943 * last error was WC_PENDING_E. In this case, we already tried to
8944 * generate an ECC key. Hence, we have to restore it. */
8945 if (kse->key != NULL && kse->keyLen > 0 &&
8946 kse->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E)) {
8947 ecc_kse->key = kse->key;
8948 ecc_kse->keyLen = kse->keyLen;
8949 ecc_kse->pubKeyLen = kse->pubKeyLen;
8950 ecc_kse->lastRet = kse->lastRet;
8951 kse->key = NULL;
8952 }
8953 #endif
8954
8955 #ifdef HAVE_CURVE25519
8956 if (ecc_group == WOLFSSL_ECC_X25519) {
8957 ret = TLSX_KeyShare_GenX25519Key(ssl, ecc_kse);
8958 }
8959 else
8960 #endif
8961 #ifdef HAVE_CURVE448
8962 if (ecc_group == WOLFSSL_ECC_X448) {
8963 ret = TLSX_KeyShare_GenX448Key(ssl, ecc_kse);
8964 }
8965 else
8966 #endif
8967 {
8968 ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
8969 }
8970
8971 #ifdef WOLFSSL_ASYNC_CRYPT
8972 if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
8973 /* Store the generated ECC key in the provided kse to later
8974 * restore it.*/
8975 kse->key = ecc_kse->key;
8976 kse->keyLen = ecc_kse->keyLen;
8977 kse->pubKeyLen = ecc_kse->pubKeyLen;
8978 ecc_kse->key = NULL;
8979 }
8980 #endif
8981 }
8982
8983 /* Generate PQC key share part */
8984 if (ret == 0) {
8985 pqc_kse->group = pqc_group;
8986 ret = TLSX_KeyShare_GenPqcKeyClient(ssl, pqc_kse);
8987 /* No error message, TLSX_KeyShare_GenPqcKeyClient will do it. */
8988 }
8989
8990 /* Allocate memory for combined public key */
8991 if (ret == 0) {
8992 kse->pubKey = (byte*)XMALLOC(ecc_kse->pubKeyLen + pqc_kse->pubKeyLen,
8993 ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
8994 if (kse->pubKey == NULL) {
8995 WOLFSSL_MSG("pubkey memory allocation failure");
8996 ret = MEMORY_ERROR;
8997 }
8998 }
8999
9000 /* Create combined public key. The order of classic/pqc key material is
9001 * indicated by the pqc_first variable. */
9002 if (ret == 0) {
9003 if (pqc_first) {
9004 XMEMCPY(kse->pubKey, pqc_kse->pubKey, pqc_kse->pubKeyLen);
9005 XMEMCPY(kse->pubKey + pqc_kse->pubKeyLen, ecc_kse->pubKey,
9006 ecc_kse->pubKeyLen);
9007 }
9008 else {
9009 XMEMCPY(kse->pubKey, ecc_kse->pubKey, ecc_kse->pubKeyLen);
9010 XMEMCPY(kse->pubKey + ecc_kse->pubKeyLen, pqc_kse->pubKey,
9011 pqc_kse->pubKeyLen);
9012 }
9013 kse->pubKeyLen = ecc_kse->pubKeyLen + pqc_kse->pubKeyLen;
9014 }
9015
9016 /* Store the private keys.
9017 * Note we are saving the PQC private key and ECC private key
9018 * separately. That's because the ECC private key is not simply a
9019 * buffer. Its is an ecc_key struct. */
9020 if (ret == 0) {
9021 #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
9022 /* PQC private key is an encoded byte array */
9023 kse->privKey = pqc_kse->privKey;
9024 kse->privKeyLen = pqc_kse->privKeyLen;
9025 pqc_kse->privKey = NULL;
9026 #else
9027 /* PQC private key is a pointer to KyberKey object */
9028 kse->privKey = (byte*)pqc_kse->key;
9029 kse->privKeyLen = 0;
9030 pqc_kse->key = NULL;
9031 #endif
9032 /* ECC private key is a pointer to ecc_key object */
9033 kse->key = ecc_kse->key;
9034 kse->keyLen = ecc_kse->keyLen;
9035 ecc_kse->key = NULL;
9036 }
9037
9038#ifdef WOLFSSL_DEBUG_TLS
9039 WOLFSSL_MSG("Public Kyber Key");
9040 WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen );
9041#endif
9042
9043 TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
9044 TLSX_KeyShare_FreeAll(pqc_kse, ssl->heap);
9045
9046 return ret;
9047}
9048#endif /* !WOLFSSL_MLKEM_NO_MAKE_KEY */
9049#endif /* WOLFSSL_HAVE_MLKEM */
9050
9051/* Generate a secret/key using the key share entry.
9052 *
9053 * ssl The SSL/TLS object.
9054 * kse The key share entry holding peer data.
9055 */
9056int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse)
9057{
9058 int ret;
9059 /* Named FFDHE groups have a bit set to identify them. */
9060 if (WOLFSSL_NAMED_GROUP_IS_FFDHE(kse->group))
9061 ret = TLSX_KeyShare_GenDhKey(ssl, kse);
9062 else if (kse->group == WOLFSSL_ECC_X25519)
9063 ret = TLSX_KeyShare_GenX25519Key(ssl, kse);
9064 else if (kse->group == WOLFSSL_ECC_X448)
9065 ret = TLSX_KeyShare_GenX448Key(ssl, kse);
9066#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_MAKE_KEY)
9067 else if (WOLFSSL_NAMED_GROUP_IS_PQC(kse->group))
9068 ret = TLSX_KeyShare_GenPqcKeyClient(ssl, kse);
9069 else if (WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(kse->group))
9070 ret = TLSX_KeyShare_GenPqcHybridKeyClient(ssl, kse);
9071#endif
9072 else
9073 ret = TLSX_KeyShare_GenEccKey(ssl, kse);
9074#ifdef WOLFSSL_ASYNC_CRYPT
9075 kse->lastRet = ret;
9076#endif
9077 return ret;
9078}
9079
9080/* Free the key share dynamic data.
9081 *
9082 * list The linked list of key share entry objects.
9083 * heap The heap used for allocation.
9084 */
9085static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
9086{
9087 KeyShareEntry* current;
9088
9089 while ((current = list) != NULL) {
9090 list = current->next;
9091 if (WOLFSSL_NAMED_GROUP_IS_FFDHE(current->group)) {
9092#ifndef NO_DH
9093 #if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
9094 defined(WC_ASYNC_ENABLE_DH)
9095 if (current->key != NULL &&
9096 ((DhKey*)current->key)->nb != NULL) {
9097 XFREE(((DhKey*)current->key)->nb, heap,
9098 DYNAMIC_TYPE_TMP_BUFFER);
9099 ((DhKey*)current->key)->nb = NULL;
9100 }
9101 #endif
9102 wc_FreeDhKey((DhKey*)current->key);
9103 if (current->privKey != NULL && current->privKeyLen > 0) {
9104 ForceZero(current->privKey, current->privKeyLen);
9105 }
9106#endif
9107 }
9108 else if (current->group == WOLFSSL_ECC_X25519) {
9109#ifdef HAVE_CURVE25519
9110 #if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW)
9111 if (current->key != NULL &&
9112 ((curve25519_key*)current->key)->nb_ctx != NULL) {
9113 XFREE(((curve25519_key*)current->key)->nb_ctx, heap,
9114 DYNAMIC_TYPE_TMP_BUFFER);
9115 }
9116 #endif
9117 wc_curve25519_free((curve25519_key*)current->key);
9118#endif
9119 }
9120 else if (current->group == WOLFSSL_ECC_X448) {
9121#ifdef HAVE_CURVE448
9122 wc_curve448_free((curve448_key*)current->key);
9123#endif
9124 }
9125 else if (WOLFSSL_NAMED_GROUP_IS_PQC(current->group)) {
9126#ifdef WOLFSSL_HAVE_MLKEM
9127 wc_KyberKey_Free((KyberKey*)current->key);
9128 #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
9129 if (current->privKey != NULL) {
9130 ForceZero(current->privKey, current->privKeyLen);
9131 }
9132 #endif
9133#endif
9134 }
9135 else if (WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(current->group)) {
9136#ifdef WOLFSSL_HAVE_MLKEM
9137 int ecc_group = 0;
9138 findEccPqc(&ecc_group, NULL, NULL, current->group);
9139
9140 /* Free PQC private key */
9141 #ifdef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
9142 wc_KyberKey_Free((KyberKey*)current->privKey);
9143 #else
9144 if (current->privKey != NULL) {
9145 ForceZero(current->privKey, current->privKeyLen);
9146 }
9147 #endif
9148
9149 /* Free ECC private key */
9150 if (ecc_group == WOLFSSL_ECC_X25519) {
9151 #ifdef HAVE_CURVE25519
9152 wc_curve25519_free((curve25519_key*)current->key);
9153 #endif
9154 }
9155 else if (ecc_group == WOLFSSL_ECC_X448) {
9156 #ifdef HAVE_CURVE448
9157 wc_curve448_free((curve448_key*)current->key);
9158 #endif
9159 }
9160 else {
9161 #ifdef HAVE_ECC
9162 #if defined(WC_ECC_NONBLOCK) && \
9163 defined(WOLFSSL_ASYNC_CRYPT_SW) && \
9164 defined(WC_ASYNC_ENABLE_ECC)
9165 if (current->key != NULL &&
9166 ((ecc_key*)current->key)->nb_ctx != NULL) {
9167 XFREE(((ecc_key*)current->key)->nb_ctx, heap,
9168 DYNAMIC_TYPE_TMP_BUFFER);
9169 }
9170 #endif
9171 wc_ecc_free((ecc_key*)current->key);
9172 #endif
9173 }
9174#endif
9175 }
9176 else {
9177#ifdef HAVE_ECC
9178 #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
9179 defined(WC_ASYNC_ENABLE_ECC)
9180 if (current->key != NULL &&
9181 ((ecc_key*)current->key)->nb_ctx != NULL) {
9182 XFREE(((ecc_key*)current->key)->nb_ctx, heap,
9183 DYNAMIC_TYPE_TMP_BUFFER);
9184 }
9185 #endif
9186 wc_ecc_free((ecc_key*)current->key);
9187#endif
9188 }
9189 XFREE(current->key, heap, DYNAMIC_TYPE_PRIVATE_KEY);
9190 #if !defined(NO_DH) || defined(WOLFSSL_HAVE_MLKEM)
9191 XFREE(current->privKey, heap, DYNAMIC_TYPE_PRIVATE_KEY);
9192 #endif
9193 XFREE(current->pubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
9194 XFREE(current->ke, heap, DYNAMIC_TYPE_PUBLIC_KEY);
9195 XFREE(current, heap, DYNAMIC_TYPE_TLSX);
9196 }
9197
9198 (void)heap;
9199}
9200
9201/* Get the size of the encoded key share extension.
9202 *
9203 * list The linked list of key share extensions.
9204 * msgType The type of the message this extension is being written into.
9205 * returns the number of bytes of the encoded key share extension.
9206 */
9207static word16 TLSX_KeyShare_GetSize(KeyShareEntry* list, byte msgType)
9208{
9209 word16 len = 0;
9210 byte isRequest = (msgType == client_hello);
9211 KeyShareEntry* current;
9212
9213 /* The named group the server wants to use. */
9214 if (msgType == hello_retry_request)
9215 return OPAQUE16_LEN;
9216
9217 /* List of key exchange groups. */
9218 if (isRequest)
9219 len += OPAQUE16_LEN;
9220 while ((current = list) != NULL) {
9221 list = current->next;
9222
9223 if (!isRequest && current->pubKey == NULL)
9224 continue;
9225
9226 len += (word16)(KE_GROUP_LEN + OPAQUE16_LEN + current->pubKeyLen);
9227 }
9228
9229 return len;
9230}
9231
9232/* Writes the key share extension into the output buffer.
9233 * Assumes that the the output buffer is big enough to hold data.
9234 *
9235 * list The linked list of key share entries.
9236 * output The buffer to write into.
9237 * msgType The type of the message this extension is being written into.
9238 * returns the number of bytes written into the buffer.
9239 */
9240static word16 TLSX_KeyShare_Write(KeyShareEntry* list, byte* output,
9241 byte msgType)
9242{
9243 word16 i = 0;
9244 byte isRequest = (msgType == client_hello);
9245 KeyShareEntry* current;
9246
9247 if (msgType == hello_retry_request) {
9248 c16toa(list->group, output);
9249 return OPAQUE16_LEN;
9250 }
9251
9252 /* ClientHello has a list but ServerHello is only the chosen. */
9253 if (isRequest)
9254 i += OPAQUE16_LEN;
9255
9256 /* Write out all in the list. */
9257 while ((current = list) != NULL) {
9258 list = current->next;
9259
9260 if (!isRequest && current->pubKey == NULL)
9261 continue;
9262
9263 c16toa(current->group, &output[i]);
9264 i += KE_GROUP_LEN;
9265 c16toa((word16)(current->pubKeyLen), &output[i]);
9266 i += OPAQUE16_LEN;
9267 XMEMCPY(&output[i], current->pubKey, current->pubKeyLen);
9268 i += (word16)current->pubKeyLen;
9269 }
9270 /* Write the length of the list if required. */
9271 if (isRequest)
9272 c16toa(i - OPAQUE16_LEN, output);
9273
9274 return i;
9275}
9276
9277/* Process the DH key share extension on the client side.
9278 *
9279 * ssl The SSL/TLS object.
9280 * keyShareEntry The key share entry object to use to calculate shared secret.
9281 * returns 0 on success and other values indicate failure.
9282 */
9283static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
9284{
9285 int ret = 0;
9286#if !defined(NO_DH) && (!defined(NO_CERTS) || !defined(NO_PSK))
9287 word32 pSz = 0;
9288 DhKey* dhKey = (DhKey*)keyShareEntry->key;
9289
9290#ifdef HAVE_PUBLIC_FFDHE
9291 const DhParams* params = NULL;
9292 switch (keyShareEntry->group) {
9293 #ifdef HAVE_FFDHE_2048
9294 case WOLFSSL_FFDHE_2048:
9295 params = wc_Dh_ffdhe2048_Get();
9296 break;
9297 #endif
9298 #ifdef HAVE_FFDHE_3072
9299 case WOLFSSL_FFDHE_3072:
9300 params = wc_Dh_ffdhe3072_Get();
9301 break;
9302 #endif
9303 #ifdef HAVE_FFDHE_4096
9304 case WOLFSSL_FFDHE_4096:
9305 params = wc_Dh_ffdhe4096_Get();
9306 break;
9307 #endif
9308 #ifdef HAVE_FFDHE_6144
9309 case WOLFSSL_FFDHE_6144:
9310 params = wc_Dh_ffdhe6144_Get();
9311 break;
9312 #endif
9313 #ifdef HAVE_FFDHE_8192
9314 case WOLFSSL_FFDHE_8192:
9315 params = wc_Dh_ffdhe8192_Get();
9316 break;
9317 #endif
9318 default:
9319 break;
9320 }
9321 if (params == NULL) {
9322 WOLFSSL_ERROR_VERBOSE(PEER_KEY_ERROR);
9323 return PEER_KEY_ERROR;
9324 }
9325 pSz = params->p_len;
9326#else
9327 ret = wc_DhGetNamedKeyParamSize(keyShareEntry->group, &pSz, NULL, NULL);
9328 if (ret != 0 || pSz == 0) {
9329 WOLFSSL_ERROR_VERBOSE(PEER_KEY_ERROR);
9330 return PEER_KEY_ERROR;
9331 }
9332#endif
9333
9334 /* RFC 8446 Section 4.2.8.1: FFDHE key_exchange values are left-padded with
9335 * zeros to the size of the named-group prime. Reject any peer key share
9336 * whose byte length does not match the expected prime size. */
9337 if (keyShareEntry->keLen != pSz) {
9338 WOLFSSL_ERROR_VERBOSE(PEER_KEY_ERROR);
9339 return PEER_KEY_ERROR;
9340 }
9341
9342 /* if DhKey is not setup, do it now */
9343 if (keyShareEntry->key == NULL) {
9344 keyShareEntry->key = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap,
9345 DYNAMIC_TYPE_DH);
9346 if (keyShareEntry->key == NULL)
9347 return MEMORY_E;
9348
9349 /* Setup Key */
9350 ret = wc_InitDhKey_ex((DhKey*)keyShareEntry->key, ssl->heap, ssl->devId);
9351 if (ret == 0) {
9352 dhKey = (DhKey*)keyShareEntry->key;
9353 /* Set key */
9354 #ifdef HAVE_PUBLIC_FFDHE
9355 ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g,
9356 params->g_len);
9357 #else
9358 ret = wc_DhSetNamedKey(dhKey, keyShareEntry->group);
9359 #endif
9360 }
9361 #if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
9362 defined(WC_ASYNC_ENABLE_DH)
9363 /* Only set non-blocking context when async device is active. With
9364 * INVALID_DEVID there is no async loop to retry on MP_WOULDBLOCK, so
9365 * skip non-blocking setup and use blocking mode instead. */
9366 if (ret == 0 && ssl->devId != INVALID_DEVID) {
9367 DhNb* dhNb = (DhNb*)XMALLOC(sizeof(DhNb), ssl->heap,
9368 DYNAMIC_TYPE_TMP_BUFFER);
9369 if (dhNb == NULL) {
9370 ret = MEMORY_E;
9371 }
9372 else {
9373 ret = wc_DhSetNonBlock((DhKey*)keyShareEntry->key, dhNb);
9374 if (ret != 0) {
9375 XFREE(dhNb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
9376 }
9377 }
9378 }
9379 #endif /* WC_DH_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
9380 WC_ASYNC_ENABLE_DH */
9381 }
9382
9383 if (ret == 0
9384 #ifdef WOLFSSL_ASYNC_CRYPT
9385 && keyShareEntry->lastRet == 0 /* don't enter here if WC_PENDING_E */
9386 #endif
9387 ) {
9388 #ifdef WOLFSSL_DEBUG_TLS
9389 WOLFSSL_MSG("Peer DH Key");
9390 WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
9391 #endif
9392
9393 ssl->options.dhKeySz = (word16)pSz;
9394
9395 /* Derive secret from private key and peer's public key. */
9396 ret = DhAgree(ssl, dhKey,
9397 (const byte*)keyShareEntry->privKey, keyShareEntry->keyLen, /* our private */
9398 keyShareEntry->ke, keyShareEntry->keLen, /* peer's public key */
9399 ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, /* secret */
9400 NULL, 0
9401 );
9402 #ifdef WOLFSSL_ASYNC_CRYPT
9403 if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
9404 return ret;
9405 }
9406 #endif
9407 }
9408
9409 /* RFC 8446 Section 7.4.1:
9410 * ... left-padded with zeros up to the size of the prime. ...
9411 */
9412 if (ret == 0 && (word32)ssl->options.dhKeySz > ssl->arrays->preMasterSz) {
9413 word32 diff = (word32)ssl->options.dhKeySz - ssl->arrays->preMasterSz;
9414 XMEMMOVE(ssl->arrays->preMasterSecret + diff,
9415 ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
9416 XMEMSET(ssl->arrays->preMasterSecret, 0, diff);
9417 ssl->arrays->preMasterSz = ssl->options.dhKeySz;
9418 }
9419
9420 /* done with key share, release resources */
9421 if (dhKey) {
9422 #if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
9423 defined(WC_ASYNC_ENABLE_DH)
9424 if (dhKey->nb != NULL) {
9425 XFREE(dhKey->nb, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
9426 dhKey->nb = NULL;
9427 }
9428 #endif
9429 wc_FreeDhKey(dhKey);
9430 }
9431 XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_DH);
9432 keyShareEntry->key = NULL;
9433 if (keyShareEntry->privKey) {
9434 ForceZero(keyShareEntry->privKey, keyShareEntry->keyLen);
9435 XFREE(keyShareEntry->privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
9436 keyShareEntry->privKey = NULL;
9437 }
9438 XFREE(keyShareEntry->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
9439 keyShareEntry->pubKey = NULL;
9440 XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
9441 keyShareEntry->ke = NULL;
9442#else
9443 (void)ssl;
9444 (void)keyShareEntry;
9445 ret = PEER_KEY_ERROR;
9446 WOLFSSL_ERROR_VERBOSE(ret);
9447#endif
9448 return ret;
9449}
9450
9451/* Process the X25519 key share extension on the client side.
9452 *
9453 * ssl The SSL/TLS object.
9454 * keyShareEntry The key share entry object to use to calculate shared secret.
9455 * ssOutput The destination buffer for the shared secret.
9456 * ssOutSz The size of the generated shared secret.
9457 *
9458 * returns 0 on success and other values indicate failure.
9459 */
9460static int TLSX_KeyShare_ProcessX25519_ex(WOLFSSL* ssl,
9461 KeyShareEntry* keyShareEntry,
9462 unsigned char* ssOutput,
9463 word32* ssOutSz)
9464{
9465 int ret = 0;
9466
9467#ifdef HAVE_CURVE25519
9468 curve25519_key* key = (curve25519_key*)keyShareEntry->key;
9469
9470#ifdef WOLFSSL_ASYNC_CRYPT
9471 if (keyShareEntry->lastRet == 0) /* don't enter here if WC_PENDING_E */
9472#endif
9473 {
9474 #ifdef HAVE_ECC
9475 if (ssl->peerEccKey != NULL) {
9476 wc_ecc_free(ssl->peerEccKey);
9477 ssl->peerEccKey = NULL;
9478 ssl->peerEccKeyPresent = 0;
9479 }
9480 #endif
9481
9482 ssl->peerX25519Key = (curve25519_key*)XMALLOC(sizeof(curve25519_key),
9483 ssl->heap, DYNAMIC_TYPE_TLSX);
9484 if (ssl->peerX25519Key == NULL) {
9485 WOLFSSL_MSG("PeerX25519Key Memory error");
9486 return MEMORY_ERROR;
9487 }
9488 ret = wc_curve25519_init(ssl->peerX25519Key);
9489 if (ret != 0) {
9490 XFREE(ssl->peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
9491 ssl->peerX25519Key = NULL;
9492 return ret;
9493 }
9494 #ifdef WOLFSSL_DEBUG_TLS
9495 WOLFSSL_MSG("Peer Curve25519 Key");
9496 WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
9497 #endif
9498
9499 if (wc_curve25519_check_public(keyShareEntry->ke, keyShareEntry->keLen,
9500 EC25519_LITTLE_ENDIAN) != 0) {
9501 ret = ECC_PEERKEY_ERROR;
9502 WOLFSSL_ERROR_VERBOSE(ret);
9503 }
9504
9505 if (ret == 0) {
9506 if (wc_curve25519_import_public_ex(keyShareEntry->ke,
9507 keyShareEntry->keLen,
9508 ssl->peerX25519Key,
9509 EC25519_LITTLE_ENDIAN) != 0) {
9510 ret = ECC_PEERKEY_ERROR;
9511 WOLFSSL_ERROR_VERBOSE(ret);
9512 }
9513 }
9514
9515 if (ret == 0) {
9516 ssl->ecdhCurveOID = ECC_X25519_OID;
9517 ssl->peerX25519KeyPresent = 1;
9518 }
9519 }
9520
9521 if (ret == 0 && key == NULL)
9522 ret = BAD_FUNC_ARG;
9523 if (ret == 0) {
9524 #ifdef WOLFSSL_CURVE25519_BLINDING
9525 ret = wc_curve25519_set_rng(key, ssl->rng);
9526 }
9527 if (ret == 0) {
9528 #endif
9529 #ifdef WOLFSSL_ASYNC_CRYPT
9530 if (keyShareEntry->lastRet != WC_NO_ERR_TRACE(WC_PENDING_E))
9531 #endif
9532 {
9533 #ifdef WOLFSSL_ASYNC_CRYPT
9534 /* initialize event */
9535 ret = wolfSSL_AsyncInit(ssl, &key->asyncDev,
9536 WC_ASYNC_FLAG_CALL_AGAIN);
9537 if (ret != 0)
9538 return ret;
9539 #endif
9540 ret = wc_curve25519_shared_secret_ex(key, ssl->peerX25519Key,
9541 ssOutput, ssOutSz, EC25519_LITTLE_ENDIAN);
9542 #ifdef WOLFSSL_ASYNC_CRYPT
9543 if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
9544 return wolfSSL_AsyncPush(ssl, &key->asyncDev);
9545 }
9546 #endif
9547 }
9548 /* On CALL_AGAIN re-entry (lastRet == PENDING): the block above
9549 * is skipped entirely, so wc_curve25519_shared_secret_ex is not
9550 * called again. ret stays 0 from initialization, and execution
9551 * falls through to the cleanup code below. */
9552 }
9553
9554 /* done with key share, release resources */
9555 if (ssl->peerX25519Key != NULL) {
9556 wc_curve25519_free(ssl->peerX25519Key);
9557 XFREE(ssl->peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
9558 ssl->peerX25519Key = NULL;
9559 ssl->peerX25519KeyPresent = 0;
9560 }
9561 if (keyShareEntry->key != NULL) {
9562 #if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW)
9563 if (((curve25519_key*)keyShareEntry->key)->nb_ctx != NULL) {
9564 XFREE(((curve25519_key*)keyShareEntry->key)->nb_ctx, ssl->heap,
9565 DYNAMIC_TYPE_TMP_BUFFER);
9566 }
9567 #endif
9568 wc_curve25519_free((curve25519_key*)keyShareEntry->key);
9569 XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
9570 keyShareEntry->key = NULL;
9571 }
9572 XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
9573 keyShareEntry->ke = NULL;
9574#else
9575 (void)ssl;
9576 (void)keyShareEntry;
9577 (void)ssOutput;
9578 (void)ssOutSz;
9579
9580 ret = PEER_KEY_ERROR;
9581 WOLFSSL_ERROR_VERBOSE(ret);
9582#endif /* HAVE_CURVE25519 */
9583
9584 return ret;
9585}
9586
9587/* Process the X25519 key share extension on the client side.
9588 *
9589 * ssl The SSL/TLS object.
9590 * keyShareEntry The key share entry object to use to calculate shared secret.
9591 *
9592 * returns 0 on success and other values indicate failure.
9593 */
9594static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl,
9595 KeyShareEntry* keyShareEntry)
9596{
9597 return TLSX_KeyShare_ProcessX25519_ex(ssl, keyShareEntry,
9598 ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz);
9599}
9600
9601/* Process the X448 key share extension on the client side.
9602 *
9603 * ssl The SSL/TLS object.
9604 * keyShareEntry The key share entry object to use to calculate shared secret.
9605 * ssOutput The destination buffer for the shared secret.
9606 * ssOutSz The size of the generated shared secret.
9607 *
9608 * returns 0 on success and other values indicate failure.
9609 */
9610static int TLSX_KeyShare_ProcessX448_ex(WOLFSSL* ssl,
9611 KeyShareEntry* keyShareEntry,
9612 unsigned char* ssOutput,
9613 word32* ssOutSz)
9614{
9615 int ret;
9616
9617#ifdef HAVE_CURVE448
9618 curve448_key* key = (curve448_key*)keyShareEntry->key;
9619 curve448_key* peerX448Key;
9620
9621#ifdef HAVE_ECC
9622 if (ssl->peerEccKey != NULL) {
9623 wc_ecc_free(ssl->peerEccKey);
9624 ssl->peerEccKey = NULL;
9625 ssl->peerEccKeyPresent = 0;
9626 }
9627#endif
9628
9629 peerX448Key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap,
9630 DYNAMIC_TYPE_TLSX);
9631 if (peerX448Key == NULL) {
9632 WOLFSSL_MSG("PeerEccKey Memory error");
9633 return MEMORY_ERROR;
9634 }
9635 ret = wc_curve448_init(peerX448Key);
9636 if (ret != 0) {
9637 XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX);
9638 return ret;
9639 }
9640#ifdef WOLFSSL_DEBUG_TLS
9641 WOLFSSL_MSG("Peer Curve448 Key");
9642 WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
9643#endif
9644
9645 if (wc_curve448_check_public(keyShareEntry->ke, keyShareEntry->keLen,
9646 EC448_LITTLE_ENDIAN) != 0) {
9647 ret = ECC_PEERKEY_ERROR;
9648 WOLFSSL_ERROR_VERBOSE(ret);
9649 }
9650
9651 if (ret == 0) {
9652 if (wc_curve448_import_public_ex(keyShareEntry->ke,
9653 keyShareEntry->keLen, peerX448Key,
9654 EC448_LITTLE_ENDIAN) != 0) {
9655 ret = ECC_PEERKEY_ERROR;
9656 WOLFSSL_ERROR_VERBOSE(ret);
9657 }
9658 }
9659
9660 if (ret == 0) {
9661 ssl->ecdhCurveOID = ECC_X448_OID;
9662
9663 ret = wc_curve448_shared_secret_ex(key, peerX448Key,
9664 ssOutput, ssOutSz, EC448_LITTLE_ENDIAN);
9665 }
9666
9667 wc_curve448_free(peerX448Key);
9668 XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX);
9669 wc_curve448_free((curve448_key*)keyShareEntry->key);
9670 XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
9671 keyShareEntry->key = NULL;
9672 XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
9673 keyShareEntry->ke = NULL;
9674#else
9675 (void)ssl;
9676 (void)keyShareEntry;
9677 (void)ssOutput;
9678 (void)ssOutSz;
9679
9680 ret = PEER_KEY_ERROR;
9681 WOLFSSL_ERROR_VERBOSE(ret);
9682#endif /* HAVE_CURVE448 */
9683
9684 return ret;
9685}
9686
9687/* Process the X448 key share extension on the client side.
9688 *
9689 * ssl The SSL/TLS object.
9690 * keyShareEntry The key share entry object to use to calculate shared secret.
9691 * returns 0 on success and other values indicate failure.
9692 */
9693static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
9694{
9695 return TLSX_KeyShare_ProcessX448_ex(ssl, keyShareEntry,
9696 ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz);
9697}
9698
9699/* Process the ECC key share extension on the client side.
9700 *
9701 * ssl The SSL/TLS object.
9702 * keyShareEntry The key share entry object to use to calculate shared secret.
9703 * ssOutput The destination buffer for the shared secret.
9704 * ssOutSz The size of the generated shared secret.
9705 *
9706 * returns 0 on success and other values indicate failure.
9707 */
9708static int TLSX_KeyShare_ProcessEcc_ex(WOLFSSL* ssl,
9709 KeyShareEntry* keyShareEntry,
9710 unsigned char* ssOutput,
9711 word32* ssOutSz)
9712{
9713 int ret = 0;
9714#ifdef HAVE_ECC
9715 int curveId = ECC_CURVE_INVALID;
9716 ecc_key* eccKey = (ecc_key*)keyShareEntry->key;
9717
9718 /* find supported curve */
9719 switch (keyShareEntry->group) {
9720 #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
9721 #ifndef NO_ECC_SECP
9722 case WOLFSSL_ECC_SECP256R1:
9723 curveId = ECC_SECP256R1;
9724 break;
9725 #endif /* !NO_ECC_SECP */
9726 #ifdef WOLFSSL_SM2
9727 case WOLFSSL_ECC_SM2P256V1:
9728 curveId = ECC_SM2P256V1;
9729 break;
9730 #endif /* WOLFSSL_SM2 */
9731 #ifdef HAVE_ECC_BRAINPOOL
9732 case WOLFSSL_ECC_BRAINPOOLP256R1TLS13:
9733 curveId = ECC_BRAINPOOLP256R1;
9734 break;
9735 #endif /* HAVE_ECC_BRAINPOOL */
9736 #endif
9737 #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
9738 #ifndef NO_ECC_SECP
9739 case WOLFSSL_ECC_SECP384R1:
9740 curveId = ECC_SECP384R1;
9741 break;
9742 #endif /* !NO_ECC_SECP */
9743 #ifdef HAVE_ECC_BRAINPOOL
9744 case WOLFSSL_ECC_BRAINPOOLP384R1TLS13:
9745 curveId = ECC_BRAINPOOLP384R1;
9746 break;
9747 #endif /* HAVE_ECC_BRAINPOOL */
9748 #endif
9749 #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
9750 #ifdef HAVE_ECC_BRAINPOOL
9751 case WOLFSSL_ECC_BRAINPOOLP512R1TLS13:
9752 curveId = ECC_BRAINPOOLP512R1;
9753 break;
9754 #endif /* HAVE_ECC_BRAINPOOL */
9755 #endif
9756 #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
9757 #ifndef NO_ECC_SECP
9758 case WOLFSSL_ECC_SECP521R1:
9759 curveId = ECC_SECP521R1;
9760 break;
9761 #endif /* !NO_ECC_SECP */
9762 #endif
9763 #if defined(HAVE_X448) && ECC_MIN_KEY_SZ <= 448
9764 case WOLFSSL_ECC_X448:
9765 curveId = ECC_X448;
9766 break;
9767 #endif
9768 default:
9769 /* unsupported curve */
9770 WOLFSSL_ERROR_VERBOSE(ECC_PEERKEY_ERROR);
9771 return ECC_PEERKEY_ERROR;
9772 }
9773
9774#ifdef WOLFSSL_ASYNC_CRYPT
9775 if (keyShareEntry->lastRet == 0) /* don't enter here if WC_PENDING_E */
9776#endif
9777 {
9778 #ifdef WOLFSSL_DEBUG_TLS
9779 WOLFSSL_MSG("Peer ECC Key");
9780 WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
9781 #endif
9782
9783 if (ssl->peerEccKey != NULL) {
9784 wc_ecc_free(ssl->peerEccKey);
9785 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
9786 ssl->peerEccKeyPresent = 0;
9787 }
9788#if defined(WOLFSSL_RENESAS_TSIP_TLS)
9789 ret = tsip_Tls13GenSharedSecret(ssl, keyShareEntry);
9790 if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
9791 return ret;
9792 }
9793 ret = 0;
9794#endif
9795
9796 ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap,
9797 DYNAMIC_TYPE_ECC);
9798 if (ssl->peerEccKey == NULL) {
9799 WOLFSSL_MSG("PeerEccKey Memory error");
9800 ret = MEMORY_ERROR;
9801 }
9802
9803 if (ret == 0) {
9804 ret = wc_ecc_init_ex(ssl->peerEccKey, ssl->heap, ssl->devId);
9805 }
9806
9807 /* Point is validated by import function. */
9808 if (ret == 0) {
9809#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
9810 ret = wc_ecc_import_x963_ex2(keyShareEntry->ke,
9811 keyShareEntry->keLen, ssl->peerEccKey, curveId, 1);
9812#else
9813 /* FIPS has validation define on. */
9814 ret = wc_ecc_import_x963_ex(keyShareEntry->ke,
9815 keyShareEntry->keLen, ssl->peerEccKey, curveId);
9816#endif
9817 if (ret != 0) {
9818 ret = ECC_PEERKEY_ERROR;
9819 WOLFSSL_ERROR_VERBOSE(ret);
9820 }
9821 }
9822
9823 if (ret == 0) {
9824 ssl->ecdhCurveOID = ssl->peerEccKey->dp->oidSum;
9825 ssl->peerEccKeyPresent = 1;
9826 }
9827 }
9828
9829 if (ret == 0 && eccKey == NULL)
9830 ret = BAD_FUNC_ARG;
9831 if (ret == 0) {
9832 ret = EccSharedSecret(ssl, eccKey, ssl->peerEccKey,
9833 keyShareEntry->ke, &keyShareEntry->keLen,
9834 ssOutput, ssOutSz, ssl->options.side);
9835 #ifdef WOLFSSL_ASYNC_CRYPT
9836 if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
9837 return ret;
9838 #endif
9839 }
9840
9841 /* done with key share, release resources */
9842 if (ssl->peerEccKey != NULL
9843 #ifdef HAVE_PK_CALLBACKS
9844 && ssl->ctx->EccSharedSecretCb == NULL
9845 #endif
9846 ) {
9847 wc_ecc_free(ssl->peerEccKey);
9848 XFREE(ssl->peerEccKey, ssl->heap, DYNAMIC_TYPE_ECC);
9849 ssl->peerEccKey = NULL;
9850 ssl->peerEccKeyPresent = 0;
9851 }
9852 if (eccKey != NULL) {
9853 #if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
9854 defined(WC_ASYNC_ENABLE_ECC)
9855 if (eccKey->nb_ctx != NULL) {
9856 XFREE(eccKey->nb_ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
9857 }
9858 #endif
9859 wc_ecc_free(eccKey);
9860 XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_ECC);
9861 keyShareEntry->key = NULL;
9862 }
9863 XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
9864 keyShareEntry->ke = NULL;
9865#else
9866 (void)ssl;
9867 (void)keyShareEntry;
9868 (void)ssOutput;
9869 (void)ssOutSz;
9870
9871 ret = PEER_KEY_ERROR;
9872 WOLFSSL_ERROR_VERBOSE(ret);
9873#endif /* HAVE_ECC */
9874
9875 return ret;
9876}
9877
9878/* Process the ECC key share extension on the client side.
9879 *
9880 * ssl The SSL/TLS object.
9881 * keyShareEntry The key share entry object to use to calculate shared secret.
9882 * returns 0 on success and other values indicate failure.
9883 */
9884static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
9885{
9886 return TLSX_KeyShare_ProcessEcc_ex(ssl, keyShareEntry,
9887 ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz);
9888}
9889
9890#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_DECAPSULATE)
9891/* Process the Kyber key share extension on the client side.
9892 *
9893 * ssl The SSL/TLS object.
9894 * keyShareEntry The key share entry object to use to calculate shared secret.
9895 * ssOutput The destination buffer for the shared secret.
9896 * ssOutSz The size of the generated shared secret.
9897 *
9898 * returns 0 on success and other values indicate failure.
9899 */
9900static int TLSX_KeyShare_ProcessPqcClient_ex(WOLFSSL* ssl,
9901 KeyShareEntry* keyShareEntry,
9902 unsigned char* ssOutput,
9903 word32* ssOutSz)
9904{
9905 int ret = 0;
9906 KyberKey* kem = (KyberKey*)keyShareEntry->key;
9907#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
9908 word32 privSz = 0;
9909#endif
9910 word32 ctSz = 0;
9911 word32 ssSz = 0;
9912
9913 if (ssl->options.side == WOLFSSL_SERVER_END) {
9914 /* I am the server, the shared secret has already been generated and
9915 * is in ssl->arrays->preMasterSecret, so nothing really to do here. */
9916 return 0;
9917 }
9918
9919 if (keyShareEntry->ke == NULL) {
9920 WOLFSSL_MSG("Invalid PQC algorithm specified.");
9921 return BAD_FUNC_ARG;
9922 }
9923 if (ssOutSz == NULL)
9924 return BAD_FUNC_ARG;
9925
9926#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
9927 if (kem == NULL) {
9928 int type = 0;
9929
9930 /* Allocate a Kyber key to hold private key. */
9931 kem = (KyberKey*) XMALLOC(sizeof(KyberKey), ssl->heap,
9932 DYNAMIC_TYPE_PRIVATE_KEY);
9933 if (kem == NULL) {
9934 WOLFSSL_MSG("GenPqcKey memory error");
9935 ret = MEMORY_E;
9936 }
9937 if (ret == 0) {
9938 ret = mlkem_id2type(keyShareEntry->group, &type);
9939 }
9940 if (ret != 0) {
9941 WOLFSSL_MSG("Invalid PQC algorithm specified.");
9942 ret = BAD_FUNC_ARG;
9943 }
9944 if (ret == 0) {
9945 ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId);
9946 if (ret != 0) {
9947 WOLFSSL_MSG("Error creating Kyber KEM");
9948 }
9949 }
9950 }
9951#else
9952 if (kem == NULL || keyShareEntry->privKeyLen != 0) {
9953 WOLFSSL_MSG("Invalid Kyber key.");
9954 ret = BAD_FUNC_ARG;
9955 }
9956#endif
9957
9958 if (ret == 0) {
9959 ret = wc_KyberKey_SharedSecretSize(kem, &ssSz);
9960 }
9961 if (ret == 0) {
9962 ret = wc_KyberKey_CipherTextSize(kem, &ctSz);
9963 }
9964
9965#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
9966 if (ret == 0) {
9967 ret = wc_KyberKey_PrivateKeySize(kem, &privSz);
9968 }
9969 if (ret == 0 && privSz != keyShareEntry->privKeyLen) {
9970 WOLFSSL_MSG("Invalid private key size.");
9971 ret = BAD_FUNC_ARG;
9972 }
9973 if (ret == 0) {
9974 PRIVATE_KEY_UNLOCK();
9975 ret = wc_KyberKey_DecodePrivateKey(kem, keyShareEntry->privKey, privSz);
9976 PRIVATE_KEY_LOCK();
9977 }
9978#endif
9979
9980 if (ret == 0 && keyShareEntry->keLen < ctSz) {
9981 WOLFSSL_MSG("PQC key share data too short for ciphertext.");
9982 ret = BUFFER_E;
9983 }
9984 if (ret == 0) {
9985 PRIVATE_KEY_UNLOCK();
9986 ret = wc_KyberKey_Decapsulate(kem, ssOutput,
9987 keyShareEntry->ke, ctSz);
9988 PRIVATE_KEY_LOCK();
9989 if (ret != 0) {
9990 WOLFSSL_MSG("wc_KyberKey decapsulation failure.");
9991 ret = BAD_FUNC_ARG;
9992 }
9993 }
9994 if (ret == 0) {
9995 *ssOutSz = ssSz;
9996 }
9997
9998 wc_KyberKey_Free(kem);
9999
10000 XFREE(kem, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
10001 keyShareEntry->key = NULL;
10002
10003 XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
10004 keyShareEntry->ke = NULL;
10005
10006 return ret;
10007}
10008
10009/* Process the Kyber key share extension on the client side.
10010 *
10011 * ssl The SSL/TLS object.
10012 * keyShareEntry The key share entry object to use to calculate shared secret.
10013 *
10014 * returns 0 on success and other values indicate failure.
10015 */
10016static int TLSX_KeyShare_ProcessPqcClient(WOLFSSL* ssl,
10017 KeyShareEntry* keyShareEntry)
10018{
10019 return TLSX_KeyShare_ProcessPqcClient_ex(ssl, keyShareEntry,
10020 ssl->arrays->preMasterSecret,
10021 &ssl->arrays->preMasterSz);
10022}
10023
10024/* Process the hybrid key share extension on the client side.
10025 *
10026 * ssl The SSL/TLS object.
10027 * keyShareEntry The key share entry object to use to calculate shared secret.
10028 * returns 0 on success and other values indicate failure.
10029 */
10030static int TLSX_KeyShare_ProcessPqcHybridClient(WOLFSSL* ssl,
10031 KeyShareEntry* keyShareEntry)
10032{
10033 int ret = 0;
10034 int pqc_group = 0;
10035 int ecc_group = 0;
10036 int pqc_first = 0;
10037 KeyShareEntry* pqc_kse = NULL;
10038 KeyShareEntry *ecc_kse = NULL;
10039 word32 ctSz = 0;
10040 word32 ssSzPqc = 0;
10041
10042 if (ssl->options.side == WOLFSSL_SERVER_END) {
10043 /* I am the server, the shared secret has already been generated and
10044 * is in ssl->arrays->preMasterSecret, so nothing really to do here. */
10045 return 0;
10046 }
10047
10048 if (keyShareEntry->ke == NULL) {
10049 WOLFSSL_MSG("Invalid PQC algorithm specified.");
10050 return BAD_FUNC_ARG;
10051 }
10052
10053 /* I am the client, both the PQC ciphertext and the ECHD public key are in
10054 * keyShareEntry->ke */
10055
10056 /* Determine the ECC and PQC group of the hybrid combination */
10057 findEccPqc(&ecc_group, &pqc_group, &pqc_first, keyShareEntry->group);
10058 if (ecc_group == 0 || pqc_group == 0) {
10059 WOLFSSL_MSG("Invalid hybrid group");
10060 ret = BAD_FUNC_ARG;
10061 }
10062
10063 if (ret == 0) {
10064 ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap,
10065 DYNAMIC_TYPE_TLSX);
10066 if (ecc_kse == NULL) {
10067 WOLFSSL_MSG("kse memory allocation failure");
10068 ret = MEMORY_ERROR;
10069 }
10070 else {
10071 XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
10072 }
10073 }
10074 if (ret == 0) {
10075 pqc_kse = (KeyShareEntry*)XMALLOC(sizeof(*pqc_kse), ssl->heap,
10076 DYNAMIC_TYPE_TLSX);
10077 if (pqc_kse == NULL) {
10078 WOLFSSL_MSG("kse memory allocation failure");
10079 ret = MEMORY_ERROR;
10080 }
10081 else {
10082 XMEMSET(pqc_kse, 0, sizeof(*pqc_kse));
10083 }
10084 }
10085
10086 /* The ciphertext and shared secret sizes of a KEM are fixed. Hence, we
10087 * decode these sizes to separate the KEM ciphertext from the ECDH public
10088 * key. */
10089 if (ret == 0) {
10090 #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
10091 int type;
10092
10093 pqc_kse->privKey = keyShareEntry->privKey;
10094
10095 ret = mlkem_id2type(pqc_group, &type);
10096 if (ret != 0) {
10097 WOLFSSL_MSG("Invalid Kyber algorithm specified.");
10098 ret = BAD_FUNC_ARG;
10099 }
10100 if (ret == 0) {
10101 pqc_kse->key = XMALLOC(sizeof(KyberKey), ssl->heap,
10102 DYNAMIC_TYPE_PRIVATE_KEY);
10103 if (pqc_kse->key == NULL) {
10104 WOLFSSL_MSG("GenPqcKey memory error");
10105 ret = MEMORY_E;
10106 }
10107 }
10108 if (ret == 0) {
10109 ret = wc_KyberKey_Init(type, (KyberKey*)pqc_kse->key,
10110 ssl->heap, ssl->devId);
10111 if (ret != 0) {
10112 WOLFSSL_MSG("Error creating Kyber KEM");
10113 }
10114 }
10115 #else
10116 pqc_kse->key = keyShareEntry->privKey;
10117 #endif
10118
10119 pqc_kse->group = pqc_group;
10120 pqc_kse->privKeyLen = keyShareEntry->privKeyLen;
10121
10122 if (ret == 0) {
10123 ret = wc_KyberKey_SharedSecretSize((KyberKey*)pqc_kse->key,
10124 &ssSzPqc);
10125 }
10126 if (ret == 0) {
10127 ret = wc_KyberKey_CipherTextSize((KyberKey*)pqc_kse->key,
10128 &ctSz);
10129 if (ret == 0 && keyShareEntry->keLen <= ctSz) {
10130 WOLFSSL_MSG("Invalid ciphertext size.");
10131 ret = BAD_FUNC_ARG;
10132 }
10133 }
10134 if (ret == 0) {
10135 pqc_kse->keLen = ctSz;
10136 pqc_kse->ke = (byte*)XMALLOC(pqc_kse->keLen, ssl->heap,
10137 DYNAMIC_TYPE_PUBLIC_KEY);
10138 if (pqc_kse->ke == NULL) {
10139 WOLFSSL_MSG("pqc_kse memory allocation failure");
10140 ret = MEMORY_ERROR;
10141 }
10142 /* Copy the PQC KEM ciphertext. Depending on the pqc_first flag,
10143 * the KEM ciphertext comes before or after the ECDH public key. */
10144 if (ret == 0) {
10145 int offset = keyShareEntry->keLen - ctSz;
10146
10147 if (pqc_first)
10148 offset = 0;
10149
10150 XMEMCPY(pqc_kse->ke, keyShareEntry->ke + offset, ctSz);
10151 }
10152 }
10153 }
10154
10155 if (ret == 0) {
10156 ecc_kse->group = ecc_group;
10157 ecc_kse->keLen = keyShareEntry->keLen - ctSz;
10158 ecc_kse->key = keyShareEntry->key;
10159 ecc_kse->ke = (byte*)XMALLOC(ecc_kse->keLen, ssl->heap,
10160 DYNAMIC_TYPE_PUBLIC_KEY);
10161 if (ecc_kse->ke == NULL) {
10162 WOLFSSL_MSG("ecc_kse memory allocation failure");
10163 ret = MEMORY_ERROR;
10164 }
10165 /* Copy the ECDH public key. Depending on the pqc_first flag, the
10166 * KEM ciphertext comes before or after the ECDH public key. */
10167 if (ret == 0) {
10168 int offset = 0;
10169
10170 if (pqc_first)
10171 offset = ctSz;
10172
10173 XMEMCPY(ecc_kse->ke, keyShareEntry->ke + offset, ecc_kse->keLen);
10174 }
10175 #ifdef WOLFSSL_ASYNC_CRYPT
10176 ecc_kse->lastRet = keyShareEntry->lastRet;
10177 #endif
10178 }
10179
10180 /* Process ECDH key share part. The generated shared secret is directly
10181 * stored in the ssl->arrays->preMasterSecret buffer. Depending on the
10182 * pqc_first flag, the ECDH shared secret part goes before or after the
10183 * KEM part. */
10184 if (ret == 0) {
10185 int offset = 0;
10186
10187 if (pqc_first)
10188 offset = ssSzPqc;
10189
10190 #ifdef HAVE_CURVE25519
10191 if (ecc_group == WOLFSSL_ECC_X25519) {
10192 ret = TLSX_KeyShare_ProcessX25519_ex(ssl, ecc_kse,
10193 ssl->arrays->preMasterSecret + offset,
10194 &ssl->arrays->preMasterSz);
10195 }
10196 else
10197 #endif
10198 #ifdef HAVE_CURVE448
10199 if (ecc_group == WOLFSSL_ECC_X448) {
10200 ret = TLSX_KeyShare_ProcessX448_ex(ssl, ecc_kse,
10201 ssl->arrays->preMasterSecret + offset,
10202 &ssl->arrays->preMasterSz);
10203 }
10204 else
10205 #endif
10206 {
10207 ret = TLSX_KeyShare_ProcessEcc_ex(ssl, ecc_kse,
10208 ssl->arrays->preMasterSecret + offset,
10209 &ssl->arrays->preMasterSz);
10210 }
10211
10212 #ifdef WOLFSSL_ASYNC_CRYPT
10213 if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
10214 keyShareEntry->lastRet = WC_PENDING_E;
10215 /* Prevent freeing of the ECC and ML-KEM private keys */
10216 ecc_kse->key = NULL;
10217 pqc_kse->privKey = NULL;
10218 }
10219 else
10220 #endif
10221 {
10222 /* Re-sync keyShareEntry->key with ecc_kse->key. ecc_kse->key was
10223 * aliased to keyShareEntry->key above. The inner Process*_ex
10224 * either ran its end-of-function cleanup and set ecc_kse->key
10225 * to NULL (so the outer pointer must also become NULL to avoid
10226 * UAF/double-free in TLSX_KeyShare_FreeAll), or returned early
10227 * before cleanup with ecc_kse->key still pointing at the live
10228 * key (so the outer pointer must keep that pointer for later
10229 * freeing). Mirroring whatever the inner left in ecc_kse->key
10230 * handles both cases correctly. */
10231 keyShareEntry->key = ecc_kse->key;
10232 }
10233 }
10234
10235 if (ret == 0) {
10236 if ((ssl->arrays->preMasterSz + ssSzPqc) > ENCRYPT_LEN) {
10237 WOLFSSL_MSG("shared secret is too long.");
10238 ret = LENGTH_ERROR;
10239 }
10240 }
10241
10242 /* Process PQC KEM key share part. Depending on the pqc_first flag, the
10243 * KEM shared secret part goes before or after the ECDH part. */
10244 if (ret == 0) {
10245 int offset = ssl->arrays->preMasterSz;
10246
10247 if (pqc_first)
10248 offset = 0;
10249
10250 ret = TLSX_KeyShare_ProcessPqcClient_ex(ssl, pqc_kse,
10251 ssl->arrays->preMasterSecret + offset, &ssSzPqc);
10252 }
10253
10254 if (ret == 0) {
10255 keyShareEntry->privKey = (byte*)pqc_kse->key;
10256
10257 ssl->arrays->preMasterSz += ssSzPqc;
10258 }
10259 else
10260#ifdef WOLFSSL_ASYNC_CRYPT
10261 if (ret != WC_NO_ERR_TRACE(WC_PENDING_E))
10262#endif
10263 {
10264 /* Clear the pre master secret buffer to prevent leaking any
10265 * intermediate keys in the error case. Do not use preMasterSz
10266 * here as it may already been set to the ECC shared secret size,
10267 * which would be too small due to the PQC offset case. */
10268 ForceZero(ssl->arrays->preMasterSecret, ENCRYPT_LEN);
10269
10270 /* Prevent FreeAll from freeing pointers owned by keyShareEntry. */
10271 if (ecc_kse != NULL)
10272 ecc_kse->key = NULL;
10273 if (pqc_kse != NULL) {
10274 #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ
10275 pqc_kse->privKey = NULL;
10276 #else
10277 pqc_kse->key = NULL;
10278 #endif
10279 }
10280 }
10281
10282 TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
10283 TLSX_KeyShare_FreeAll(pqc_kse, ssl->heap);
10284
10285 return ret;
10286}
10287#endif /* WOLFSSL_HAVE_MLKEM && !WOLFSSL_MLKEM_NO_DECAPSULATE */
10288
10289/* Process the key share extension on the client side.
10290 *
10291 * ssl The SSL/TLS object.
10292 * keyShareEntry The key share entry object to use to calculate shared secret.
10293 * returns 0 on success and other values indicate failure.
10294 */
10295static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
10296{
10297 int ret;
10298
10299#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
10300 keyShareEntry->session = ssl->session->namedGroup;
10301 ssl->session->namedGroup = keyShareEntry->group;
10302#endif
10303 /* reset the pre master secret size */
10304 if (ssl->arrays->preMasterSz == 0)
10305 ssl->arrays->preMasterSz = ENCRYPT_LEN;
10306
10307 /* Use Key Share Data from server. */
10308 if (WOLFSSL_NAMED_GROUP_IS_FFDHE(keyShareEntry->group))
10309 ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry);
10310 else if (keyShareEntry->group == WOLFSSL_ECC_X25519)
10311 ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry);
10312 else if (keyShareEntry->group == WOLFSSL_ECC_X448)
10313 ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry);
10314#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_DECAPSULATE)
10315 else if (WOLFSSL_NAMED_GROUP_IS_PQC(keyShareEntry->group))
10316 ret = TLSX_KeyShare_ProcessPqcClient(ssl, keyShareEntry);
10317 else if (WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(keyShareEntry->group))
10318 ret = TLSX_KeyShare_ProcessPqcHybridClient(ssl, keyShareEntry);
10319#endif
10320 else
10321 ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry);
10322
10323#ifdef WOLFSSL_DEBUG_TLS
10324 if (ret == 0) {
10325 WOLFSSL_MSG("KE Secret");
10326 WOLFSSL_BUFFER(ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz);
10327 }
10328#endif
10329#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
10330 keyShareEntry->derived = (ret == 0);
10331#endif
10332#ifdef WOLFSSL_ASYNC_CRYPT
10333 keyShareEntry->lastRet = ret;
10334#endif
10335
10336 return ret;
10337}
10338
10339/* Parse an entry of the KeyShare extension.
10340 *
10341 * ssl The SSL/TLS object.
10342 * input The extension data.
10343 * length The length of the extension data.
10344 * kse The new key share entry object.
10345 * returns a positive number to indicate amount of data parsed and a negative
10346 * number on error.
10347 */
10348static int TLSX_KeyShareEntry_Parse(const WOLFSSL* ssl, const byte* input,
10349 word16 length, KeyShareEntry **kse, word16* seenGroups,
10350 int* seenGroupsCnt, TLSX** extensions)
10351{
10352 int ret;
10353 word16 group;
10354 word16 keLen;
10355 int offset = 0;
10356 byte* ke;
10357 int i;
10358
10359 if (length < OPAQUE16_LEN + OPAQUE16_LEN)
10360 return BUFFER_ERROR;
10361 /* Named group */
10362 ato16(&input[offset], &group);
10363 offset += OPAQUE16_LEN;
10364 /* Key exchange data - public key. */
10365 ato16(&input[offset], &keLen);
10366 offset += OPAQUE16_LEN;
10367 if (keLen == 0)
10368 return BUFFER_ERROR;
10369 if (keLen > length - offset)
10370 return BUFFER_ERROR;
10371
10372 if (seenGroups != NULL) {
10373 if (*seenGroupsCnt >= MAX_KEYSHARE_NAMED_GROUPS) {
10374 return BAD_KEY_SHARE_DATA;
10375 }
10376 for (i = 0; i < *seenGroupsCnt; i++) {
10377 if (seenGroups[i] == group) {
10378 return BAD_KEY_SHARE_DATA;
10379 }
10380 }
10381 seenGroups[i] = group;
10382 *seenGroupsCnt = i + 1;
10383 }
10384
10385 /* Store a copy in the key share object. */
10386 ke = (byte*)XMALLOC(keLen, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
10387 if (ke == NULL)
10388 return MEMORY_E;
10389 XMEMCPY(ke, &input[offset], keLen);
10390
10391 /* Populate a key share object in the extension. */
10392 ret = TLSX_KeyShare_Use(ssl, group, keLen, ke, kse, extensions);
10393 if (ret != 0) {
10394 XFREE(ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
10395 return ret;
10396 }
10397
10398 /* Total length of the parsed data. */
10399 return offset + keLen;
10400}
10401
10402/* Searches the groups sent for the specified named group.
10403 *
10404 * ssl SSL/TLS object.
10405 * name Group name to match.
10406 * returns 1 when the extension has the group name and 0 otherwise.
10407 */
10408static int TLSX_KeyShare_Find(WOLFSSL* ssl, word16 group)
10409{
10410 TLSX* extension;
10411 KeyShareEntry* list;
10412
10413 extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
10414 if (extension == NULL) {
10415 extension = TLSX_Find(ssl->ctx->extensions, TLSX_KEY_SHARE);
10416 if (extension == NULL)
10417 return 0;
10418 }
10419
10420 list = (KeyShareEntry*)extension->data;
10421 while (list != NULL) {
10422 if (list->group == group)
10423 return 1;
10424 list = list->next;
10425 }
10426
10427 return 0;
10428}
10429
10430
10431/* Searches the supported groups extension for the specified named group.
10432 *
10433 * ssl The SSL/TLS object.
10434 * name The group name to match.
10435 * returns 1 when the extension has the group name and 0 otherwise.
10436 */
10437static int TLSX_SupportedGroups_Find(const WOLFSSL* ssl, word16 name,
10438 TLSX* extensions)
10439{
10440#ifdef HAVE_SUPPORTED_CURVES
10441 TLSX* extension;
10442 SupportedCurve* curve = NULL;
10443
10444 if ((extension = TLSX_Find(extensions, TLSX_SUPPORTED_GROUPS)) == NULL) {
10445 if ((extension = TLSX_Find(ssl->ctx->extensions,
10446 TLSX_SUPPORTED_GROUPS)) == NULL) {
10447 return 0;
10448 }
10449 }
10450
10451 for (curve = (SupportedCurve*)extension->data; curve; curve = curve->next) {
10452 if (curve->name == name)
10453 return 1;
10454 }
10455#endif
10456
10457 (void)ssl;
10458 (void)name;
10459
10460 return 0;
10461}
10462
10463int TLSX_KeyShare_Parse_ClientHello(const WOLFSSL* ssl,
10464 const byte* input, word16 length, TLSX** extensions)
10465{
10466 int ret;
10467 int offset = 0;
10468 word16 len;
10469 TLSX* extension;
10470 word16 seenGroups[MAX_KEYSHARE_NAMED_GROUPS];
10471 int seenGroupsCnt = 0;
10472
10473 /* Add a KeyShare extension if it doesn't exist even if peer sent no
10474 * entries. The presence of this extension signals that the peer can be
10475 * negotiated with. */
10476 extension = TLSX_Find(*extensions, TLSX_KEY_SHARE);
10477 if (extension == NULL) {
10478 /* Push new KeyShare extension. */
10479 ret = TLSX_Push(extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
10480 if (ret != 0)
10481 return ret;
10482 }
10483
10484 if (length < OPAQUE16_LEN)
10485 return BUFFER_ERROR;
10486
10487 /* ClientHello contains zero or more key share entries. Limits extension
10488 * length to 2^16-1 and subtracting 4 bytes for header size per RFC 8446 */
10489 ato16(input, &len);
10490 if ((len != length - OPAQUE16_LEN) ||
10491 length > (MAX_EXT_DATA_LEN - HELLO_EXT_SZ)) {
10492 return BUFFER_ERROR;
10493 }
10494 offset += OPAQUE16_LEN;
10495
10496 while (offset < (int)length) {
10497 ret = TLSX_KeyShareEntry_Parse(ssl, &input[offset],
10498 length - (word16)offset, NULL, seenGroups, &seenGroupsCnt,
10499 extensions);
10500 if (ret < 0)
10501 return ret;
10502
10503 offset += ret;
10504 }
10505
10506 return 0;
10507}
10508
10509/* Parse the KeyShare extension.
10510 * Different formats in different messages.
10511 *
10512 * ssl The SSL/TLS object.
10513 * input The extension data.
10514 * length The length of the extension data.
10515 * msgType The type of the message this extension is being parsed from.
10516 * returns 0 on success and other values indicate failure.
10517 */
10518int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input, word16 length,
10519 byte msgType)
10520{
10521 int ret = 0;
10522 KeyShareEntry *keyShareEntry = NULL;
10523 word16 group;
10524
10525 if (msgType == client_hello) {
10526 ret = TLSX_KeyShare_Parse_ClientHello(ssl, input, length,
10527 &ssl->extensions);
10528 }
10529 else if (msgType == server_hello) {
10530 int len;
10531
10532 if (length < OPAQUE16_LEN)
10533 return BUFFER_ERROR;
10534
10535 ssl->options.shSentKeyShare = 1;
10536
10537 /* The data is the named group the server wants to use. */
10538 ato16(input, &group);
10539
10540 /* Check the selected group was supported by ClientHello extensions. */
10541 if (!TLSX_SupportedGroups_Find(ssl, group, ssl->extensions)) {
10542 WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
10543 return BAD_KEY_SHARE_DATA;
10544 }
10545
10546 /* Check if the group was sent. */
10547 if (!TLSX_KeyShare_Find(ssl, group)) {
10548 WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
10549 return BAD_KEY_SHARE_DATA;
10550 }
10551
10552 /* ServerHello contains one key share entry. */
10553 len = TLSX_KeyShareEntry_Parse(ssl, input, length, &keyShareEntry, NULL,
10554 NULL, &ssl->extensions);
10555 if (len != (int)length)
10556 return BUFFER_ERROR;
10557
10558 /* Not in list sent if there isn't a private key. */
10559 if (keyShareEntry == NULL || (keyShareEntry->key == NULL
10560 #if !defined(NO_DH) || defined(WOLFSSL_HAVE_MLKEM)
10561 && keyShareEntry->privKey == NULL
10562 #endif
10563 )) {
10564 WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
10565 return BAD_KEY_SHARE_DATA;
10566 }
10567
10568 /* Process the entry to calculate the secret. */
10569 ret = TLSX_KeyShare_Process(ssl, keyShareEntry);
10570 if (ret == 0)
10571 ssl->session->namedGroup = ssl->namedGroup = group;
10572 }
10573 else if (msgType == hello_retry_request) {
10574 if (length != OPAQUE16_LEN)
10575 return BUFFER_ERROR;
10576
10577 ssl->options.hrrSentKeyShare = 1;
10578
10579 /* The data is the named group the server wants to use. */
10580 ato16(input, &group);
10581
10582 #ifdef WOLFSSL_ASYNC_CRYPT
10583 /* only perform find and clear TLSX if not returning from async */
10584 if (ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E))
10585 #endif
10586 {
10587 /* Check the selected group was supported by ClientHello extensions.
10588 */
10589 if (!TLSX_SupportedGroups_Find(ssl, group, ssl->extensions)) {
10590 WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
10591 return BAD_KEY_SHARE_DATA;
10592 }
10593
10594 /* Make sure KeyShare for server requested group was not sent in
10595 * ClientHello. */
10596 if (TLSX_KeyShare_Find(ssl, group)) {
10597 WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
10598 return BAD_KEY_SHARE_DATA;
10599 }
10600
10601 /* Clear out unusable key shares. */
10602 ret = TLSX_KeyShare_Empty(ssl);
10603 if (ret != 0)
10604 return ret;
10605 }
10606
10607 ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL, &ssl->extensions);
10608 if (ret == 0)
10609 ssl->session->namedGroup = ssl->namedGroup = group;
10610 }
10611 else {
10612 /* Not a message type that is allowed to have this extension. */
10613 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
10614 return SANITY_MSG_E;
10615 }
10616
10617 return ret;
10618}
10619
10620/* Create a new key share entry and put it into the list.
10621 *
10622 * list The linked list of key share entries.
10623 * group The named group.
10624 * heap The memory to allocate with.
10625 * keyShareEntry The new key share entry object.
10626 * returns 0 on success and other values indicate failure.
10627 */
10628static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap,
10629 KeyShareEntry** keyShareEntry)
10630{
10631 KeyShareEntry* kse;
10632 KeyShareEntry** next;
10633
10634 kse = (KeyShareEntry*)XMALLOC(sizeof(KeyShareEntry), heap,
10635 DYNAMIC_TYPE_TLSX);
10636 if (kse == NULL)
10637 return MEMORY_E;
10638
10639 XMEMSET(kse, 0, sizeof(*kse));
10640 kse->group = (word16)group;
10641
10642 /* Add it to the back and maintain the links. */
10643 while (*list != NULL) {
10644 /* Assign to temporary to work around compiler bug found by customer. */
10645 next = &((*list)->next);
10646 list = next;
10647 }
10648 *list = kse;
10649 *keyShareEntry = kse;
10650
10651 (void)heap;
10652
10653 return 0;
10654}
10655
10656#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE)
10657/* Process the Kyber key share extension on the server side.
10658 *
10659 * ssl The SSL/TLS object.
10660 * keyShareEntry The key share entry object to be sent to the client.
10661 * data The key share data received from the client.
10662 * len The length of the key share data from the client.
10663 * ssOutput The destination buffer for the shared secret.
10664 * ssOutSz The size of the generated shared secret.
10665 *
10666 * returns 0 on success and other values indicate failure.
10667 */
10668static int TLSX_KeyShare_HandlePqcKeyServer(WOLFSSL* ssl,
10669 KeyShareEntry* keyShareEntry, byte* clientData, word16 clientLen,
10670 unsigned char* ssOutput, word32* ssOutSz)
10671{
10672 /* We are on the server side. The key share contains a PQC KEM public key
10673 * that we are using for an encapsulate operation. The resulting ciphertext
10674 * is stored in the server key share. */
10675 KyberKey* kemKey = (KyberKey*)keyShareEntry->key;
10676 byte* ciphertext = NULL;
10677 int ret = 0;
10678 word32 pubSz = 0;
10679 word32 ctSz = 0;
10680 word32 ssSz = 0;
10681
10682 if (clientData == NULL) {
10683 WOLFSSL_MSG("No KEM public key from the client.");
10684 return BAD_FUNC_ARG;
10685 }
10686
10687 if (kemKey == NULL) {
10688 int type = 0;
10689
10690 /* Allocate a Kyber key to hold private key. */
10691 kemKey = (KyberKey*) XMALLOC(sizeof(KyberKey), ssl->heap,
10692 DYNAMIC_TYPE_PRIVATE_KEY);
10693 if (kemKey == NULL) {
10694 WOLFSSL_MSG("GenPqcKey memory error");
10695 ret = MEMORY_E;
10696 }
10697 if (ret == 0) {
10698 ret = mlkem_id2type(keyShareEntry->group, &type);
10699 }
10700 if (ret != 0) {
10701 WOLFSSL_MSG("Invalid PQC algorithm specified.");
10702 ret = BAD_FUNC_ARG;
10703 }
10704 if (ret == 0) {
10705 ret = wc_KyberKey_Init(type, kemKey, ssl->heap, ssl->devId);
10706 if (ret != 0) {
10707 WOLFSSL_MSG("Error creating Kyber KEM");
10708 }
10709 }
10710 }
10711
10712 if (ret == 0) {
10713 ret = wc_KyberKey_PublicKeySize(kemKey, &pubSz);
10714 }
10715 if (ret == 0) {
10716 ret = wc_KyberKey_CipherTextSize(kemKey, &ctSz);
10717 }
10718 if (ret == 0) {
10719 ret = wc_KyberKey_SharedSecretSize(kemKey, &ssSz);
10720 }
10721
10722 if (ret == 0 && clientLen != pubSz) {
10723 WOLFSSL_MSG("Invalid public key.");
10724 ret = BAD_FUNC_ARG;
10725 }
10726
10727 if (ret == 0) {
10728 ciphertext = (byte*)XMALLOC(ctSz, ssl->heap, DYNAMIC_TYPE_TLSX);
10729
10730 if (ciphertext == NULL) {
10731 WOLFSSL_MSG("Ciphertext memory allocation failure.");
10732 ret = MEMORY_E;
10733 }
10734 }
10735
10736 if (ret == 0) {
10737 ret = wc_KyberKey_DecodePublicKey(kemKey, clientData, pubSz);
10738 }
10739 if (ret == 0) {
10740 ret = wc_KyberKey_Encapsulate(kemKey, ciphertext,
10741 ssOutput, ssl->rng);
10742 if (ret != 0) {
10743 WOLFSSL_MSG("wc_KyberKey encapsulation failure.");
10744 }
10745 }
10746
10747 if (ret == 0) {
10748 XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
10749
10750 *ssOutSz = ssSz;
10751 keyShareEntry->ke = NULL;
10752 keyShareEntry->keLen = 0;
10753
10754 XFREE(keyShareEntry->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
10755 keyShareEntry->pubKey = ciphertext;
10756 keyShareEntry->pubKeyLen = ctSz;
10757 ciphertext = NULL;
10758
10759 /* Set namedGroup so wolfSSL_get_curve_name() can function properly on
10760 * the server side. */
10761 ssl->namedGroup = keyShareEntry->group;
10762 }
10763
10764 XFREE(ciphertext, ssl->heap, DYNAMIC_TYPE_TLSX);
10765
10766 wc_KyberKey_Free(kemKey);
10767 XFREE(kemKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
10768 keyShareEntry->key = NULL;
10769 return ret;
10770}
10771
10772int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl,
10773 KeyShareEntry* keyShareEntry, byte* data, word16 len)
10774{
10775 /* I am the server. The data parameter is the concatenation of the client's
10776 * ECDH public key and the KEM public key. I need to generate a matching
10777 * public key for ECDH and encapsulate a shared secret using the KEM public
10778 * key. We send the ECDH public key and the KEM ciphertext back to the
10779 * client. Additionally, we create the ECDH shared secret here already.
10780 */
10781 int type;
10782 byte* ciphertext = NULL;
10783 int ret = 0;
10784 int pqc_group = 0;
10785 int ecc_group = 0;
10786 int pqc_first = 0;
10787 KeyShareEntry *ecc_kse = NULL;
10788 KeyShareEntry *pqc_kse = NULL;
10789 word32 pubSz = 0;
10790 word32 ctSz = 0;
10791 word32 ssSzPqc = 0;
10792
10793 if (data == NULL) {
10794 WOLFSSL_MSG("No hybrid key share data from the client.");
10795 return BAD_FUNC_ARG;
10796 }
10797
10798 /* Determine the ECC and PQC group of the hybrid combination */
10799 findEccPqc(&ecc_group, &pqc_group, &pqc_first, keyShareEntry->group);
10800 if (ecc_group == 0 || pqc_group == 0) {
10801 WOLFSSL_MSG("Invalid hybrid group");
10802 ret = BAD_FUNC_ARG;
10803 }
10804
10805 if (ret == 0) {
10806 ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap,
10807 DYNAMIC_TYPE_TLSX);
10808 pqc_kse = (KeyShareEntry*)XMALLOC(sizeof(*pqc_kse), ssl->heap,
10809 DYNAMIC_TYPE_TLSX);
10810 if (ecc_kse == NULL || pqc_kse == NULL) {
10811 WOLFSSL_MSG("kse memory allocation failure");
10812 ret = MEMORY_ERROR;
10813 }
10814 }
10815 if (ret == 0) {
10816 XMEMSET(ecc_kse, 0, sizeof(*ecc_kse));
10817 ecc_kse->group = ecc_group;
10818 XMEMSET(pqc_kse, 0, sizeof(*pqc_kse));
10819 pqc_kse->group = pqc_group;
10820 }
10821
10822 /* The ciphertext and shared secret sizes of a KEM are fixed. Hence, we
10823 * decode these sizes to properly concatenate the KEM ciphertext with the
10824 * ECDH public key. */
10825 if (ret == 0) {
10826 /* Allocate a Kyber key to hold private key. */
10827 pqc_kse->key = (KyberKey*) XMALLOC(sizeof(KyberKey), ssl->heap,
10828 DYNAMIC_TYPE_PRIVATE_KEY);
10829 if (pqc_kse->key == NULL) {
10830 WOLFSSL_MSG("GenPqcKey memory error");
10831 ret = MEMORY_E;
10832 }
10833 if (ret == 0) {
10834 ret = mlkem_id2type(pqc_kse->group, &type);
10835 }
10836 if (ret != 0) {
10837 WOLFSSL_MSG("Invalid PQC algorithm specified.");
10838 ret = BAD_FUNC_ARG;
10839 }
10840 if (ret == 0) {
10841 ret = wc_KyberKey_Init(type, (KyberKey*)pqc_kse->key,
10842 ssl->heap, ssl->devId);
10843 if (ret != 0) {
10844 WOLFSSL_MSG("Error creating Kyber KEM");
10845 }
10846 }
10847 if (ret == 0) {
10848 ret = wc_KyberKey_SharedSecretSize((KyberKey*)pqc_kse->key,
10849 &ssSzPqc);
10850 }
10851 if (ret == 0) {
10852 ret = wc_KyberKey_CipherTextSize((KyberKey*)pqc_kse->key,
10853 &ctSz);
10854 }
10855 if (ret == 0) {
10856 ret = wc_KyberKey_PublicKeySize((KyberKey*)pqc_kse->key,
10857 &pubSz);
10858 }
10859 }
10860
10861#ifdef WOLFSSL_ASYNC_CRYPT
10862 if (ret == 0) {
10863 /* Check if the provided kse already contains ECC data and the
10864 * last error was WC_PENDING_E. In this case, we already tried to
10865 * process ECC kse data. Hence, we have to restore it. */
10866 if (keyShareEntry->key != NULL && keyShareEntry->keyLen > 0 &&
10867 keyShareEntry->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E)) {
10868 ecc_kse->key = keyShareEntry->key;
10869 ecc_kse->keyLen = keyShareEntry->keyLen;
10870 ecc_kse->pubKey = keyShareEntry->pubKey;
10871 ecc_kse->pubKeyLen = keyShareEntry->pubKeyLen;
10872 ecc_kse->lastRet = keyShareEntry->lastRet;
10873 keyShareEntry->key = NULL;
10874 keyShareEntry->pubKey = NULL;
10875 }
10876 }
10877#endif
10878
10879 /* Generate the ECDH key share part to be sent to the client */
10880 if (ret == 0 && ecc_group != 0 && ecc_kse->pubKey == NULL) {
10881 #ifdef HAVE_CURVE25519
10882 if (ecc_group == WOLFSSL_ECC_X25519) {
10883 ret = TLSX_KeyShare_GenX25519Key(ssl, ecc_kse);
10884 }
10885 else
10886 #endif
10887 #ifdef HAVE_CURVE448
10888 if (ecc_group == WOLFSSL_ECC_X448) {
10889 ret = TLSX_KeyShare_GenX448Key(ssl, ecc_kse);
10890 }
10891 else
10892 #endif
10893 {
10894 ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse);
10895 }
10896 #ifdef WOLFSSL_ASYNC_CRYPT
10897 if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
10898 /* Store the generated ECC key in the provided kse to later
10899 * restore it.*/
10900 keyShareEntry->key = ecc_kse->key;
10901 keyShareEntry->keyLen = ecc_kse->keyLen;
10902 keyShareEntry->pubKeyLen = ecc_kse->pubKeyLen;
10903 keyShareEntry->lastRet = WC_PENDING_E;
10904 ecc_kse->key = NULL;
10905 }
10906 else if (ret == 0 &&
10907 keyShareEntry->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E)) {
10908 keyShareEntry->lastRet = 0;
10909 ecc_kse->lastRet = 0;
10910 }
10911 #endif
10912 }
10913
10914 if (ret == 0 && len != pubSz + ecc_kse->pubKeyLen) {
10915 WOLFSSL_MSG("Invalid public key.");
10916 ret = BAD_FUNC_ARG;
10917 }
10918
10919 /* Allocate buffer for the concatenated client key share data
10920 * (PQC KEM ciphertext + ECDH public key) */
10921 if (ret == 0) {
10922 ciphertext = (byte*)XMALLOC(ecc_kse->pubKeyLen + ctSz, ssl->heap,
10923 DYNAMIC_TYPE_TLSX);
10924
10925 if (ciphertext == NULL) {
10926 WOLFSSL_MSG("Ciphertext memory allocation failure.");
10927 ret = MEMORY_E;
10928 }
10929 }
10930
10931 /* Process ECDH key share part. The generated shared secret is directly
10932 * stored in the ssl->arrays->preMasterSecret buffer. Depending on the
10933 * pqc_first flag, the ECDH shared secret part goes before or after the
10934 * KEM part. */
10935 if (ret == 0) {
10936 ecc_kse->keLen = len - pubSz;
10937 ecc_kse->ke = (byte*)XMALLOC(ecc_kse->keLen, ssl->heap,
10938 DYNAMIC_TYPE_PUBLIC_KEY);
10939 if (ecc_kse->ke == NULL) {
10940 WOLFSSL_MSG("ecc_kse memory allocation failure");
10941 ret = MEMORY_ERROR;
10942 }
10943 if (ret == 0) {
10944 int pubOffset = 0;
10945 int ssOffset = 0;
10946
10947 if (pqc_first) {
10948 pubOffset = pubSz;
10949 ssOffset = ssSzPqc;
10950 }
10951
10952 XMEMCPY(ecc_kse->ke, data + pubOffset, ecc_kse->keLen);
10953
10954 #ifdef HAVE_CURVE25519
10955 if (ecc_group == WOLFSSL_ECC_X25519) {
10956 ret = TLSX_KeyShare_ProcessX25519_ex(ssl, ecc_kse,
10957 ssl->arrays->preMasterSecret + ssOffset,
10958 &ssl->arrays->preMasterSz);
10959 }
10960 else
10961 #endif
10962 #ifdef HAVE_CURVE448
10963 if (ecc_group == WOLFSSL_ECC_X448) {
10964 ret = TLSX_KeyShare_ProcessX448_ex(ssl, ecc_kse,
10965 ssl->arrays->preMasterSecret + ssOffset,
10966 &ssl->arrays->preMasterSz);
10967 }
10968 else
10969 #endif
10970 {
10971 ret = TLSX_KeyShare_ProcessEcc_ex(ssl, ecc_kse,
10972 ssl->arrays->preMasterSecret + ssOffset,
10973 &ssl->arrays->preMasterSz);
10974 }
10975 }
10976 if (ret == 0) {
10977 if (ssl->arrays->preMasterSz != ecc_kse->keyLen) {
10978 WOLFSSL_MSG("Data length mismatch.");
10979 ret = BAD_FUNC_ARG;
10980 }
10981 }
10982 #ifdef WOLFSSL_ASYNC_CRYPT
10983 else if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
10984 keyShareEntry->lastRet = WC_PENDING_E;
10985 keyShareEntry->key = ecc_kse->key;
10986 keyShareEntry->pubKey = ecc_kse->pubKey;
10987 keyShareEntry->pubKeyLen = ecc_kse->pubKeyLen;
10988 ecc_kse->key = NULL;
10989 ecc_kse->pubKey = NULL;
10990 }
10991 #endif
10992 }
10993
10994 if (ret == 0 && ssl->arrays->preMasterSz + ssSzPqc > ENCRYPT_LEN) {
10995 WOLFSSL_MSG("shared secret is too long.");
10996 ret = LENGTH_ERROR;
10997 }
10998
10999 /* Process PQC KEM key share part. Depending on the pqc_first flag, the
11000 * KEM shared secret part goes before or after the ECDH part. */
11001 if (ret == 0) {
11002 int input_offset = ecc_kse->keLen;
11003 int output_offset = ssl->arrays->preMasterSz;
11004
11005 if (pqc_first) {
11006 input_offset = 0;
11007 output_offset = 0;
11008 }
11009
11010 ret = TLSX_KeyShare_HandlePqcKeyServer(ssl, pqc_kse,
11011 data + input_offset, pubSz,
11012 ssl->arrays->preMasterSecret + output_offset, &ssSzPqc);
11013 }
11014
11015 if (ret == 0) {
11016 XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
11017
11018 ssl->arrays->preMasterSz += ssSzPqc;
11019 keyShareEntry->ke = NULL;
11020 keyShareEntry->keLen = 0;
11021
11022 /* Concatenate the ECDH public key and the PQC KEM ciphertext. Based on
11023 * the pqc_first flag, the ECDH public key goes before or after the KEM
11024 * ciphertext. */
11025 if (pqc_first) {
11026 XMEMCPY(ciphertext, pqc_kse->pubKey, ctSz);
11027 XMEMCPY(ciphertext + ctSz, ecc_kse->pubKey, ecc_kse->pubKeyLen);
11028 }
11029 else {
11030 XMEMCPY(ciphertext, ecc_kse->pubKey, ecc_kse->pubKeyLen);
11031 XMEMCPY(ciphertext + ecc_kse->pubKeyLen, pqc_kse->pubKey, ctSz);
11032 }
11033
11034 XFREE(keyShareEntry->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
11035 keyShareEntry->pubKey = ciphertext;
11036 keyShareEntry->pubKeyLen = ecc_kse->pubKeyLen + ctSz;
11037 ciphertext = NULL;
11038
11039 /* Set namedGroup so wolfSSL_get_curve_name() can function properly on
11040 * the server side. */
11041 ssl->namedGroup = keyShareEntry->group;
11042 }
11043 else
11044#ifdef WOLFSSL_ASYNC_CRYPT
11045 if (ret != WC_NO_ERR_TRACE(WC_PENDING_E))
11046#endif
11047 {
11048 /* Clear the pre master secret buffer to prevent leaking any
11049 * intermediate keys in the error case. Do not use preMasterSz
11050 * here as it may already been set to the ECC shared secret size,
11051 * which would be too small due to the PQC offset case. */
11052 ForceZero(ssl->arrays->preMasterSecret, ENCRYPT_LEN);
11053 }
11054
11055 TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap);
11056 TLSX_KeyShare_FreeAll(pqc_kse, ssl->heap);
11057 XFREE(ciphertext, ssl->heap, DYNAMIC_TYPE_TLSX);
11058 return ret;
11059}
11060#endif /* WOLFSSL_HAVE_MLKEM && !WOLFSSL_MLKEM_NO_ENCAPSULATE */
11061
11062/* Use the data to create a new key share object in the extensions.
11063 *
11064 * ssl The SSL/TLS object.
11065 * group The named group.
11066 * len The length of the public key data.
11067 * data The public key data.
11068 * kse The new key share entry object.
11069 * returns 0 on success and other values indicate failure.
11070 */
11071int TLSX_KeyShare_Use(const WOLFSSL* ssl, word16 group, word16 len, byte* data,
11072 KeyShareEntry **kse, TLSX** extensions)
11073{
11074 int ret = 0;
11075 TLSX* extension;
11076 KeyShareEntry* keyShareEntry = NULL;
11077
11078 /* Find the KeyShare extension if it exists. */
11079 extension = TLSX_Find(*extensions, TLSX_KEY_SHARE);
11080 if (extension == NULL) {
11081 /* Push new KeyShare extension. */
11082 ret = TLSX_Push(extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
11083 if (ret != 0)
11084 return ret;
11085
11086 extension = TLSX_Find(*extensions, TLSX_KEY_SHARE);
11087 if (extension == NULL)
11088 return MEMORY_E;
11089 }
11090 extension->resp = 0;
11091
11092 /* Try to find the key share entry with this group. */
11093 keyShareEntry = (KeyShareEntry*)extension->data;
11094 while (keyShareEntry != NULL) {
11095 #if defined(WOLFSSL_ML_KEM_USE_OLD_IDS) && \
11096 defined (WOLFSSL_EXTRA_PQC_HYBRIDS)
11097 if ((group == WOLFSSL_P256_ML_KEM_512_OLD &&
11098 keyShareEntry->group == WOLFSSL_SECP256R1MLKEM512) ||
11099 (group == WOLFSSL_P384_ML_KEM_768_OLD &&
11100 keyShareEntry->group == WOLFSSL_SECP384R1MLKEM768) ||
11101 (group == WOLFSSL_P521_ML_KEM_1024_OLD &&
11102 keyShareEntry->group == WOLFSSL_SECP521R1MLKEM1024)) {
11103 keyShareEntry->group = group;
11104 break;
11105 }
11106 else
11107 #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS && WOLFSSL_EXTRA_PQC_HYBRIDS */
11108 if (keyShareEntry->group == group)
11109 break;
11110 keyShareEntry = keyShareEntry->next;
11111 }
11112
11113 /* Create a new key share entry if not found. */
11114 if (keyShareEntry == NULL) {
11115 ret = TLSX_KeyShare_New((KeyShareEntry**)&extension->data, group,
11116 ssl->heap, &keyShareEntry);
11117 if (ret != 0)
11118 return ret;
11119 }
11120
11121 if (data != NULL) {
11122 /* Store the peer data in the key share object. */
11123 XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
11124 keyShareEntry->ke = data;
11125 keyShareEntry->keLen = len;
11126 }
11127 else {
11128 /* Generate a key pair. Casting to non-const since changes inside are
11129 * minimal but would require an extensive redesign to refactor. Also
11130 * this path shouldn't be taken when parsing a ClientHello in stateless
11131 * mode. */
11132 ret = TLSX_KeyShare_GenKey((WOLFSSL*)ssl, keyShareEntry);
11133 if (ret != 0)
11134 return ret;
11135 }
11136
11137 if (kse != NULL)
11138 *kse = keyShareEntry;
11139
11140 return 0;
11141}
11142
11143/* Set an empty Key Share extension.
11144 *
11145 * ssl The SSL/TLS object.
11146 * returns 0 on success and other values indicate failure.
11147 */
11148int TLSX_KeyShare_Empty(WOLFSSL* ssl)
11149{
11150 int ret = 0;
11151 TLSX* extension;
11152
11153 /* Find the KeyShare extension if it exists. */
11154 extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
11155 if (extension == NULL) {
11156 /* Push new KeyShare extension. */
11157 ret = TLSX_Push(&ssl->extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
11158 }
11159 else if (extension->data != NULL) {
11160 TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
11161 extension->data = NULL;
11162 }
11163
11164 return ret;
11165}
11166
11167static const word16 preferredGroup[] = {
11168 /* Sort by strength, but prefer non-experimental PQ/T hybrid groups */
11169#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \
11170 defined(WOLFSSL_PQC_HYBRIDS)
11171 #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519) && \
11172 ECC_MIN_KEY_SZ <= 256
11173 WOLFSSL_X25519MLKEM768,
11174 #endif
11175 #if !defined(WOLFSSL_NO_ML_KEM_1024) && defined(HAVE_ECC) && \
11176 (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \
11177 ECC_MIN_KEY_SZ <= 384
11178 WOLFSSL_SECP384R1MLKEM1024,
11179 #endif
11180 #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_ECC) && \
11181 (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \
11182 ECC_MIN_KEY_SZ <= 256
11183 WOLFSSL_SECP256R1MLKEM768,
11184 #endif
11185#endif /* WOLFSSL_HAVE_MLKEM && !WOLFSSL_NO_ML_KEM && WOLFSSL_PQC_HYBRIDS */
11186#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \
11187 !defined(WOLFSSL_NO_ML_KEM_1024) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
11188 WOLFSSL_ML_KEM_1024,
11189#endif
11190#if defined(HAVE_ECC) && (!defined(NO_ECC521) || \
11191 defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 521
11192 WOLFSSL_ECC_SECP521R1,
11193#endif
11194#if defined(HAVE_ECC) && defined(HAVE_ECC512) && \
11195 defined(HAVE_ECC_BRAINPOOL) && ECC_MIN_KEY_SZ <= 512
11196 WOLFSSL_ECC_BRAINPOOLP512R1TLS13,
11197#endif
11198#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \
11199 !defined(WOLFSSL_NO_ML_KEM_768) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
11200 WOLFSSL_ML_KEM_768,
11201#endif
11202#if defined(HAVE_ECC) && (!defined(NO_ECC384) || \
11203 defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 384
11204 WOLFSSL_ECC_SECP384R1,
11205#if defined(HAVE_ECC_BRAINPOOL)
11206 WOLFSSL_ECC_BRAINPOOLP384R1TLS13,
11207#endif
11208#endif
11209#if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
11210 WOLFSSL_ECC_X448,
11211#endif
11212#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM) && \
11213 !defined(WOLFSSL_NO_ML_KEM_512) && !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
11214 WOLFSSL_ML_KEM_512,
11215#endif
11216#if defined(HAVE_ECC) && (!defined(NO_ECC256) || \
11217 defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) && ECC_MIN_KEY_SZ <= 256
11218 WOLFSSL_ECC_SECP256R1,
11219#if !defined(HAVE_FIPS) && defined(WOLFSSL_SM2)
11220 WOLFSSL_ECC_SM2P256V1,
11221#endif
11222#if defined(HAVE_ECC_BRAINPOOL)
11223 WOLFSSL_ECC_BRAINPOOLP256R1TLS13,
11224#endif
11225#endif
11226#if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
11227 WOLFSSL_ECC_X25519,
11228#endif
11229#if defined(HAVE_FFDHE_8192)
11230 WOLFSSL_FFDHE_8192,
11231#endif
11232#if defined(HAVE_FFDHE_6144)
11233 WOLFSSL_FFDHE_6144,
11234#endif
11235#if defined(HAVE_FFDHE_4096)
11236 WOLFSSL_FFDHE_4096,
11237#endif
11238#if defined(HAVE_FFDHE_3072)
11239 WOLFSSL_FFDHE_3072,
11240#endif
11241#if defined(HAVE_FFDHE_2048)
11242 WOLFSSL_FFDHE_2048,
11243#endif
11244#ifndef WOLFSSL_NO_ML_KEM
11245 #if !defined(WOLFSSL_NO_ML_KEM_1024) && \
11246 defined(WOLFSSL_EXTRA_PQC_HYBRIDS)
11247 WOLFSSL_SECP521R1MLKEM1024,
11248 #endif
11249 #if !defined(WOLFSSL_NO_ML_KEM_768) && \
11250 defined(WOLFSSL_EXTRA_PQC_HYBRIDS)
11251 WOLFSSL_SECP384R1MLKEM768,
11252 #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
11253 WOLFSSL_X448MLKEM768,
11254 #endif /* HAVE_CURVE448 */
11255 #endif
11256 #if !defined(WOLFSSL_NO_ML_KEM_512) && \
11257 defined(WOLFSSL_EXTRA_PQC_HYBRIDS)
11258 WOLFSSL_SECP256R1MLKEM512,
11259 #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
11260 WOLFSSL_X25519MLKEM512,
11261 #endif /* HAVE_CURVE25519 */
11262 #endif
11263#endif /* !WOLFSSL_NO_ML_KEM */
11264#ifdef WOLFSSL_MLKEM_KYBER
11265 #ifdef WOLFSSL_KYBER1024
11266 WOLFSSL_KYBER_LEVEL5,
11267 WOLFSSL_P521_KYBER_LEVEL5,
11268 #endif
11269 #ifdef WOLFSSL_KYBER768
11270 WOLFSSL_KYBER_LEVEL3,
11271 WOLFSSL_P384_KYBER_LEVEL3,
11272 WOLFSSL_P256_KYBER_LEVEL3,
11273 #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
11274 WOLFSSL_X25519_KYBER_LEVEL3,
11275 #endif
11276 #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
11277 WOLFSSL_X448_KYBER_LEVEL3,
11278 #endif
11279 #endif
11280 #ifdef WOLFSSL_KYBER512
11281 WOLFSSL_KYBER_LEVEL1,
11282 WOLFSSL_P256_KYBER_LEVEL1,
11283 #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
11284 WOLFSSL_X25519_KYBER_LEVEL1,
11285 #endif
11286 #endif
11287#endif /* WOLFSSL_MLKEM_KYBER */
11288 WOLFSSL_NAMED_GROUP_INVALID
11289};
11290
11291#define PREFERRED_GROUP_SZ \
11292 ((sizeof(preferredGroup)/sizeof(*preferredGroup)) - 1)
11293 /* -1 for the invalid group */
11294
11295/* Examines the application specified group ranking and returns the rank of the
11296 * group.
11297 * If no group ranking set then all groups are rank 0 (highest).
11298 *
11299 * ssl The SSL/TLS object.
11300 * group The group to check ranking for.
11301 * returns ranking from 0 to MAX_GROUP_COUNT-1 or -1 when group not in list.
11302 */
11303static int TLSX_KeyShare_GroupRank(const WOLFSSL* ssl, int group)
11304{
11305 byte i;
11306 const word16* groups;
11307 byte numGroups;
11308
11309 if (ssl->numGroups == 0) {
11310 /* If the user didn't specify a group list with a preferred order,
11311 * use the internal preferred group list. */
11312 groups = preferredGroup;
11313 numGroups = PREFERRED_GROUP_SZ;
11314 }
11315 else {
11316 groups = ssl->group;
11317 numGroups = ssl->numGroups;
11318 }
11319
11320 for (i = 0; i < numGroups; i++) {
11321#if defined(WOLFSSL_ML_KEM_USE_OLD_IDS) && \
11322 defined (WOLFSSL_EXTRA_PQC_HYBRIDS)
11323 if ((group == WOLFSSL_P256_ML_KEM_512_OLD &&
11324 groups[i] == WOLFSSL_SECP256R1MLKEM512) ||
11325 (group == WOLFSSL_P384_ML_KEM_768_OLD &&
11326 groups[i] == WOLFSSL_SECP384R1MLKEM768) ||
11327 (group == WOLFSSL_P521_ML_KEM_1024_OLD &&
11328 groups[i] == WOLFSSL_SECP521R1MLKEM1024)) {
11329 return i;
11330 }
11331#endif
11332 if (groups[i] == (word16)group)
11333 return i;
11334 }
11335
11336 return WOLFSSL_FATAL_ERROR;
11337}
11338
11339/* Set a key share that is supported by the client into extensions.
11340 *
11341 * ssl The SSL/TLS object.
11342 * returns BAD_KEY_SHARE_DATA if no supported group has a key share,
11343 * 0 if a supported group has a key share and other values indicate an error.
11344 */
11345int TLSX_KeyShare_SetSupported(const WOLFSSL* ssl, TLSX** extensions)
11346{
11347 int ret;
11348#ifdef HAVE_SUPPORTED_CURVES
11349 TLSX* extension;
11350 SupportedCurve* curve = NULL;
11351 SupportedCurve* preferredCurve = NULL;
11352 word16 name = WOLFSSL_NAMED_GROUP_INVALID;
11353 KeyShareEntry* kse = NULL;
11354 int preferredRank = WOLFSSL_MAX_GROUP_COUNT;
11355 int rank;
11356
11357 extension = TLSX_Find(*extensions, TLSX_SUPPORTED_GROUPS);
11358 if (extension != NULL)
11359 curve = (SupportedCurve*)extension->data;
11360 for (; curve != NULL; curve = curve->next) {
11361 /* Use server's preference order. Common group was found but key share
11362 * was missing */
11363 if (!TLSX_IsGroupSupported(curve->name))
11364 continue;
11365 if (wolfSSL_curve_is_disabled(ssl, curve->name))
11366 continue;
11367
11368 rank = TLSX_KeyShare_GroupRank(ssl, curve->name);
11369 if (rank == -1)
11370 continue;
11371 if (rank < preferredRank) {
11372 preferredCurve = curve;
11373 preferredRank = rank;
11374 }
11375 }
11376 curve = preferredCurve;
11377
11378 if (curve == NULL) {
11379 byte i;
11380 /* Fallback to user selected group */
11381 preferredRank = WOLFSSL_MAX_GROUP_COUNT;
11382 for (i = 0; i < ssl->numGroups; i++) {
11383 rank = TLSX_KeyShare_GroupRank(ssl, ssl->group[i]);
11384 if (rank == -1)
11385 continue;
11386 if (rank < preferredRank) {
11387 name = ssl->group[i];
11388 preferredRank = rank;
11389 }
11390 }
11391 if (name == WOLFSSL_NAMED_GROUP_INVALID) {
11392 /* No group selected or specified by the server */
11393 WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
11394 return BAD_KEY_SHARE_DATA;
11395 }
11396 }
11397 else {
11398 name = curve->name;
11399 }
11400
11401 #ifdef WOLFSSL_ASYNC_CRYPT
11402 /* Check the old key share data list. */
11403 extension = TLSX_Find(*extensions, TLSX_KEY_SHARE);
11404 if (extension != NULL) {
11405 kse = (KeyShareEntry*)extension->data;
11406 /* We should not be computing keys if we are only going to advertise
11407 * our choice here. */
11408 if (kse != NULL && kse->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E)) {
11409 WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA);
11410 return BAD_KEY_SHARE_DATA;
11411 }
11412 }
11413 #endif
11414
11415 /* Push new KeyShare extension. This will also free the old one */
11416 ret = TLSX_Push(extensions, TLSX_KEY_SHARE, NULL, ssl->heap);
11417 if (ret != 0)
11418 return ret;
11419 /* Extension got pushed to head */
11420 extension = *extensions;
11421 /* Push the selected curve */
11422 ret = TLSX_KeyShare_New((KeyShareEntry**)&extension->data, name,
11423 ssl->heap, &kse);
11424 if (ret != 0)
11425 return ret;
11426 /* Set extension to be in response. */
11427 extension->resp = 1;
11428#else
11429
11430 (void)ssl;
11431
11432 WOLFSSL_ERROR_VERBOSE(NOT_COMPILED_IN);
11433 ret = NOT_COMPILED_IN;
11434#endif
11435
11436 return ret;
11437}
11438
11439#ifdef WOLFSSL_DUAL_ALG_CERTS
11440/* Writes the CKS objects of a list in a buffer. */
11441static word16 CKS_WRITE(WOLFSSL* ssl, byte* output)
11442{
11443 XMEMCPY(output, ssl->sigSpec, ssl->sigSpecSz);
11444 return ssl->sigSpecSz;
11445}
11446
11447static int TLSX_UseCKS(TLSX** extensions, WOLFSSL* ssl, void* heap)
11448{
11449 int ret = 0;
11450 TLSX* extension;
11451
11452 if (extensions == NULL) {
11453 return BAD_FUNC_ARG;
11454 }
11455
11456 extension = TLSX_Find(*extensions, TLSX_CKS);
11457 /* If it is already present, do nothing. */
11458 if (extension == NULL) {
11459 /* The data required is in the ssl struct, so push it in. */
11460 ret = TLSX_Push(extensions, TLSX_CKS, (void*)ssl, heap);
11461 }
11462
11463 return ret;
11464}
11465
11466int TLSX_CKS_Set(WOLFSSL* ssl, TLSX** extensions)
11467{
11468 int ret;
11469 TLSX* extension;
11470 /* Push new KeyShare extension. This will also free the old one */
11471 ret = TLSX_Push(extensions, TLSX_CKS, NULL, ssl->heap);
11472 if (ret != 0)
11473 return ret;
11474 /* Extension got pushed to head */
11475 extension = *extensions;
11476 /* Need ssl->sigSpecSz during extension length calculation. */
11477 extension->data = ssl;
11478 /* Set extension to be in response. */
11479 extension->resp = 1;
11480 return ret;
11481}
11482
11483int TLSX_CKS_Parse(WOLFSSL* ssl, byte* input, word16 length,
11484 TLSX** extensions)
11485{
11486 int ret;
11487 int i, j;
11488
11489 (void) extensions;
11490
11491 /* Validating the input. */
11492 if (length == 0)
11493 return BUFFER_ERROR;
11494 for (i = 0; i < length; i++) {
11495 switch (input[i])
11496 {
11497 case WOLFSSL_CKS_SIGSPEC_NATIVE:
11498 case WOLFSSL_CKS_SIGSPEC_ALTERNATIVE:
11499 case WOLFSSL_CKS_SIGSPEC_BOTH:
11500 /* These are all valid values; do nothing */
11501 break;
11502 case WOLFSSL_CKS_SIGSPEC_EXTERNAL:
11503 default:
11504 /* All other values (including external) are not. */
11505 return BAD_FUNC_ARG;
11506 }
11507 }
11508
11509 /* This could be a situation where the client tried to start with TLS 1.3
11510 * when it sent ClientHello and the server down-graded to TLS 1.2. In that
11511 * case, erroring out because it is TLS 1.2 is not a reasonable thing to do.
11512 * In the case of TLS 1.2, the CKS values will be ignored. */
11513 if (!IsAtLeastTLSv1_3(ssl->version)) {
11514 ssl->sigSpec = NULL;
11515 ssl->sigSpecSz = 0;
11516 return 0;
11517 }
11518
11519 /* Extension data is valid, but if we are the server and we don't have an
11520 * alt private key, do not respond with CKS extension. */
11521 if (wolfSSL_is_server(ssl) && ssl->buffers.altKey == NULL) {
11522 ssl->sigSpec = NULL;
11523 ssl->sigSpecSz = 0;
11524 return 0;
11525 }
11526
11527 /* Copy as the lifetime of input seems to be ephemeral. */
11528 ssl->peerSigSpec = (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_TLSX);
11529 if (ssl->peerSigSpec == NULL) {
11530 return BUFFER_ERROR;
11531 }
11532 XMEMCPY(ssl->peerSigSpec, input, length);
11533 ssl->peerSigSpecSz = length;
11534
11535 /* If there is no preference set, use theirs... */
11536 if (ssl->sigSpec == NULL) {
11537 ret = wolfSSL_UseCKS(ssl, ssl->peerSigSpec, 1);
11538 if (ret == WOLFSSL_SUCCESS) {
11539 ret = TLSX_UseCKS(&ssl->extensions, ssl, ssl->heap);
11540 TLSX_SetResponse(ssl, TLSX_CKS);
11541 }
11542 return ret;
11543 }
11544
11545 /* ...otherwise, prioritize our preference. */
11546 for (i = 0; i < ssl->sigSpecSz; i++) {
11547 for (j = 0; j < length; j++) {
11548 if (ssl->sigSpec[i] == input[j]) {
11549 /* Got the match, set to this one. */
11550 ret = wolfSSL_UseCKS(ssl, &ssl->sigSpec[i], 1);
11551 if (ret == WOLFSSL_SUCCESS) {
11552 ret = TLSX_UseCKS(&ssl->extensions, ssl, ssl->heap);
11553 TLSX_SetResponse(ssl, TLSX_CKS);
11554 }
11555 return ret;
11556 }
11557 }
11558 }
11559
11560 /* No match found. Cannot continue. */
11561 return MATCH_SUITE_ERROR;
11562}
11563#endif /* WOLFSSL_DUAL_ALG_CERTS */
11564
11565/* Server side KSE processing */
11566int TLSX_KeyShare_Choose(const WOLFSSL *ssl, TLSX* extensions,
11567 byte cipherSuite0, byte cipherSuite, KeyShareEntry** kse, byte* searched)
11568{
11569 TLSX* extension;
11570 KeyShareEntry* clientKSE = NULL;
11571 KeyShareEntry* list = NULL;
11572 KeyShareEntry* preferredKSE = NULL;
11573 int preferredRank = WOLFSSL_MAX_GROUP_COUNT;
11574 int rank;
11575
11576 (void)cipherSuite0;
11577 (void)cipherSuite;
11578
11579 if (ssl == NULL || ssl->options.side != WOLFSSL_SERVER_END)
11580 return BAD_FUNC_ARG;
11581
11582 *searched = 0;
11583
11584 /* Find the KeyShare extension if it exists. */
11585 extension = TLSX_Find(extensions, TLSX_KEY_SHARE);
11586 if (extension != NULL)
11587 list = (KeyShareEntry*)extension->data;
11588
11589 if (extension && extension->resp == 1) {
11590 /* Outside of the async case this path should not be taken. */
11591 int ret = WC_NO_ERR_TRACE(INCOMPLETE_DATA);
11592 #ifdef WOLFSSL_ASYNC_CRYPT
11593 /* in async case make sure key generation is finalized */
11594 KeyShareEntry* serverKSE = (KeyShareEntry*)extension->data;
11595 if (serverKSE && serverKSE->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E)) {
11596 if (ssl->options.serverState == SERVER_HELLO_RETRY_REQUEST_COMPLETE)
11597 *searched = 1;
11598 ret = TLSX_KeyShare_GenKey((WOLFSSL*)ssl, serverKSE);
11599 }
11600 else
11601 #endif
11602 {
11603 ret = INCOMPLETE_DATA;
11604 }
11605 return ret;
11606 }
11607
11608 /* Use server's preference order. */
11609 for (clientKSE = list; clientKSE != NULL; clientKSE = clientKSE->next) {
11610 if (clientKSE->ke == NULL)
11611 continue;
11612
11613#ifdef WOLFSSL_SM2
11614 if ((cipherSuite0 == CIPHER_BYTE) &&
11615 ((cipherSuite == TLS_SM4_GCM_SM3) ||
11616 (cipherSuite == TLS_SM4_CCM_SM3))) {
11617 if (clientKSE->group != WOLFSSL_ECC_SM2P256V1) {
11618 continue;
11619 }
11620 }
11621 else if (clientKSE->group == WOLFSSL_ECC_SM2P256V1) {
11622 continue;
11623 }
11624#endif
11625
11626 /* Check consistency now - extensions in any order. */
11627 if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group, extensions))
11628 continue;
11629
11630 if (!WOLFSSL_NAMED_GROUP_IS_FFDHE(clientKSE->group)) {
11631 /* Check max value supported. */
11632 if (clientKSE->group > WOLFSSL_ECC_MAX) {
11633#ifdef WOLFSSL_HAVE_MLKEM
11634 if (!WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group) &&
11635 !WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(clientKSE->group))
11636#endif
11637 continue;
11638 }
11639 if (wolfSSL_curve_is_disabled(ssl, clientKSE->group))
11640 continue;
11641 }
11642 if (!TLSX_IsGroupSupported(clientKSE->group))
11643 continue;
11644
11645 rank = TLSX_KeyShare_GroupRank(ssl, clientKSE->group);
11646 if (rank == -1)
11647 continue;
11648 if (rank < preferredRank) {
11649 preferredKSE = clientKSE;
11650 preferredRank = rank;
11651 }
11652 }
11653 *kse = preferredKSE;
11654 *searched = 1;
11655 return 0;
11656}
11657
11658/* Server side KSE processing */
11659int TLSX_KeyShare_Setup(WOLFSSL *ssl, KeyShareEntry* clientKSE)
11660{
11661 int ret;
11662 TLSX* extension;
11663 KeyShareEntry* serverKSE;
11664 KeyShareEntry* list = NULL;
11665
11666 if (ssl == NULL || ssl->options.side != WOLFSSL_SERVER_END)
11667 return BAD_FUNC_ARG;
11668
11669 extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
11670 if (extension == NULL)
11671 return BAD_STATE_E;
11672
11673 if (clientKSE == NULL) {
11674#ifdef WOLFSSL_ASYNC_CRYPT
11675 /* Not necessarily an error. The key may have already been setup. */
11676 if (extension != NULL && extension->resp == 1) {
11677 serverKSE = (KeyShareEntry*)extension->data;
11678 if (serverKSE != NULL) {
11679 /* in async case make sure key generation is finalized */
11680 if (serverKSE->lastRet == WC_NO_ERR_TRACE(WC_PENDING_E))
11681 return TLSX_KeyShare_GenKey((WOLFSSL*)ssl, serverKSE);
11682 else if (serverKSE->lastRet == 0)
11683 return 0;
11684 }
11685 }
11686#endif
11687 return BAD_FUNC_ARG;
11688 }
11689
11690 /* Generate a new key pair except in the case of PQC KEM because we
11691 * are going to encapsulate and that does not require us to generate a
11692 * key pair.
11693 */
11694 ret = TLSX_KeyShare_New(&list, clientKSE->group, ssl->heap, &serverKSE);
11695 if (ret != 0)
11696 return ret;
11697
11698 if (clientKSE->key == NULL) {
11699#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE)
11700 if (WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group)) {
11701 ret = TLSX_KeyShare_HandlePqcKeyServer(ssl, serverKSE,
11702 clientKSE->ke, clientKSE->keLen,
11703 ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz);
11704 }
11705 else if (WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(clientKSE->group)) {
11706 ret = TLSX_KeyShare_HandlePqcHybridKeyServer(ssl, serverKSE,
11707 clientKSE->ke, clientKSE->keLen);
11708 }
11709 else
11710#endif
11711 {
11712 ret = TLSX_KeyShare_GenKey(ssl, serverKSE);
11713 }
11714
11715 /* for async do setup of serverKSE below, but return WC_PENDING_E */
11716 if (ret != 0
11717 #ifdef WOLFSSL_ASYNC_CRYPT
11718 && ret != WC_NO_ERR_TRACE(WC_PENDING_E)
11719 #endif
11720 ) {
11721 TLSX_KeyShare_FreeAll(list, ssl->heap);
11722 return ret;
11723 }
11724 }
11725 else {
11726 /* transfer buffers to serverKSE */
11727 serverKSE->key = clientKSE->key;
11728 clientKSE->key = NULL;
11729 serverKSE->keyLen = clientKSE->keyLen;
11730 serverKSE->pubKey = clientKSE->pubKey;
11731 clientKSE->pubKey = NULL;
11732 serverKSE->pubKeyLen = clientKSE->pubKeyLen;
11733 #ifndef NO_DH
11734 serverKSE->privKey = clientKSE->privKey;
11735 clientKSE->privKey = NULL;
11736 #endif
11737 }
11738 serverKSE->ke = clientKSE->ke;
11739 serverKSE->keLen = clientKSE->keLen;
11740 clientKSE->ke = NULL;
11741 clientKSE->keLen = 0;
11742 ssl->namedGroup = serverKSE->group;
11743
11744 TLSX_KeyShare_FreeAll((KeyShareEntry*)extension->data, ssl->heap);
11745 extension->data = (void *)serverKSE;
11746
11747 extension->resp = 1;
11748 return ret;
11749}
11750
11751/* Ensure there is a key pair that can be used for key exchange.
11752 *
11753 * ssl The SSL/TLS object.
11754 * doHelloRetry If set to non-zero will do hello_retry
11755 * returns 0 on success and other values indicate failure.
11756 */
11757int TLSX_KeyShare_Establish(WOLFSSL *ssl, int* doHelloRetry)
11758{
11759 int ret;
11760 KeyShareEntry* clientKSE = NULL;
11761 byte searched = 0;
11762
11763 *doHelloRetry = 0;
11764
11765 ret = TLSX_KeyShare_Choose(ssl, ssl->extensions, ssl->cipher.cipherSuite0,
11766 ssl->cipher.cipherSuite, &clientKSE, &searched);
11767 if (ret != 0 || !searched)
11768 return ret;
11769
11770 /* No supported group found - send HelloRetryRequest. */
11771 if (clientKSE == NULL) {
11772 /* Set KEY_SHARE_ERROR to indicate HelloRetryRequest required. */
11773 *doHelloRetry = 1;
11774 return TLSX_KeyShare_SetSupported(ssl, &ssl->extensions);
11775 }
11776
11777 return TLSX_KeyShare_Setup(ssl, clientKSE);
11778}
11779
11780/* Derive the shared secret of the key exchange.
11781 *
11782 * ssl The SSL/TLS object.
11783 * returns 0 on success and other values indicate failure.
11784 */
11785int TLSX_KeyShare_DeriveSecret(WOLFSSL *ssl)
11786{
11787 int ret;
11788 TLSX* extension;
11789 KeyShareEntry* list = NULL;
11790
11791#ifdef WOLFSSL_ASYNC_CRYPT
11792 ret = wolfSSL_AsyncPop(ssl, NULL);
11793 /* Check for error */
11794 if (ret != WC_NO_ERR_TRACE(WC_NO_PENDING_E) && ret < 0) {
11795 return ret;
11796 }
11797#endif
11798
11799 /* Find the KeyShare extension if it exists. */
11800 extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
11801 if (extension != NULL)
11802 list = (KeyShareEntry*)extension->data;
11803
11804 if (list == NULL)
11805 return KEY_SHARE_ERROR;
11806
11807 /* Calculate secret. */
11808 ret = TLSX_KeyShare_Process(ssl, list);
11809
11810 return ret;
11811}
11812
11813#define KS_FREE_ALL TLSX_KeyShare_FreeAll
11814#define KS_GET_SIZE TLSX_KeyShare_GetSize
11815#define KS_WRITE TLSX_KeyShare_Write
11816#define KS_PARSE TLSX_KeyShare_Parse
11817
11818#else
11819
11820#define KS_FREE_ALL(a, b) WC_DO_NOTHING
11821#define KS_GET_SIZE(a, b) 0
11822#define KS_WRITE(a, b, c) 0
11823#define KS_PARSE(a, b, c, d) 0
11824
11825#endif /* WOLFSSL_TLS13 */
11826
11827/******************************************************************************/
11828/* Pre-Shared Key */
11829/******************************************************************************/
11830
11831#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
11832/* Free the pre-shared key dynamic data.
11833 *
11834 * list The linked list of key share entry objects.
11835 * heap The heap used for allocation.
11836 */
11837static void TLSX_PreSharedKey_FreeAll(PreSharedKey* list, void* heap)
11838{
11839 PreSharedKey* current;
11840
11841 while ((current = list) != NULL) {
11842 list = current->next;
11843 XFREE(current->identity, heap, DYNAMIC_TYPE_TLSX);
11844 XFREE(current, heap, DYNAMIC_TYPE_TLSX);
11845 }
11846
11847 (void)heap;
11848}
11849
11850/* Get the size of the encoded pre shared key extension.
11851 *
11852 * list The linked list of pre-shared key extensions.
11853 * msgType The type of the message this extension is being written into.
11854 * returns the number of bytes of the encoded pre-shared key extension or
11855 * SANITY_MSG_E to indicate invalid message type.
11856 */
11857static int TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType,
11858 word16* pSz)
11859{
11860 if (msgType == client_hello) {
11861 /* Length of identities + Length of binders. */
11862 word32 len = OPAQUE16_LEN + OPAQUE16_LEN;
11863 while (list != NULL) {
11864 /* Each entry has: identity, ticket age and binder. */
11865 len += OPAQUE16_LEN + list->identityLen + OPAQUE32_LEN +
11866 OPAQUE8_LEN + (word32)list->binderLen;
11867 if (len > WOLFSSL_MAX_16BIT) {
11868 WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
11869 return LENGTH_ERROR;
11870 }
11871 list = list->next;
11872 }
11873 if ((word32)*pSz + len > WOLFSSL_MAX_16BIT) {
11874 WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
11875 return LENGTH_ERROR;
11876 }
11877 *pSz += (word16)len;
11878 return 0;
11879 }
11880
11881 if (msgType == server_hello) {
11882 *pSz += OPAQUE16_LEN;
11883 return 0;
11884 }
11885
11886 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
11887 return SANITY_MSG_E;
11888}
11889
11890/* The number of bytes to be written for the binders.
11891 *
11892 * list The linked list of pre-shared key extensions.
11893 * msgType The type of the message this extension is being written into.
11894 * returns the number of bytes of the encoded pre-shared key extension or
11895 * SANITY_MSG_E to indicate invalid message type.
11896 */
11897int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType,
11898 word16* pSz)
11899{
11900 word32 len;
11901
11902 if (msgType != client_hello) {
11903 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
11904 return SANITY_MSG_E;
11905 }
11906
11907 /* Length of all binders. */
11908 len = OPAQUE16_LEN;
11909 while (list != NULL) {
11910 len += OPAQUE8_LEN + (word32)list->binderLen;
11911 if (len > WOLFSSL_MAX_16BIT) {
11912 WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
11913 return LENGTH_ERROR;
11914 }
11915 list = list->next;
11916 }
11917
11918 *pSz = (word16)len;
11919 return 0;
11920}
11921
11922/* Writes the pre-shared key extension into the output buffer - binders only.
11923 * Assumes that the the output buffer is big enough to hold data.
11924 *
11925 * list The linked list of key share entries.
11926 * output The buffer to write into.
11927 * msgType The type of the message this extension is being written into.
11928 * returns the number of bytes written into the buffer.
11929 */
11930int TLSX_PreSharedKey_WriteBinders(PreSharedKey* list, byte* output,
11931 byte msgType, word16* pSz)
11932{
11933 PreSharedKey* current = list;
11934 word16 idx = 0;
11935 word16 lenIdx;
11936 word16 len;
11937
11938 if (msgType != client_hello) {
11939 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
11940 return SANITY_MSG_E;
11941 }
11942
11943 /* Skip length of all binders. */
11944 lenIdx = idx;
11945 idx += OPAQUE16_LEN;
11946 while (current != NULL) {
11947 /* Binder data length. */
11948 output[idx++] = (byte)current->binderLen;
11949 /* Binder data. */
11950 XMEMCPY(output + idx, current->binder, current->binderLen);
11951 idx += (word16)current->binderLen;
11952
11953 current = current->next;
11954 }
11955 /* Length of the binders. */
11956 len = idx - lenIdx - OPAQUE16_LEN;
11957 c16toa(len, output + lenIdx);
11958
11959 *pSz = idx;
11960 return 0;
11961}
11962
11963
11964/* Writes the pre-shared key extension into the output buffer.
11965 * Assumes that the the output buffer is big enough to hold data.
11966 *
11967 * list The linked list of key share entries.
11968 * output The buffer to write into.
11969 * msgType The type of the message this extension is being written into.
11970 * returns the number of bytes written into the buffer.
11971 */
11972static int TLSX_PreSharedKey_Write(PreSharedKey* list, byte* output,
11973 byte msgType, word16* pSz)
11974{
11975 if (msgType == client_hello) {
11976 PreSharedKey* current = list;
11977 word16 idx = 0;
11978 word16 lenIdx;
11979 word16 len;
11980 int ret;
11981
11982 /* Write identities only. Binders after HMACing over this. */
11983 lenIdx = idx;
11984 idx += OPAQUE16_LEN;
11985 while (current != NULL) {
11986 /* Identity length */
11987 c16toa(current->identityLen, output + idx);
11988 idx += OPAQUE16_LEN;
11989 /* Identity data */
11990 XMEMCPY(output + idx, current->identity, current->identityLen);
11991 idx += current->identityLen;
11992
11993 /* Obfuscated ticket age. */
11994 c32toa(current->ticketAge, output + idx);
11995 idx += OPAQUE32_LEN;
11996
11997 current = current->next;
11998 }
11999 /* Length of the identities. */
12000 len = idx - lenIdx - OPAQUE16_LEN;
12001 c16toa(len, output + lenIdx);
12002
12003 /* Don't include binders here.
12004 * The binders are based on the hash of all the ClientHello data up to
12005 * and include the identities written above.
12006 */
12007 ret = TLSX_PreSharedKey_GetSizeBinders(list, msgType, &len);
12008 if (ret < 0)
12009 return ret;
12010 *pSz += idx + len;
12011 }
12012 else if (msgType == server_hello) {
12013 word16 i;
12014
12015 /* Find the index of the chosen identity. */
12016 for (i=0; list != NULL && !list->chosen; i++)
12017 list = list->next;
12018 if (list == NULL) {
12019 WOLFSSL_ERROR_VERBOSE(BUILD_MSG_ERROR);
12020 return BUILD_MSG_ERROR;
12021 }
12022
12023 /* The index of the identity chosen by the server from the list supplied
12024 * by the client.
12025 */
12026 c16toa(i, output);
12027 *pSz += OPAQUE16_LEN;
12028 }
12029 else {
12030 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12031 return SANITY_MSG_E;
12032 }
12033
12034 return 0;
12035}
12036
12037int TLSX_PreSharedKey_Parse_ClientHello(TLSX** extensions, const byte* input,
12038 word16 length, void* heap)
12039{
12040
12041 int ret;
12042 word16 len;
12043 word16 idx = 0;
12044 TLSX* extension;
12045 PreSharedKey* list;
12046
12047 TLSX_Remove(extensions, TLSX_PRE_SHARED_KEY, heap);
12048
12049 /* Length of identities and of binders. */
12050 if ((int)(length - idx) < OPAQUE16_LEN + OPAQUE16_LEN)
12051 return BUFFER_E;
12052
12053 /* Length of identities. */
12054 ato16(input + idx, &len);
12055 idx += OPAQUE16_LEN;
12056 if (len < MIN_PSK_ID_LEN || length - idx < len)
12057 return BUFFER_E;
12058
12059 /* Create a pre-shared key object for each identity. */
12060 while (len > 0) {
12061 const byte* identity;
12062 word16 identityLen;
12063 word32 age;
12064
12065 if (len < OPAQUE16_LEN)
12066 return BUFFER_E;
12067
12068 /* Length of identity. */
12069 ato16(input + idx, &identityLen);
12070 idx += OPAQUE16_LEN;
12071 if (len < OPAQUE16_LEN + identityLen + OPAQUE32_LEN ||
12072 identityLen > MAX_PSK_ID_LEN)
12073 return BUFFER_E;
12074 /* Cache identity pointer. */
12075 identity = input + idx;
12076 idx += identityLen;
12077 /* Ticket age. */
12078 ato32(input + idx, &age);
12079 idx += OPAQUE32_LEN;
12080
12081 ret = TLSX_PreSharedKey_Use(extensions, identity, identityLen, age, no_mac,
12082 0, 0, 1, NULL, heap);
12083 if (ret != 0)
12084 return ret;
12085
12086 /* Done with this identity. */
12087 len -= OPAQUE16_LEN + identityLen + OPAQUE32_LEN;
12088 }
12089
12090 /* Find the list of identities sent to server. */
12091 extension = TLSX_Find(*extensions, TLSX_PRE_SHARED_KEY);
12092 if (extension == NULL)
12093 return PSK_KEY_ERROR;
12094 list = (PreSharedKey*)extension->data;
12095
12096 /* Length of binders. */
12097 if (idx + OPAQUE16_LEN > length)
12098 return BUFFER_E;
12099 ato16(input + idx, &len);
12100 idx += OPAQUE16_LEN;
12101 if (len < MIN_PSK_BINDERS_LEN || length - idx < len)
12102 return BUFFER_E;
12103
12104 /* Set binder for each identity. */
12105 while (list != NULL && len > 0) {
12106 /* Length of binder */
12107 list->binderLen = input[idx++];
12108 if (list->binderLen < WC_SHA256_DIGEST_SIZE ||
12109 list->binderLen > WC_MAX_DIGEST_SIZE)
12110 return BUFFER_E;
12111 if (len < OPAQUE8_LEN + list->binderLen)
12112 return BUFFER_E;
12113
12114 /* Copy binder into static buffer. */
12115 XMEMCPY(list->binder, input + idx, list->binderLen);
12116 idx += (word16)list->binderLen;
12117
12118 /* Done with binder entry. */
12119 len -= OPAQUE8_LEN + (word16)list->binderLen;
12120
12121 /* Next identity. */
12122 list = list->next;
12123 }
12124 if (list != NULL || len != 0)
12125 return BUFFER_E;
12126
12127 return 0;
12128
12129}
12130
12131/* Parse the pre-shared key extension.
12132 * Different formats in different messages.
12133 *
12134 * ssl The SSL/TLS object.
12135 * input The extension data.
12136 * length The length of the extension data.
12137 * msgType The type of the message this extension is being parsed from.
12138 * returns 0 on success and other values indicate failure.
12139 */
12140static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, const byte* input,
12141 word16 length, byte msgType)
12142{
12143
12144 if (msgType == client_hello) {
12145 return TLSX_PreSharedKey_Parse_ClientHello(&ssl->extensions, input,
12146 length, ssl->heap);
12147 }
12148
12149 if (msgType == server_hello) {
12150 word16 idx;
12151 PreSharedKey* list;
12152 TLSX* extension;
12153
12154 /* Index of identity chosen by server. */
12155 if (length != OPAQUE16_LEN)
12156 return BUFFER_E;
12157 ato16(input, &idx);
12158
12159 #ifdef WOLFSSL_EARLY_DATA
12160 ssl->options.pskIdIndex = idx + 1;
12161 #endif
12162
12163 /* Find the list of identities sent to server. */
12164 extension = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
12165 if (extension == NULL)
12166 return INCOMPLETE_DATA;
12167 list = (PreSharedKey*)extension->data;
12168
12169 /* Mark the identity as chosen. */
12170 for (; list != NULL && idx > 0; idx--)
12171 list = list->next;
12172 if (list == NULL) {
12173 WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
12174 return PSK_KEY_ERROR;
12175 }
12176 list->chosen = 1;
12177
12178 if (list->resumption) {
12179 /* Check that the session's details are the same as the server's. */
12180 if (ssl->options.cipherSuite0 != ssl->session->cipherSuite0 ||
12181 ssl->options.cipherSuite != ssl->session->cipherSuite ||
12182 ssl->session->version.major != ssl->ctx->method->version.major ||
12183 ssl->session->version.minor != ssl->ctx->method->version.minor) {
12184 WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
12185 return PSK_KEY_ERROR;
12186 }
12187 }
12188
12189 return 0;
12190 }
12191
12192 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12193 return SANITY_MSG_E;
12194}
12195
12196/* Create a new pre-shared key and put it into the list.
12197 *
12198 * list The linked list of pre-shared key.
12199 * identity The identity.
12200 * len The length of the identity data.
12201 * heap The memory to allocate with.
12202 * preSharedKey The new pre-shared key object.
12203 * returns 0 on success and other values indicate failure.
12204 */
12205static int TLSX_PreSharedKey_New(PreSharedKey** list, const byte* identity,
12206 word16 len, void *heap,
12207 PreSharedKey** preSharedKey)
12208{
12209 PreSharedKey* psk;
12210 PreSharedKey** next;
12211
12212 psk = (PreSharedKey*)XMALLOC(sizeof(PreSharedKey), heap, DYNAMIC_TYPE_TLSX);
12213 if (psk == NULL)
12214 return MEMORY_E;
12215 XMEMSET(psk, 0, sizeof(*psk));
12216
12217 /* Make a copy of the identity data. */
12218 psk->identity = (byte*)XMALLOC(len + NULL_TERM_LEN, heap,
12219 DYNAMIC_TYPE_TLSX);
12220 if (psk->identity == NULL) {
12221 XFREE(psk, heap, DYNAMIC_TYPE_TLSX);
12222 return MEMORY_E;
12223 }
12224 XMEMCPY(psk->identity, identity, len);
12225 psk->identityLen = len;
12226 /* Use a NULL terminator in case it is a C string */
12227 psk->identity[psk->identityLen] = '\0';
12228
12229 /* Add it to the end and maintain the links. */
12230 while (*list != NULL) {
12231 /* Assign to temporary to work around compiler bug found by customer. */
12232 next = &((*list)->next);
12233 list = next;
12234 }
12235 *list = psk;
12236 *preSharedKey = psk;
12237
12238 (void)heap;
12239
12240 return 0;
12241}
12242
12243static WC_INLINE byte GetHmacLength(int hmac)
12244{
12245 switch (hmac) {
12246 #ifndef NO_SHA256
12247 case sha256_mac:
12248 return WC_SHA256_DIGEST_SIZE;
12249 #endif
12250 #ifdef WOLFSSL_SHA384
12251 case sha384_mac:
12252 return WC_SHA384_DIGEST_SIZE;
12253 #endif
12254 #ifdef WOLFSSL_SHA512
12255 case sha512_mac:
12256 return WC_SHA512_DIGEST_SIZE;
12257 #endif
12258 #ifdef WOLFSSL_SM3
12259 case sm3_mac:
12260 return WC_SM3_DIGEST_SIZE;
12261 #endif
12262 default:
12263 break;
12264 }
12265 return 0;
12266}
12267
12268/* Use the data to create a new pre-shared key object in the extensions.
12269 *
12270 * ssl The SSL/TLS object.
12271 * identity The identity.
12272 * len The length of the identity data.
12273 * age The age of the identity.
12274 * hmac The HMAC algorithm.
12275 * cipherSuite0 The first byte of the cipher suite to use.
12276 * cipherSuite The second byte of the cipher suite to use.
12277 * resumption The PSK is for resumption of a session.
12278 * preSharedKey The new pre-shared key object.
12279 * returns 0 on success and other values indicate failure.
12280 */
12281int TLSX_PreSharedKey_Use(TLSX** extensions, const byte* identity, word16 len,
12282 word32 age, byte hmac, byte cipherSuite0,
12283 byte cipherSuite, byte resumption,
12284 PreSharedKey **preSharedKey, void* heap)
12285{
12286 int ret = 0;
12287 TLSX* extension;
12288 PreSharedKey* psk = NULL;
12289
12290 /* Find the pre-shared key extension if it exists. */
12291 extension = TLSX_Find(*extensions, TLSX_PRE_SHARED_KEY);
12292 if (extension == NULL) {
12293 /* Push new pre-shared key extension. */
12294 ret = TLSX_Push(extensions, TLSX_PRE_SHARED_KEY, NULL, heap);
12295 if (ret != 0)
12296 return ret;
12297
12298 extension = TLSX_Find(*extensions, TLSX_PRE_SHARED_KEY);
12299 if (extension == NULL)
12300 return MEMORY_E;
12301 }
12302
12303 /* Try to find the pre-shared key with this identity. */
12304 psk = (PreSharedKey*)extension->data;
12305 while (psk != NULL) {
12306 if ((psk->identityLen == len) &&
12307 (XMEMCMP(psk->identity, identity, len) == 0)) {
12308 break;
12309 }
12310 psk = psk->next;
12311 }
12312
12313 /* Create a new pre-shared key object if not found. */
12314 if (psk == NULL) {
12315 ret = TLSX_PreSharedKey_New((PreSharedKey**)&extension->data, identity,
12316 len, heap, &psk);
12317 if (ret != 0)
12318 return ret;
12319 }
12320
12321 /* Update/set age and HMAC algorithm. */
12322 psk->ticketAge = age;
12323 psk->hmac = hmac;
12324 psk->cipherSuite0 = cipherSuite0;
12325 psk->cipherSuite = cipherSuite;
12326 psk->resumption = resumption;
12327 psk->binderLen = GetHmacLength(psk->hmac);
12328
12329 if (preSharedKey != NULL)
12330 *preSharedKey = psk;
12331
12332 return 0;
12333}
12334
12335#define PSK_FREE_ALL TLSX_PreSharedKey_FreeAll
12336#define PSK_GET_SIZE TLSX_PreSharedKey_GetSize
12337#define PSK_WRITE TLSX_PreSharedKey_Write
12338#define PSK_PARSE TLSX_PreSharedKey_Parse
12339
12340#else
12341
12342#define PSK_FREE_ALL(a, b) WC_DO_NOTHING
12343#define PSK_GET_SIZE(a, b, c) 0
12344#define PSK_WRITE(a, b, c, d) 0
12345#define PSK_PARSE(a, b, c, d) 0
12346
12347#endif
12348
12349/******************************************************************************/
12350/* Certificate Authentication with External Pre-Shared Key */
12351/******************************************************************************/
12352
12353#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
12354 !defined(NO_PSK)
12355
12356static int TLSX_CertWithExternPsk_GetSize(byte msgType, word16* pSz)
12357{
12358 (void)msgType;
12359 (void)pSz;
12360 /* Zero-length extension - nothing to add. */
12361 return 0;
12362}
12363
12364static int TLSX_CertWithExternPsk_Write(byte* output, byte msgType,
12365 word16* pSz)
12366{
12367 (void)output;
12368 (void)msgType;
12369 (void)pSz;
12370 /* Zero-length extension - nothing to write. */
12371 return 0;
12372}
12373
12374static int TLSX_CertWithExternPsk_Parse(WOLFSSL* ssl, byte msgType)
12375{
12376 if (msgType == client_hello) {
12377 /* Server has not opted in - treat the extension as unknown. */
12378 if (!ssl->options.certWithExternPsk)
12379 return 0;
12380 /* Record that the client offered the extension, leaving resp=0.
12381 * CheckPreSharedKeys() is the sole writer that flips resp to 1, and
12382 * only after confirming that a non-ticket PSK was matched. */
12383 if (TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK) == NULL) {
12384 return TLSX_Push(&ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK,
12385 NULL, ssl->heap);
12386 }
12387 return 0;
12388 }
12389
12390 if (msgType == server_hello) {
12391 if (TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK) == NULL) {
12392 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
12393 return EXT_NOT_ALLOWED;
12394 }
12395 ssl->options.certWithExternPsk = 1;
12396 return 0;
12397 }
12398
12399 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12400 return SANITY_MSG_E;
12401}
12402
12403int TLSX_CertWithExternPsk_Use(WOLFSSL* ssl)
12404{
12405 TLSX* extension = TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK);
12406
12407 if (extension == NULL) {
12408 int ret = TLSX_Push(&ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK, NULL,
12409 ssl->heap);
12410 if (ret != 0)
12411 return ret;
12412 extension = TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK);
12413 if (extension == NULL)
12414 return MEMORY_E;
12415 }
12416 extension->resp = 1;
12417 return 0;
12418}
12419
12420#define PSK_WITH_CERT_GET_SIZE TLSX_CertWithExternPsk_GetSize
12421#define PSK_WITH_CERT_WRITE TLSX_CertWithExternPsk_Write
12422#define PSK_WITH_CERT_PARSE TLSX_CertWithExternPsk_Parse
12423
12424#else
12425
12426#define PSK_WITH_CERT_GET_SIZE(a, b) 0
12427#define PSK_WITH_CERT_WRITE(a, b, c) 0
12428#define PSK_WITH_CERT_PARSE(a, b) 0
12429
12430#endif /* WOLFSSL_TLS13 && WOLFSSL_CERT_WITH_EXTERN_PSK */
12431
12432/******************************************************************************/
12433/* PSK Key Exchange Modes */
12434/******************************************************************************/
12435
12436#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
12437/* Get the size of the encoded PSK KE modes extension.
12438 * Only in ClientHello.
12439 *
12440 * modes The PSK KE mode bit string.
12441 * msgType The type of the message this extension is being written into.
12442 * returns the number of bytes of the encoded PSK KE mode extension.
12443 */
12444static int TLSX_PskKeModes_GetSize(byte modes, byte msgType, word16* pSz)
12445{
12446 if (msgType == client_hello) {
12447 /* Format: Len | Modes* */
12448 word16 len = OPAQUE8_LEN;
12449 /* Check whether each possible mode is to be written. */
12450 if (modes & (1 << PSK_KE))
12451 len += OPAQUE8_LEN;
12452 if (modes & (1 << PSK_DHE_KE))
12453 len += OPAQUE8_LEN;
12454 *pSz += len;
12455 return 0;
12456 }
12457
12458 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12459 return SANITY_MSG_E;
12460}
12461
12462/* Writes the PSK KE modes extension into the output buffer.
12463 * Assumes that the the output buffer is big enough to hold data.
12464 * Only in ClientHello.
12465 *
12466 * modes The PSK KE mode bit string.
12467 * output The buffer to write into.
12468 * msgType The type of the message this extension is being written into.
12469 * returns the number of bytes written into the buffer.
12470 */
12471static int TLSX_PskKeModes_Write(byte modes, byte* output, byte msgType,
12472 word16* pSz)
12473{
12474 if (msgType == client_hello) {
12475 /* Format: Len | Modes* */
12476 word16 idx = OPAQUE8_LEN;
12477
12478 /* Write out each possible mode. */
12479 if (modes & (1 << PSK_KE))
12480 output[idx++] = PSK_KE;
12481 if (modes & (1 << PSK_DHE_KE))
12482 output[idx++] = PSK_DHE_KE;
12483 /* Write out length of mode list. */
12484 output[0] = (byte)(idx - OPAQUE8_LEN);
12485
12486 *pSz += idx;
12487 return 0;
12488 }
12489
12490 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12491 return SANITY_MSG_E;
12492}
12493
12494int TLSX_PskKeyModes_Parse_Modes(const byte* input, word16 length, byte msgType,
12495 byte* modes)
12496{
12497 if (msgType == client_hello) {
12498 /* Format: Len | Modes* */
12499 int idx = 0;
12500 word16 len;
12501 *modes = 0;
12502
12503 /* Ensure length byte exists. */
12504 if (length < OPAQUE8_LEN)
12505 return BUFFER_E;
12506
12507 /* Get length of mode list and ensure that is the only data. */
12508 len = input[0];
12509 if (length - OPAQUE8_LEN != len)
12510 return BUFFER_E;
12511
12512 idx = OPAQUE8_LEN;
12513 /* Set a bit for each recognized modes. */
12514 while (len > 0) {
12515 /* Ignore unrecognized modes. */
12516 if (input[idx] <= PSK_DHE_KE)
12517 *modes |= 1 << input[idx];
12518 idx++;
12519 len--;
12520 }
12521 return 0;
12522 }
12523
12524 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12525 return SANITY_MSG_E;
12526}
12527
12528/* Parse the PSK KE modes extension.
12529 * Only in ClientHello.
12530 *
12531 * ssl The SSL/TLS object.
12532 * input The extension data.
12533 * length The length of the extension data.
12534 * msgType The type of the message this extension is being parsed from.
12535 * returns 0 on success and other values indicate failure.
12536 */
12537static int TLSX_PskKeModes_Parse(WOLFSSL* ssl, const byte* input, word16 length,
12538 byte msgType)
12539{
12540 int ret;
12541 byte modes;
12542
12543 ret = TLSX_PskKeyModes_Parse_Modes(input, length, msgType, &modes);
12544 if (ret == 0)
12545 ret = TLSX_PskKeyModes_Use(ssl, modes);
12546
12547 if (ret != 0) {
12548 WOLFSSL_ERROR_VERBOSE(ret);
12549 }
12550
12551 return ret;
12552}
12553
12554/* Use the data to create a new PSK Key Exchange Modes object in the extensions.
12555 *
12556 * ssl The SSL/TLS object.
12557 * modes The PSK key exchange modes.
12558 * returns 0 on success and other values indicate failure.
12559 */
12560int TLSX_PskKeyModes_Use(WOLFSSL* ssl, byte modes)
12561{
12562 int ret = 0;
12563 TLSX* extension;
12564
12565 /* Find the PSK key exchange modes extension if it exists. */
12566 extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
12567 if (extension == NULL) {
12568 /* Push new PSK key exchange modes extension. */
12569 ret = TLSX_Push(&ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES, NULL,
12570 ssl->heap);
12571 if (ret != 0)
12572 return ret;
12573
12574 extension = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
12575 if (extension == NULL)
12576 return MEMORY_E;
12577 }
12578
12579 extension->val = modes;
12580
12581 return 0;
12582}
12583
12584#define PKM_GET_SIZE TLSX_PskKeModes_GetSize
12585#define PKM_WRITE TLSX_PskKeModes_Write
12586#define PKM_PARSE TLSX_PskKeModes_Parse
12587
12588#else
12589
12590#define PKM_GET_SIZE(a, b, c) 0
12591#define PKM_WRITE(a, b, c, d) 0
12592#define PKM_PARSE(a, b, c, d) 0
12593
12594#endif
12595
12596/******************************************************************************/
12597/* Post-Handshake Authentication */
12598/******************************************************************************/
12599
12600#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
12601/* Get the size of the encoded Post-Handshake Authentication extension.
12602 * Only in ClientHello.
12603 *
12604 * msgType The type of the message this extension is being written into.
12605 * returns the number of bytes of the encoded Post-Handshake Authentication
12606 * extension.
12607 */
12608static int TLSX_PostHandAuth_GetSize(byte msgType, word16* pSz)
12609{
12610 if (msgType == client_hello) {
12611 *pSz += 0;
12612 return 0;
12613 }
12614
12615 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12616 return SANITY_MSG_E;
12617}
12618
12619/* Writes the Post-Handshake Authentication extension into the output buffer.
12620 * Assumes that the the output buffer is big enough to hold data.
12621 * Only in ClientHello.
12622 *
12623 * output The buffer to write into.
12624 * msgType The type of the message this extension is being written into.
12625 * returns the number of bytes written into the buffer.
12626 */
12627static int TLSX_PostHandAuth_Write(byte* output, byte msgType, word16* pSz)
12628{
12629 (void)output;
12630
12631 if (msgType == client_hello) {
12632 *pSz += 0;
12633 return 0;
12634 }
12635
12636 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12637 return SANITY_MSG_E;
12638}
12639
12640/* Parse the Post-Handshake Authentication extension.
12641 * Only in ClientHello.
12642 *
12643 * ssl The SSL/TLS object.
12644 * input The extension data.
12645 * length The length of the extension data.
12646 * msgType The type of the message this extension is being parsed from.
12647 * returns 0 on success and other values indicate failure.
12648 */
12649static int TLSX_PostHandAuth_Parse(WOLFSSL* ssl, const byte* input,
12650 word16 length, byte msgType)
12651{
12652 (void)input;
12653
12654 if (msgType == client_hello) {
12655 /* Ensure extension is empty. */
12656 if (length != 0)
12657 return BUFFER_E;
12658
12659 ssl->options.postHandshakeAuth = 1;
12660 return 0;
12661 }
12662
12663 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12664 return SANITY_MSG_E;
12665}
12666
12667/* Create a new Post-handshake authentication object in the extensions.
12668 *
12669 * ssl The SSL/TLS object.
12670 * returns 0 on success and other values indicate failure.
12671 */
12672static int TLSX_PostHandAuth_Use(WOLFSSL* ssl)
12673{
12674 int ret = 0;
12675 TLSX* extension;
12676
12677 /* Find the PSK key exchange modes extension if it exists. */
12678 extension = TLSX_Find(ssl->extensions, TLSX_POST_HANDSHAKE_AUTH);
12679 if (extension == NULL) {
12680 /* Push new Post-handshake Authentication extension. */
12681 ret = TLSX_Push(&ssl->extensions, TLSX_POST_HANDSHAKE_AUTH, NULL,
12682 ssl->heap);
12683 if (ret != 0)
12684 return ret;
12685 }
12686
12687 return 0;
12688}
12689
12690#define PHA_GET_SIZE TLSX_PostHandAuth_GetSize
12691#define PHA_WRITE TLSX_PostHandAuth_Write
12692#define PHA_PARSE TLSX_PostHandAuth_Parse
12693
12694#else
12695
12696#define PHA_GET_SIZE(a, b) 0
12697#define PHA_WRITE(a, b, c) 0
12698#define PHA_PARSE(a, b, c, d) 0
12699
12700#endif
12701
12702/******************************************************************************/
12703/* Early Data Indication */
12704/******************************************************************************/
12705
12706#ifdef WOLFSSL_EARLY_DATA
12707/* Get the size of the encoded Early Data Indication extension.
12708 * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
12709 *
12710 * msgType The type of the message this extension is being written into.
12711 * returns the number of bytes of the encoded Early Data Indication extension.
12712 */
12713static int TLSX_EarlyData_GetSize(byte msgType, word16* pSz)
12714{
12715 int ret = 0;
12716
12717 if (msgType == client_hello || msgType == encrypted_extensions)
12718 *pSz += 0;
12719 else if (msgType == session_ticket)
12720 *pSz += OPAQUE32_LEN;
12721 else {
12722 ret = SANITY_MSG_E;
12723 WOLFSSL_ERROR_VERBOSE(ret);
12724 }
12725
12726 return ret;
12727}
12728
12729/* Writes the Early Data Indicator extension into the output buffer.
12730 * Assumes that the the output buffer is big enough to hold data.
12731 * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
12732 *
12733 * maxSz The maximum early data size.
12734 * output The buffer to write into.
12735 * msgType The type of the message this extension is being written into.
12736 * returns the number of bytes written into the buffer.
12737 */
12738static int TLSX_EarlyData_Write(word32 maxSz, byte* output, byte msgType,
12739 word16* pSz)
12740{
12741 if (msgType == client_hello || msgType == encrypted_extensions)
12742 return 0;
12743 else if (msgType == session_ticket) {
12744 c32toa(maxSz, output);
12745 *pSz += OPAQUE32_LEN;
12746 return 0;
12747 }
12748
12749 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12750 return SANITY_MSG_E;
12751}
12752
12753/* Parse the Early Data Indicator extension.
12754 * In messages: ClientHello, EncryptedExtensions and NewSessionTicket.
12755 *
12756 * ssl The SSL/TLS object.
12757 * input The extension data.
12758 * length The length of the extension data.
12759 * msgType The type of the message this extension is being parsed from.
12760 * returns 0 on success and other values indicate failure.
12761 */
12762static int TLSX_EarlyData_Parse(WOLFSSL* ssl, const byte* input, word16 length,
12763 byte msgType)
12764{
12765 WOLFSSL_ENTER("TLSX_EarlyData_Parse");
12766 if (msgType == client_hello) {
12767 if (length != 0)
12768 return BUFFER_E;
12769
12770 if (ssl->earlyData == expecting_early_data) {
12771
12772 if (ssl->options.maxEarlyDataSz != 0)
12773 ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_ACCEPTED;
12774 else
12775 ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_REJECTED;
12776
12777 return TLSX_EarlyData_Use(ssl, 0, 0);
12778 }
12779 ssl->earlyData = early_data_ext;
12780
12781 return 0;
12782 }
12783 if (msgType == encrypted_extensions) {
12784 if (length != 0)
12785 return BUFFER_E;
12786
12787 /* Ensure the index of PSK identity chosen by server is 0.
12788 * Index is plus one to handle 'not set' value of 0.
12789 */
12790 if (ssl->options.pskIdIndex != 1) {
12791 WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
12792 return PSK_KEY_ERROR;
12793 }
12794
12795 if (ssl->options.side == WOLFSSL_CLIENT_END) {
12796 /* the extension from server comes in */
12797 ssl->earlyDataStatus = WOLFSSL_EARLY_DATA_ACCEPTED;
12798 }
12799
12800 return TLSX_EarlyData_Use(ssl, 1, 1);
12801 }
12802 if (msgType == session_ticket) {
12803 word32 maxSz;
12804
12805 if (length != OPAQUE32_LEN)
12806 return BUFFER_E;
12807 ato32(input, &maxSz);
12808
12809 ssl->session->maxEarlyDataSz = maxSz;
12810 return 0;
12811 }
12812
12813 WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
12814 return SANITY_MSG_E;
12815}
12816
12817/* Use the data to create a new Early Data object in the extensions.
12818 *
12819 * ssl The SSL/TLS object.
12820 * maxSz The maximum early data size.
12821 * is_response if this extension is part of a response
12822 * returns 0 on success and other values indicate failure.
12823 */
12824int TLSX_EarlyData_Use(WOLFSSL* ssl, word32 maxSz, int is_response)
12825{
12826 int ret = 0;
12827 TLSX* extension;
12828
12829 /* Find the early data extension if it exists. */
12830 extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
12831 if (extension == NULL) {
12832 /* Push new early data extension. */
12833 ret = TLSX_Push(&ssl->extensions, TLSX_EARLY_DATA, NULL, ssl->heap);
12834 if (ret != 0)
12835 return ret;
12836
12837 extension = TLSX_Find(ssl->extensions, TLSX_EARLY_DATA);
12838 if (extension == NULL)
12839 return MEMORY_E;
12840 }
12841
12842 extension->resp = is_response;
12843 /* In QUIC, earlydata size is either 0 or 0xffffffff.
12844 * Override any size between, possibly left from our initial value */
12845 extension->val = (WOLFSSL_IS_QUIC(ssl) && is_response && maxSz > 0) ?
12846 WOLFSSL_MAX_32BIT : maxSz;
12847
12848 return 0;
12849}
12850
12851#define EDI_GET_SIZE TLSX_EarlyData_GetSize
12852#define EDI_WRITE TLSX_EarlyData_Write
12853#define EDI_PARSE TLSX_EarlyData_Parse
12854
12855#else
12856
12857#define EDI_GET_SIZE(a, b) 0
12858#define EDI_WRITE(a, b, c, d) 0
12859#define EDI_PARSE(a, b, c, d) 0
12860
12861#endif
12862
12863/******************************************************************************/
12864/* QUIC transport parameter extension */
12865/******************************************************************************/
12866#ifdef WOLFSSL_QUIC
12867
12868static word16 TLSX_QuicTP_GetSize(TLSX* extension)
12869{
12870 const QuicTransportParam *tp = (QuicTransportParam*)extension->data;
12871
12872 return tp ? tp->len : 0;
12873}
12874
12875int TLSX_QuicTP_Use(WOLFSSL* ssl, TLSX_Type ext_type, int is_response)
12876{
12877 int ret = 0;
12878 TLSX* extension;
12879
12880 WOLFSSL_ENTER("TLSX_QuicTP_Use");
12881 if (ssl->quic.transport_local == NULL) {
12882 /* RFC9000, ch 7.3: "An endpoint MUST treat the absence of [...]
12883 * from either endpoint [...] as a connection error of type
12884 * TRANSPORT_PARAMETER_ERROR."
12885 */
12886 ret = QUIC_TP_MISSING_E;
12887 goto cleanup;
12888 }
12889
12890 extension = TLSX_Find(ssl->extensions, ext_type);
12891 if (extension == NULL) {
12892 ret = TLSX_Push(&ssl->extensions, ext_type, NULL, ssl->heap);
12893 if (ret != 0)
12894 goto cleanup;
12895
12896 extension = TLSX_Find(ssl->extensions, ext_type);
12897 if (extension == NULL) {
12898 ret = MEMORY_E;
12899 goto cleanup;
12900 }
12901 }
12902 if (extension->data) {
12903 QuicTransportParam_free((QuicTransportParam*)extension->data, ssl->heap);
12904 extension->data = NULL;
12905 }
12906 extension->resp = is_response;
12907 extension->data = (void*)QuicTransportParam_dup(ssl->quic.transport_local, ssl->heap);
12908 if (!extension->data) {
12909 ret = MEMORY_E;
12910 goto cleanup;
12911 }
12912
12913cleanup:
12914 WOLFSSL_LEAVE("TLSX_QuicTP_Use", ret);
12915 return ret;
12916}
12917
12918static word16 TLSX_QuicTP_Write(QuicTransportParam *tp, byte* output)
12919{
12920 word16 len = 0;
12921
12922 WOLFSSL_ENTER("TLSX_QuicTP_Write");
12923 if (tp && tp->len) {
12924 XMEMCPY(output, tp->data, tp->len);
12925 len = tp->len;
12926 }
12927 WOLFSSL_LEAVE("TLSX_QuicTP_Write", len);
12928 return len;
12929}
12930
12931static int TLSX_QuicTP_Parse(WOLFSSL *ssl, const byte *input, size_t len, int ext_type, int msgType)
12932{
12933 const QuicTransportParam *tp, **ptp;
12934
12935 (void)msgType;
12936 tp = QuicTransportParam_new(input, len, ssl->heap);
12937 if (!tp) {
12938 return MEMORY_E;
12939 }
12940 ptp = (ext_type == TLSX_KEY_QUIC_TP_PARAMS_DRAFT) ?
12941 &ssl->quic.transport_peer_draft : &ssl->quic.transport_peer;
12942 if (*ptp) {
12943 QTP_FREE(*ptp, ssl->heap);
12944 }
12945 *ptp = tp;
12946 return 0;
12947}
12948
12949#define QTP_GET_SIZE TLSX_QuicTP_GetSize
12950#define QTP_USE TLSX_QuicTP_Use
12951#define QTP_WRITE TLSX_QuicTP_Write
12952#define QTP_PARSE TLSX_QuicTP_Parse
12953
12954#endif /* WOLFSSL_QUIC */
12955
12956#if defined(WOLFSSL_DTLS_CID)
12957#define CID_GET_SIZE TLSX_ConnectionID_GetSize
12958#define CID_WRITE TLSX_ConnectionID_Write
12959#define CID_PARSE TLSX_ConnectionID_Parse
12960#define CID_FREE TLSX_ConnectionID_Free
12961#else
12962#define CID_GET_SIZE(a) 0
12963#define CID_WRITE(a, b) 0
12964#define CID_PARSE(a, b, c, d) 0
12965#define CID_FREE(a, b) 0
12966#endif /* defined(WOLFSSL_DTLS_CID) */
12967
12968#if defined(HAVE_RPK)
12969/******************************************************************************/
12970/* Client_Certificate_Type extension */
12971/******************************************************************************/
12972/* return 1 if specified type is included in the given list, otherwise 0 */
12973static int IsCertTypeListed(byte type, byte cnt, const byte* list)
12974{
12975 int ret = 0;
12976 int i;
12977
12978 if (cnt == 0 || list == NULL)
12979 return ret;
12980
12981 if (cnt > 0 && cnt <= MAX_CLIENT_CERT_TYPE_CNT) {
12982 for (i = 0; i < cnt; i++) {
12983 if (list[i] == type)
12984 return 1;
12985 }
12986 }
12987 return 0;
12988}
12989
12990/* Search both arrays from above to find a common value between the two given
12991 * arrays(a and b). return 1 if it finds a common value, otherwise return 0.
12992 */
12993static int GetCommonItem(const byte* a, byte aLen, const byte* b, byte bLen,
12994 byte* type)
12995{
12996 int i, j;
12997
12998 if (a == NULL || b == NULL)
12999 return 0;
13000
13001 for (i = 0; i < aLen; i++) {
13002 for (j = 0; j < bLen; j++) {
13003 if (a[i] == b[j]) {
13004 *type = a[i];
13005 return 1;
13006 }
13007 }
13008 }
13009 return 0;
13010}
13011
13012/* Creates a "client certificate type" extension if necessary.
13013 * Returns 0 if no error occurred, negative value otherwise.
13014 * A return of 0, it does not indicae that the extension was created.
13015 */
13016static int TLSX_ClientCertificateType_Use(WOLFSSL* ssl, byte isServer)
13017{
13018 int ret = 0;
13019
13020 if (ssl == NULL)
13021 return BAD_FUNC_ARG;
13022
13023 if (isServer) {
13024 /* [in server side]
13025 */
13026
13027 if (IsCertTypeListed(WOLFSSL_CERT_TYPE_RPK,
13028 ssl->options.rpkConfig.preferred_ClientCertTypeCnt,
13029 ssl->options.rpkConfig.preferred_ClientCertTypes)) {
13030
13031 WOLFSSL_MSG("Adding Client Certificate Type extension");
13032 ret = TLSX_Push(&ssl->extensions, TLSX_CLIENT_CERTIFICATE_TYPE, ssl,
13033 ssl->heap);
13034 if (ret == 0) {
13035 TLSX_SetResponse(ssl, TLSX_CLIENT_CERTIFICATE_TYPE);
13036 }
13037 }
13038 }
13039 else {
13040 /* [in client side]
13041 * This extension MUST be omitted from the ClientHello unless the RPK
13042 * certificate is preferred by the user and actually loaded.
13043 */
13044
13045 if (IsCertTypeListed(WOLFSSL_CERT_TYPE_RPK,
13046 ssl->options.rpkConfig.preferred_ClientCertTypeCnt,
13047 ssl->options.rpkConfig.preferred_ClientCertTypes)) {
13048
13049 if (ssl->options.rpkState.isRPKLoaded) {
13050
13051 ssl->options.rpkState.sending_ClientCertTypeCnt = 1;
13052 ssl->options.rpkState.sending_ClientCertTypes[0] =
13053 WOLFSSL_CERT_TYPE_RPK;
13054
13055 /* Push new client_certificate_type extension. */
13056 WOLFSSL_MSG("Adding Client Certificate Type extension");
13057 ret = TLSX_Push(&ssl->extensions, TLSX_CLIENT_CERTIFICATE_TYPE,
13058 ssl, ssl->heap);
13059 }
13060 else {
13061 WOLFSSL_MSG("Willing to use RPK cert but not loaded it");
13062 }
13063 }
13064 else {
13065 WOLFSSL_MSG("No will to use RPK cert");
13066 }
13067 }
13068 return ret;
13069}
13070
13071/* Parse a "client certificate type" extension received from peer.
13072 * returns 0 on success and other values indicate failure.
13073 */
13074static int TLSX_ClientCertificateType_Parse(WOLFSSL* ssl, const byte* input,
13075 word16 length, byte msgType)
13076{
13077 byte typeCnt;
13078 int idx = 0;
13079 int ret = 0;
13080 int i;
13081 int populate = 0;
13082 byte cmnType;
13083
13084
13085 if (msgType == client_hello) {
13086 /* [parse ClientHello in server end]
13087 * case 1) if peer verify is disabled, this extension must be omitted
13088 * from ServerHello.
13089 * case 2) if user have not set his preference, find X509 in parsed
13090 * result, then populate "Client Certificate Type" extension.
13091 * case 3) if user have not set his preference and X509 isn't included
13092 * in parsed result, send "unsupported certificate" alert.
13093 * case 4) if user have set his preference, find a common cert type
13094 * in users preference and received cert types.
13095 * case 5) if user have set his preference, but no common cert type
13096 * found.
13097 */
13098
13099 /* case 1 */
13100 if (ssl->options.verifyNone) {
13101 return ret;
13102 }
13103
13104 /* parse extension */
13105 if (length < OPAQUE8_LEN)
13106 return BUFFER_E;
13107
13108 typeCnt = input[idx];
13109
13110 if (typeCnt > MAX_CLIENT_CERT_TYPE_CNT)
13111 return BUFFER_E;
13112
13113 if ((typeCnt + 1) * OPAQUE8_LEN != length){
13114 return BUFFER_E;
13115 }
13116
13117 ssl->options.rpkState.received_ClientCertTypeCnt = input[idx];
13118 idx += OPAQUE8_LEN;
13119
13120 for (i = 0; i < typeCnt; i++) {
13121 ssl->options.rpkState.received_ClientCertTypes[i] = input[idx];
13122 idx += OPAQUE8_LEN;
13123 }
13124
13125 if (ssl->options.rpkConfig.preferred_ClientCertTypeCnt == 0) {
13126 /* case 2 */
13127 if (IsCertTypeListed(WOLFSSL_CERT_TYPE_X509,
13128 ssl->options.rpkState.received_ClientCertTypeCnt,
13129 ssl->options.rpkState.received_ClientCertTypes)) {
13130
13131 ssl->options.rpkState.sending_ClientCertTypeCnt = 1;
13132 ssl->options.rpkState.sending_ClientCertTypes[0] =
13133 WOLFSSL_CERT_TYPE_X509;
13134 populate = 1;
13135 }
13136 /* case 3 */
13137 else {
13138 WOLFSSL_MSG("No common cert type found in client_certificate_type ext");
13139 SendAlert(ssl, alert_fatal, unsupported_certificate);
13140 return UNSUPPORTED_CERTIFICATE;
13141 }
13142 }
13143 else if (ssl->options.rpkConfig.preferred_ClientCertTypeCnt > 0) {
13144 /* case 4 */
13145 if (GetCommonItem(
13146 ssl->options.rpkConfig.preferred_ClientCertTypes,
13147 ssl->options.rpkConfig.preferred_ClientCertTypeCnt,
13148 ssl->options.rpkState.received_ClientCertTypes,
13149 ssl->options.rpkState.received_ClientCertTypeCnt,
13150 &cmnType)) {
13151 ssl->options.rpkState.sending_ClientCertTypeCnt = 1;
13152 ssl->options.rpkState.sending_ClientCertTypes[0] = cmnType;
13153 populate = 1;
13154 }
13155 /* case 5 */
13156 else {
13157 WOLFSSL_MSG("No common cert type found in client_certificate_type ext");
13158 SendAlert(ssl, alert_fatal, unsupported_certificate);
13159 return UNSUPPORTED_CERTIFICATE;
13160 }
13161 }
13162
13163 /* populate client_certificate_type extension */
13164 if (populate) {
13165 WOLFSSL_MSG("Adding Client Certificate Type extension");
13166 ret = TLSX_Push(&ssl->extensions, TLSX_CLIENT_CERTIFICATE_TYPE, ssl,
13167 ssl->heap);
13168 if (ret == 0) {
13169 TLSX_SetResponse(ssl, TLSX_CLIENT_CERTIFICATE_TYPE);
13170 }
13171 }
13172 }
13173 else if (msgType == server_hello || msgType == encrypted_extensions) {
13174 /* parse it in client side */
13175 if (length == 1) {
13176 ssl->options.rpkState.received_ClientCertTypeCnt = 1;
13177 ssl->options.rpkState.received_ClientCertTypes[0] = *input;
13178 }
13179 else {
13180 return BUFFER_E;
13181 }
13182 }
13183
13184 return ret;
13185}
13186
13187/* Write out the "client certificate type" extension data into the given buffer.
13188 * return the size wrote in the buffer on success, negative value on error.
13189 */
13190static word16 TLSX_ClientCertificateType_Write(void* data, byte* output,
13191 byte msgType)
13192{
13193 WOLFSSL* ssl = (WOLFSSL*)data;
13194 word16 idx = 0;
13195 byte cnt = 0;
13196 int i;
13197
13198 /* skip to write extension if count is zero */
13199 cnt = ssl->options.rpkState.sending_ClientCertTypeCnt;
13200
13201 if (cnt == 0)
13202 return 0;
13203
13204 if (msgType == client_hello) {
13205 /* client side */
13206
13207 *(output + idx) = cnt;
13208 idx += OPAQUE8_LEN;
13209
13210 for (i = 0; i < cnt; i++) {
13211 *(output + idx) = ssl->options.rpkState.sending_ClientCertTypes[i];
13212 idx += OPAQUE8_LEN;
13213 }
13214 return idx;
13215 }
13216 else if (msgType == server_hello || msgType == encrypted_extensions) {
13217 /* sever side */
13218 if (cnt == 1) {
13219 *(output + idx) = ssl->options.rpkState.sending_ClientCertTypes[0];
13220 idx += OPAQUE8_LEN;
13221 }
13222 }
13223 return idx;
13224}
13225
13226/* Calculate then return the size of the "client certificate type" extension
13227 * data.
13228 * return the extension data size on success, negative value on error.
13229*/
13230static int TLSX_ClientCertificateType_GetSize(WOLFSSL* ssl, byte msgType)
13231{
13232 int ret = 0;
13233 byte cnt;
13234
13235 if (ssl == NULL)
13236 return BAD_FUNC_ARG;
13237
13238 if (msgType == client_hello) {
13239 /* client side */
13240 cnt = ssl->options.rpkState.sending_ClientCertTypeCnt;
13241 ret = (int)(OPAQUE8_LEN + cnt * OPAQUE8_LEN);
13242 }
13243 else if (msgType == server_hello || msgType == encrypted_extensions) {
13244 /* server side */
13245 cnt = ssl->options.rpkState.sending_ClientCertTypeCnt;/* must be one */
13246 if (cnt != 1)
13247 return SANITY_MSG_E;
13248 ret = OPAQUE8_LEN;
13249 }
13250 else {
13251 return SANITY_MSG_E;
13252 }
13253 return ret;
13254}
13255
13256 #define CCT_GET_SIZE TLSX_ClientCertificateType_GetSize
13257 #define CCT_WRITE TLSX_ClientCertificateType_Write
13258 #define CCT_PARSE TLSX_ClientCertificateType_Parse
13259#else
13260 #define CCT_GET_SIZE(a) 0
13261 #define CCT_WRITE(a, b) 0
13262 #define CCT_PARSE(a, b, c, d) 0
13263#endif /* HAVE_RPK */
13264
13265#if defined(HAVE_RPK)
13266/******************************************************************************/
13267/* Server_Certificate_Type extension */
13268/******************************************************************************/
13269/* Creates a "server certificate type" extension if necessary.
13270 * Returns 0 if no error occurred, negative value otherwise.
13271 * A return of 0, it does not indicae that the extension was created.
13272 */
13273static int TLSX_ServerCertificateType_Use(WOLFSSL* ssl, byte isServer)
13274{
13275 int ret = 0;
13276 byte ctype;
13277
13278 if (ssl == NULL)
13279 return BAD_FUNC_ARG;
13280
13281 if (isServer) {
13282 /* [in server side] */
13283 /* find common cert type to both end */
13284 if (GetCommonItem(
13285 ssl->options.rpkConfig.preferred_ServerCertTypes,
13286 ssl->options.rpkConfig.preferred_ServerCertTypeCnt,
13287 ssl->options.rpkState.received_ServerCertTypes,
13288 ssl->options.rpkState.received_ServerCertTypeCnt,
13289 &ctype)) {
13290 ssl->options.rpkState.sending_ServerCertTypeCnt = 1;
13291 ssl->options.rpkState.sending_ServerCertTypes[0] = ctype;
13292
13293 /* Push new server_certificate_type extension. */
13294 WOLFSSL_MSG("Adding Server Certificate Type extension");
13295 ret = TLSX_Push(&ssl->extensions, TLSX_SERVER_CERTIFICATE_TYPE, ssl,
13296 ssl->heap);
13297 if (ret == 0) {
13298 TLSX_SetResponse(ssl, TLSX_SERVER_CERTIFICATE_TYPE);
13299 }
13300 }
13301 else {
13302 /* no common cert type found */
13303 WOLFSSL_MSG("No common cert type found in server_certificate_type ext");
13304 SendAlert(ssl, alert_fatal, unsupported_certificate);
13305 ret = UNSUPPORTED_CERTIFICATE;
13306 }
13307 }
13308 else {
13309 /* [in client side] */
13310 if (IsCertTypeListed(WOLFSSL_CERT_TYPE_RPK,
13311 ssl->options.rpkConfig.preferred_ServerCertTypeCnt,
13312 ssl->options.rpkConfig.preferred_ServerCertTypes)) {
13313
13314 ssl->options.rpkState.sending_ServerCertTypeCnt =
13315 ssl->options.rpkConfig.preferred_ServerCertTypeCnt;
13316 XMEMCPY(ssl->options.rpkState.sending_ServerCertTypes,
13317 ssl->options.rpkConfig.preferred_ServerCertTypes,
13318 ssl->options.rpkConfig.preferred_ServerCertTypeCnt);
13319
13320 /* Push new server_certificate_type extension. */
13321 WOLFSSL_MSG("Adding Server Certificate Type extension");
13322 ret = TLSX_Push(&ssl->extensions, TLSX_SERVER_CERTIFICATE_TYPE, ssl,
13323 ssl->heap);
13324 }
13325 else {
13326 WOLFSSL_MSG("No will to accept RPK cert");
13327 }
13328 }
13329
13330 return ret;
13331}
13332
13333/* Parse a "server certificate type" extension received from peer.
13334 * returns 0 on success and other values indicate failure.
13335 */
13336static int TLSX_ServerCertificateType_Parse(WOLFSSL* ssl, const byte* input,
13337 word16 length, byte msgType)
13338{
13339 byte typeCnt;
13340 int idx = 0;
13341 int ret = 0;
13342 int i;
13343
13344 if (msgType == client_hello) {
13345 /* in server side */
13346
13347 if (length < OPAQUE8_LEN)
13348 return BUFFER_E;
13349
13350 typeCnt = input[idx];
13351
13352 if (typeCnt > MAX_SERVER_CERT_TYPE_CNT)
13353 return BUFFER_E;
13354
13355 if ((typeCnt + 1) * OPAQUE8_LEN != length){
13356 return BUFFER_E;
13357 }
13358 ssl->options.rpkState.received_ServerCertTypeCnt = input[idx];
13359 idx += OPAQUE8_LEN;
13360
13361 for (i = 0; i < typeCnt; i++) {
13362 ssl->options.rpkState.received_ServerCertTypes[i] = input[idx];
13363 idx += OPAQUE8_LEN;
13364 }
13365
13366 ret = TLSX_ServerCertificateType_Use(ssl, 1);
13367 if (ret == 0) {
13368 TLSX_SetResponse(ssl, TLSX_SERVER_CERTIFICATE_TYPE);
13369 }
13370 }
13371 else if (msgType == server_hello || msgType == encrypted_extensions) {
13372 /* in client side */
13373 if (length != 1) /* length slould be 1 */
13374 return BUFFER_E;
13375
13376 ssl->options.rpkState.received_ServerCertTypeCnt = 1;
13377 ssl->options.rpkState.received_ServerCertTypes[0] = *input;
13378 }
13379
13380 return 0;
13381}
13382
13383/* Write out the "server certificate type" extension data into the given buffer.
13384 * return the size wrote in the buffer on success, negative value on error.
13385 */
13386static word16 TLSX_ServerCertificateType_Write(void* data, byte* output,
13387 byte msgType)
13388{
13389 WOLFSSL* ssl = (WOLFSSL*)data;
13390 word16 idx = 0;
13391 int cnt = 0;
13392 int i;
13393
13394 /* skip to write extension if count is zero */
13395 cnt = ssl->options.rpkState.sending_ServerCertTypeCnt;
13396
13397 if (cnt == 0)
13398 return 0;
13399
13400 if (msgType == client_hello) {
13401 /* in client side */
13402
13403 *(output + idx) = cnt;
13404 idx += OPAQUE8_LEN;
13405
13406 for (i = 0; i < cnt; i++) {
13407 *(output + idx) = ssl->options.rpkState.sending_ServerCertTypes[i];
13408 idx += OPAQUE8_LEN;
13409 }
13410 }
13411 else if (msgType == server_hello || msgType == encrypted_extensions) {
13412 /* in server side */
13413 /* ensure cnt is one */
13414 if (cnt != 1)
13415 return 0;
13416
13417 *(output + idx) = ssl->options.rpkState.sending_ServerCertTypes[0];
13418 idx += OPAQUE8_LEN;
13419 }
13420 return idx;
13421}
13422
13423/* Calculate then return the size of the "server certificate type" extension
13424 * data.
13425 * return the extension data size on success, negative value on error.
13426*/
13427static int TLSX_ServerCertificateType_GetSize(WOLFSSL* ssl, byte msgType)
13428{
13429 int ret = 0;
13430 int cnt;
13431
13432 if (ssl == NULL)
13433 return BAD_FUNC_ARG;
13434
13435 if (msgType == client_hello) {
13436 /* in clent side */
13437 cnt = ssl->options.rpkState.sending_ServerCertTypeCnt;
13438 if (cnt > 0) {
13439 ret = (int)(OPAQUE8_LEN + cnt * OPAQUE8_LEN);
13440 }
13441 }
13442 else if (msgType == server_hello || msgType == encrypted_extensions) {
13443 /* in server side */
13444 ret = (int)OPAQUE8_LEN;
13445 }
13446 else {
13447 return SANITY_MSG_E;
13448 }
13449 return ret;
13450}
13451
13452 #define SCT_GET_SIZE TLSX_ServerCertificateType_GetSize
13453 #define SCT_WRITE TLSX_ServerCertificateType_Write
13454 #define SCT_PARSE TLSX_ServerCertificateType_Parse
13455#else
13456 #define SCT_GET_SIZE(a) 0
13457 #define SCT_WRITE(a, b) 0
13458 #define SCT_PARSE(a, b, c, d) 0
13459#endif /* HAVE_RPK */
13460
13461/******************************************************************************/
13462/* TLS Extensions Framework */
13463/******************************************************************************/
13464
13465/** Finds an extension in the provided list. */
13466TLSX* TLSX_Find(TLSX* list, TLSX_Type type)
13467{
13468 TLSX* extension = list;
13469
13470 while (extension && extension->type != type)
13471 extension = extension->next;
13472
13473 return extension;
13474}
13475
13476/** Remove an extension. */
13477void TLSX_Remove(TLSX** list, TLSX_Type type, void* heap)
13478{
13479 TLSX* extension;
13480 TLSX** next;
13481
13482 if (list == NULL)
13483 return;
13484
13485 extension = *list;
13486 next = list;
13487
13488 while (extension && extension->type != type) {
13489 next = &extension->next;
13490 extension = extension->next;
13491 }
13492
13493 if (extension) {
13494 *next = extension->next;
13495 extension->next = NULL;
13496 TLSX_FreeAll(extension, heap);
13497 }
13498}
13499
13500#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
13501#define GREASE_ECH_SIZE 160
13502#define TLS_INFO_CONST_STRING "tls ech"
13503#define TLS_INFO_CONST_STRING_SZ 7
13504
13505/* return status after setting up ech to write a grease ech */
13506static int TLSX_GreaseECH_Use(TLSX** extensions, void* heap, WC_RNG* rng)
13507{
13508 int ret = 0;
13509 WOLFSSL_ECH* ech;
13510
13511 if (extensions == NULL)
13512 return BAD_FUNC_ARG;
13513
13514 ech = (WOLFSSL_ECH*)XMALLOC(sizeof(WOLFSSL_ECH), heap,
13515 DYNAMIC_TYPE_TMP_BUFFER);
13516
13517 if (ech == NULL)
13518 return MEMORY_E;
13519
13520 ForceZero(ech, sizeof(WOLFSSL_ECH));
13521
13522 ech->state = ECH_WRITE_GREASE;
13523
13524 /* 0 for outer */
13525 ech->type = ECH_TYPE_OUTER;
13526 /* kemId */
13527 ech->kemId = DHKEM_X25519_HKDF_SHA256;
13528 /* cipherSuite kdf */
13529 ech->cipherSuite.kdfId = HKDF_SHA256;
13530 /* cipherSuite aead */
13531 ech->cipherSuite.aeadId = HPKE_AES_128_GCM;
13532
13533 /* random configId */
13534 ret = wc_RNG_GenerateByte(rng, &(ech->configId));
13535
13536 /* curve25519 encLen */
13537 ech->encLen = DHKEM_X25519_ENC_LEN;
13538
13539 if (ret == 0)
13540 ret = TLSX_Push(extensions, TLSX_ECH, ech, heap);
13541
13542 if (ret != 0) {
13543 XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
13544 }
13545
13546 return ret;
13547}
13548
13549/* return status after setting up ech to write real ech */
13550static int TLSX_ECH_Use(WOLFSSL_EchConfig* echConfig, TLSX** extensions,
13551 void* heap, WC_RNG* rng)
13552{
13553 int ret = 0;
13554 int suiteIndex;
13555 TLSX* echX;
13556 WOLFSSL_ECH* ech;
13557 if (extensions == NULL)
13558 return BAD_FUNC_ARG;
13559 /* skip if we already have an ech extension, we will for hrr */
13560 echX = TLSX_Find(*extensions, TLSX_ECH);
13561 if (echX != NULL)
13562 return 0;
13563 /* find a supported cipher suite */
13564 suiteIndex = EchConfigGetSupportedCipherSuite(echConfig);
13565 if (suiteIndex < 0)
13566 return suiteIndex;
13567 ech = (WOLFSSL_ECH*)XMALLOC(sizeof(WOLFSSL_ECH), heap,
13568 DYNAMIC_TYPE_TMP_BUFFER);
13569 if (ech == NULL)
13570 return MEMORY_E;
13571 ForceZero(ech, sizeof(WOLFSSL_ECH));
13572 ech->state = ECH_WRITE_REAL;
13573 ech->echConfig = echConfig;
13574 /* 0 for outer */
13575 ech->type = ECH_TYPE_OUTER;
13576 /* kemId */
13577 ech->kemId = echConfig->kemId;
13578 /* cipherSuite kdf */
13579 ech->cipherSuite.kdfId = echConfig->cipherSuites[suiteIndex].kdfId;
13580 /* cipherSuite aead */
13581 ech->cipherSuite.aeadId = echConfig->cipherSuites[suiteIndex].aeadId;
13582 /* configId */
13583 ech->configId = echConfig->configId;
13584 /* encLen */
13585 ech->encLen = wc_HpkeKemGetEncLen(echConfig->kemId);
13586 if (ech->encLen == 0) {
13587 XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
13588 return BAD_FUNC_ARG;
13589 }
13590 /* setup hpke */
13591 ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER);
13592 if (ech->hpke == NULL) {
13593 XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
13594 return MEMORY_E;
13595 }
13596 ret = wc_HpkeInit(ech->hpke, ech->kemId, ech->cipherSuite.kdfId,
13597 ech->cipherSuite.aeadId, heap);
13598 /* setup the ephemeralKey */
13599 if (ret == 0)
13600 ret = wc_HpkeGenerateKeyPair(ech->hpke, &ech->ephemeralKey, rng);
13601 if (ret == 0) {
13602 ret = TLSX_Push(extensions, TLSX_ECH, ech, heap);
13603 if (ret != 0) {
13604 wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, ech->ephemeralKey,
13605 ech->hpke->heap);
13606 }
13607 }
13608 if (ret != 0) {
13609 XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
13610 XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
13611 }
13612 return ret;
13613}
13614
13615/* return status after setting up ech to read and decrypt */
13616static int TLSX_ServerECH_Use(TLSX** extensions, void* heap,
13617 WOLFSSL_EchConfig* configs)
13618{
13619 int ret;
13620 WOLFSSL_ECH* ech;
13621 TLSX* echX;
13622 if (extensions == NULL)
13623 return BAD_FUNC_ARG;
13624 /* if we already have ech don't override it */
13625 echX = TLSX_Find(*extensions, TLSX_ECH);
13626 if (echX != NULL)
13627 return 0;
13628 ech = (WOLFSSL_ECH*)XMALLOC(sizeof(WOLFSSL_ECH), heap,
13629 DYNAMIC_TYPE_TMP_BUFFER);
13630 if (ech == NULL)
13631 return MEMORY_E;
13632 ForceZero(ech, sizeof(WOLFSSL_ECH));
13633 ech->state = ECH_WRITE_NONE;
13634 /* 0 for outer */
13635 ech->type = ECH_TYPE_OUTER;
13636 ech->echConfig = configs;
13637 /* setup the rest of the settings when we receive ech from the client */
13638 ret = TLSX_Push(extensions, TLSX_ECH, ech, heap);
13639 if (ret != 0)
13640 XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
13641 return ret;
13642}
13643
13644/* return status after writing the ech and updating offset */
13645static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte msgType, byte* writeBuf,
13646 word16* offset)
13647{
13648 int ret = 0;
13649 int rngRet = -1;
13650 word32 configsLen = 0;
13651 void* ephemeralKey = NULL;
13652 byte* writeBuf_p = writeBuf;
13653 WC_DECLARE_VAR(hpke, Hpke, 1, DYNAMIC_TYPE_TMP_BUFFER);
13654 WC_DECLARE_VAR(rng, WC_RNG, 1, DYNAMIC_TYPE_RNG);
13655
13656 WOLFSSL_MSG("TLSX_ECH_Write");
13657 if (msgType == hello_retry_request) {
13658 WC_ALLOC_VAR_EX(rng, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG, ret = MEMORY_E);
13659 if (ret == 0) {
13660 ret = wc_InitRng(rng);
13661 }
13662 if (ret == 0) {
13663 /* randomize confirmation in case ech is rejected */
13664 ret = wc_RNG_GenerateBlock(rng, writeBuf,
13665 ECH_ACCEPT_CONFIRMATION_SZ);
13666 wc_FreeRng(rng);
13667 }
13668 if (ret == 0) {
13669 *offset += ECH_ACCEPT_CONFIRMATION_SZ;
13670 ech->confBuf = writeBuf;
13671 }
13672
13673 WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
13674 return ret;
13675 }
13676 if (ech->state == ECH_WRITE_NONE || ech->state == ECH_PARSED_INTERNAL)
13677 return 0;
13678 if (ech->state == ECH_WRITE_RETRY_CONFIGS) {
13679 /* get size then write */
13680 ret = GetEchConfigsEx(ech->echConfig, NULL, &configsLen);
13681 if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
13682 return ret;
13683 ret = GetEchConfigsEx(ech->echConfig, writeBuf, &configsLen);
13684 if (ret != WOLFSSL_SUCCESS)
13685 return ret;
13686 *offset += configsLen;
13687 return 0;
13688 }
13689 /* type */
13690 *writeBuf_p = ech->type;
13691 writeBuf_p += sizeof(ech->type);
13692 /* outer has body, inner does not */
13693 if (ech->type == ECH_TYPE_OUTER) {
13694 /* kdfId */
13695 c16toa(ech->cipherSuite.kdfId, writeBuf_p);
13696 writeBuf_p += sizeof(ech->cipherSuite.kdfId);
13697 /* aeadId */
13698 c16toa(ech->cipherSuite.aeadId, writeBuf_p);
13699 writeBuf_p += sizeof(ech->cipherSuite.aeadId);
13700 /* configId */
13701 *writeBuf_p = ech->configId;
13702 writeBuf_p += sizeof(ech->configId);
13703 /* encLen */
13704 if (ech->hpkeContext == NULL) {
13705 c16toa(ech->encLen, writeBuf_p);
13706 }
13707 else {
13708 /* set to 0 if this is clientInner 2 */
13709 c16toa(0, writeBuf_p);
13710 }
13711 writeBuf_p += 2;
13712 if (ech->state == ECH_WRITE_GREASE) {
13713 WC_ALLOC_VAR_EX(hpke, Hpke, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, ret = MEMORY_E);
13714 WC_ALLOC_VAR_EX(rng, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG, ret = MEMORY_E);
13715 /* hpke init */
13716 if (ret == 0) {
13717 ret = wc_HpkeInit(hpke, ech->kemId, ech->cipherSuite.kdfId,
13718 ech->cipherSuite.aeadId, NULL);
13719 }
13720 if (ret == 0)
13721 rngRet = ret = wc_InitRng(rng);
13722 /* create the ephemeralKey */
13723 if (ret == 0)
13724 ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng);
13725 /* enc */
13726 if (ret == 0) {
13727 ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, writeBuf_p,
13728 &ech->encLen);
13729 writeBuf_p += ech->encLen;
13730 }
13731 if (ret == 0) {
13732 /* innerClientHelloLen */
13733 c16toa(GREASE_ECH_SIZE + ((writeBuf_p + 2 - writeBuf) % 32),
13734 writeBuf_p);
13735 writeBuf_p += 2;
13736
13737 /* innerClientHello */
13738 ret = wc_RNG_GenerateBlock(rng, writeBuf_p, GREASE_ECH_SIZE +
13739 ((writeBuf_p - writeBuf) % 32));
13740 writeBuf_p += GREASE_ECH_SIZE + ((writeBuf_p - writeBuf) % 32);
13741 }
13742 if (rngRet == 0)
13743 wc_FreeRng(rng);
13744 if (ephemeralKey != NULL)
13745 wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, hpke->heap);
13746 WC_FREE_VAR_EX(hpke, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13747 WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
13748 }
13749 else {
13750 /* only write enc if this is our first ech, no hpke context */
13751 if (ech->hpkeContext == NULL) {
13752 /* write enc to writeBuf_p */
13753 ret = wc_HpkeSerializePublicKey(ech->hpke, ech->ephemeralKey,
13754 writeBuf_p, &ech->encLen);
13755 writeBuf_p += ech->encLen;
13756 }
13757 /* innerClientHelloLen */
13758 c16toa((word16)ech->innerClientHelloLen, writeBuf_p);
13759 writeBuf_p += 2;
13760 /* set payload offset for when we finalize */
13761 ech->outerClientPayload = writeBuf_p;
13762 /* write zeros for payload */
13763 XMEMSET(writeBuf_p, 0, ech->innerClientHelloLen);
13764 writeBuf_p += ech->innerClientHelloLen;
13765 }
13766 }
13767 if (ret == 0)
13768 *offset += (writeBuf_p - writeBuf);
13769 return ret;
13770}
13771
13772/* return the size needed for the ech extension */
13773static int TLSX_ECH_GetSize(WOLFSSL_ECH* ech, byte msgType)
13774{
13775 int ret;
13776 word32 size = 0;
13777
13778 if (ech->state == ECH_WRITE_GREASE) {
13779 size = sizeof(ech->type) + sizeof(ech->cipherSuite) +
13780 sizeof(ech->configId) + sizeof(word16) + ech->encLen +
13781 sizeof(word16);
13782
13783 size += GREASE_ECH_SIZE + (size % 32);
13784 }
13785 else if (msgType == hello_retry_request) {
13786 size = ECH_ACCEPT_CONFIRMATION_SZ;
13787 }
13788 else if (ech->state == ECH_WRITE_NONE ||
13789 ech->state == ECH_PARSED_INTERNAL) {
13790 size = 0;
13791 }
13792 else if (ech->state == ECH_WRITE_RETRY_CONFIGS) {
13793 /* get the size of the raw configs */
13794 ret = GetEchConfigsEx(ech->echConfig, NULL, &size);
13795
13796 if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
13797 return ret;
13798 }
13799 else if (ech->type == ECH_TYPE_INNER)
13800 {
13801 size = sizeof(ech->type);
13802 }
13803 else
13804 {
13805 size = sizeof(ech->type) + sizeof(ech->cipherSuite) +
13806 sizeof(ech->configId) + sizeof(word16) + sizeof(word16) +
13807 ech->innerClientHelloLen;
13808 /* only set encLen if this is inner hello 1 */
13809 if (ech->hpkeContext == NULL)
13810 size += ech->encLen;
13811 }
13812
13813 return (int)size;
13814}
13815
13816/* rough check that inner hello fields do not exceed length of decrypted
13817 * information. Additionally, this function will check that all padding bytes
13818 * are zero and decrease the innerHelloLen accordingly if so.
13819 * returns 0 on success and otherwise failure */
13820static int TLSX_ECH_CheckInnerPadding(WOLFSSL* ssl, WOLFSSL_ECH* ech)
13821{
13822 int headerSz;
13823 const byte* innerCh;
13824 word32 innerChLen;
13825 word32 idx;
13826 byte sessionIdLen;
13827 word16 cipherSuitesLen;
13828 byte compressionLen;
13829 word16 extLen;
13830 byte acc = 0;
13831 word32 i;
13832
13833#ifdef WOLFSSL_DTLS13
13834 headerSz = ssl->options.dtls ? DTLS13_HANDSHAKE_HEADER_SZ :
13835 HANDSHAKE_HEADER_SZ;
13836#else
13837 (void)ssl;
13838
13839 headerSz = HANDSHAKE_HEADER_SZ;
13840#endif
13841
13842 innerCh = ech->innerClientHello + headerSz;
13843 innerChLen = ech->innerClientHelloLen;
13844
13845 idx = OPAQUE16_LEN + RAN_LEN;
13846 if (idx >= innerChLen)
13847 return BUFFER_ERROR;
13848
13849 sessionIdLen = innerCh[idx++];
13850 /* innerHello sessionID must initially be empty */
13851 if (sessionIdLen != 0)
13852 return INVALID_PARAMETER;
13853 idx += sessionIdLen;
13854 if (idx + OPAQUE16_LEN > innerChLen)
13855 return BUFFER_ERROR;
13856
13857 ato16(innerCh + idx, &cipherSuitesLen);
13858 idx += OPAQUE16_LEN + cipherSuitesLen;
13859 if (idx >= innerChLen)
13860 return BUFFER_ERROR;
13861
13862 compressionLen = innerCh[idx++];
13863 idx += compressionLen;
13864 if (idx + OPAQUE16_LEN > innerChLen)
13865 return BUFFER_ERROR;
13866
13867 ato16(innerCh + idx, &extLen);
13868 idx += OPAQUE16_LEN + extLen;
13869 if (idx > innerChLen)
13870 return BUFFER_ERROR;
13871
13872 /* should now be at the end of the innerHello
13873 * Per ECH spec all padding bytes MUST be 0 */
13874 for (i = idx; i < innerChLen; i++) {
13875 acc |= innerCh[i];
13876 }
13877 if (acc != 0) {
13878 return INVALID_PARAMETER;
13879 }
13880
13881 ech->innerClientHelloLen -= i - idx;
13882 return 0;
13883}
13884
13885/* Locate the given extension type, use the extOffset to start off after where a
13886 * previous call to this function ended
13887 *
13888 * outerCh The outer ClientHello buffer.
13889 * chLen Outer ClientHello length.
13890 * extType Extension type to look for.
13891 * extLen Out parameter, length of found extension.
13892 * extOffset Offset into outer ClientHello to look for extension from.
13893 * extensionsStart Start of outer ClientHello extensions.
13894 * extensionsLen Length of outer ClientHello extensions.
13895 * returns 0 on success and otherwise failure.
13896 */
13897static const byte* TLSX_ECH_FindOuterExtension(const byte* outerCh,
13898 word32 chLen, word16 extType, word32* extLen, word32* extOffset,
13899 word16* extensionsStart, word16* extensionsLen)
13900{
13901 word32 idx = *extOffset;
13902 byte sessionIdLen;
13903 word16 cipherSuitesLen;
13904 byte compressionLen;
13905 word16 type;
13906 word16 len;
13907
13908 if (idx == 0) {
13909 idx = OPAQUE16_LEN + RAN_LEN;
13910 if (idx >= chLen)
13911 return NULL;
13912
13913 sessionIdLen = outerCh[idx++];
13914 idx += sessionIdLen;
13915 if (idx + OPAQUE16_LEN > chLen)
13916 return NULL;
13917
13918 ato16(outerCh + idx, &cipherSuitesLen);
13919 idx += OPAQUE16_LEN + cipherSuitesLen;
13920 if (idx >= chLen)
13921 return NULL;
13922
13923 compressionLen = outerCh[idx++];
13924 idx += compressionLen;
13925 if (idx + OPAQUE16_LEN > chLen)
13926 return NULL;
13927
13928 ato16(outerCh + idx, extensionsLen);
13929 idx += OPAQUE16_LEN;
13930 *extensionsStart = (word16)idx;
13931
13932 if (idx + *extensionsLen > chLen)
13933 return NULL;
13934 }
13935
13936 while (idx - *extensionsStart < *extensionsLen) {
13937 if (idx + OPAQUE16_LEN + OPAQUE16_LEN > chLen)
13938 return NULL;
13939
13940 ato16(outerCh + idx, &type);
13941 idx += OPAQUE16_LEN;
13942 ato16(outerCh + idx, &len);
13943 idx += OPAQUE16_LEN;
13944
13945 if (idx + len - *extensionsStart > *extensionsLen)
13946 return NULL;
13947
13948 if (type == extType) {
13949 *extLen = len + OPAQUE16_LEN + OPAQUE16_LEN;
13950 *extOffset = idx + len;
13951 return outerCh + idx - OPAQUE16_LEN - OPAQUE16_LEN;
13952 }
13953
13954 idx += len;
13955 }
13956
13957 return NULL;
13958}
13959
13960/* If newinnerCh is NULL, validate ordering and existence of references
13961 * - updates newInnerChLen with total length of selected extensions
13962 * If newinnerCh is not NULL, copy extensions into newInnerCh
13963 *
13964 * outerCh The outer ClientHello buffer.
13965 * outerChLen Outer ClientHello length.
13966 * newInnerCh The inner ClientHello buffer.
13967 * newInnerChLen Inner ClientHello length.
13968 * numOuterRefs Number of references described by OuterExtensions extension.
13969 * OuterRefTypes References described by OuterExtensions extension.
13970 * returns 0 on success and otherwise failure.
13971 */
13972static int TLSX_ECH_CopyOuterExtensions(const byte* outerCh, word32 outerChLen,
13973 byte** newInnerCh, word32* newInnerChLen,
13974 word16 numOuterRefs, const byte* outerRefTypes)
13975{
13976 int ret = 0;
13977 word16 refType;
13978 word32 outerExtLen;
13979 word32 outerExtOffset = 0;
13980 word16 extsStart = 0;
13981 word16 extsLen = 0;
13982 const byte* outerExtData;
13983
13984 if (newInnerCh == NULL) {
13985 *newInnerChLen = 0;
13986 }
13987
13988 while (numOuterRefs-- > 0) {
13989 ato16(outerRefTypes, &refType);
13990
13991 if (refType == TLSXT_ECH) {
13992 WOLFSSL_MSG("ECH: ech_outer_extensions references ECH");
13993 ret = INVALID_PARAMETER;
13994 break;
13995 }
13996
13997 outerExtData = TLSX_ECH_FindOuterExtension(outerCh, outerChLen,
13998 refType, &outerExtLen, &outerExtOffset,
13999 &extsStart, &extsLen);
14000
14001 if (outerExtData == NULL) {
14002 WOLFSSL_MSG("ECH: referenced extension not in outer CH or out "
14003 "of order");
14004 ret = INVALID_PARAMETER;
14005 break;
14006 }
14007
14008 if (newInnerCh == NULL) {
14009 *newInnerChLen += outerExtLen;
14010 }
14011 else {
14012 XMEMCPY(*newInnerCh, outerExtData, outerExtLen);
14013 *newInnerCh += outerExtLen;
14014 }
14015
14016 outerRefTypes += OPAQUE16_LEN;
14017 }
14018
14019 return ret;
14020}
14021
14022/* Expand ech_outer_extensions in the inner ClientHello by copying referenced
14023 * extensions from the outer ClientHello.
14024 * If the sessionID exists in the outer ClientHello then also copy that into the
14025 * expanded inner ClientHello.
14026 *
14027 * ssl SSL/TLS object.
14028 * ech ECH object.
14029 * heap Heap hint.
14030 * returns 0 on success and otherwise failure.
14031 */
14032static int TLSX_ECH_ExpandOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech,
14033 void* heap)
14034{
14035 int ret = 0;
14036 int headerSz;
14037 const byte* innerCh;
14038 word32 innerChLen;
14039 const byte* outerCh;
14040 word32 outerChLen;
14041 word32 idx;
14042 byte sessionIdLen;
14043 word16 cipherSuitesLen;
14044 byte compressionLen;
14045
14046 word32 innerExtIdx;
14047 word16 innerExtLen;
14048 word32 echOuterExtIdx = 0;
14049 word16 echOuterExtLen = 0;
14050 int foundEchOuter = 0;
14051 word16 numOuterRefs = 0;
14052 const byte* outerRefTypes = NULL;
14053 word32 extraSize = 0;
14054 byte* newInnerCh = NULL;
14055 byte* newInnerChRef;
14056 word32 newInnerChLen;
14057 word32 copyLen;
14058
14059 WOLFSSL_ENTER("TLSX_ExpandEchOuterExtensions");
14060
14061 if (ech == NULL || ech->innerClientHello == NULL || ech->aad == NULL)
14062 return BAD_FUNC_ARG;
14063
14064#ifdef WOLFSSL_DTLS13
14065 headerSz = ssl->options.dtls ? DTLS13_HANDSHAKE_HEADER_SZ :
14066 HANDSHAKE_HEADER_SZ;
14067#else
14068 headerSz = HANDSHAKE_HEADER_SZ;
14069#endif
14070
14071 innerCh = ech->innerClientHello + headerSz;
14072 innerChLen = ech->innerClientHelloLen;
14073 outerCh = ech->aad;
14074 outerChLen = ech->aadLen;
14075
14076 /* don't need to check for buffer overflows here since they are caught by
14077 * TLSX_ECH_CheckInnerPadding */
14078 idx = OPAQUE16_LEN + RAN_LEN;
14079
14080 sessionIdLen = innerCh[idx++];
14081 idx += sessionIdLen;
14082
14083 ato16(innerCh + idx, &cipherSuitesLen);
14084 idx += OPAQUE16_LEN + cipherSuitesLen;
14085
14086 compressionLen = innerCh[idx++];
14087 idx += compressionLen;
14088
14089 ato16(innerCh + idx, &innerExtLen);
14090 idx += OPAQUE16_LEN;
14091 innerExtIdx = idx;
14092
14093 /* validate ech_outer_extensions and calculate extra size */
14094 while (idx < innerChLen && (idx - innerExtIdx) < innerExtLen) {
14095 word16 type;
14096 word16 len;
14097 byte outerExtListLen;
14098
14099 if (idx + OPAQUE16_LEN + OPAQUE16_LEN > innerChLen)
14100 return BUFFER_ERROR;
14101
14102 ato16(innerCh + idx, &type);
14103 idx += OPAQUE16_LEN;
14104 ato16(innerCh + idx, &len);
14105 idx += OPAQUE16_LEN;
14106
14107 if (idx + len > innerChLen)
14108 return BUFFER_ERROR;
14109
14110 if (type == TLSXT_ECH_OUTER_EXTENSIONS) {
14111 if (foundEchOuter) {
14112 WOLFSSL_MSG("ECH: duplicate ech_outer_extensions");
14113 return INVALID_PARAMETER;
14114 }
14115 foundEchOuter = 1;
14116 echOuterExtIdx = idx - OPAQUE16_LEN - OPAQUE16_LEN;
14117 echOuterExtLen = len + OPAQUE16_LEN + OPAQUE16_LEN;
14118
14119 /* ech_outer_extensions data format: 1-byte length + extension types
14120 * ExtensionType OuterExtensions<2..254>; */
14121 if (len < 1)
14122 return BUFFER_ERROR;
14123 outerExtListLen = innerCh[idx];
14124 if (outerExtListLen + 1 != len || outerExtListLen < 2 ||
14125 outerExtListLen == 255)
14126 return BUFFER_ERROR;
14127
14128 outerRefTypes = innerCh + idx + 1;
14129 numOuterRefs = outerExtListLen / OPAQUE16_LEN;
14130
14131 ret = TLSX_ECH_CopyOuterExtensions(outerCh, outerChLen, NULL,
14132 &extraSize, numOuterRefs, outerRefTypes);
14133 if (ret != 0)
14134 return ret;
14135 }
14136
14137 idx += len;
14138 }
14139
14140 newInnerChLen = innerChLen - echOuterExtLen + extraSize - sessionIdLen +
14141 ssl->session->sessionIDSz;
14142 if (newInnerChLen > 0xFFFF) {
14143 return BUFFER_E;
14144 }
14145
14146 if (!foundEchOuter && sessionIdLen == ssl->session->sessionIDSz) {
14147 /* no extensions + no sessionID to copy */
14148 WOLFSSL_MSG("ECH: no EchOuterExtensions extension found");
14149 return ret;
14150 }
14151 else {
14152 newInnerCh = (byte*)XMALLOC(newInnerChLen + headerSz, heap,
14153 DYNAMIC_TYPE_TMP_BUFFER);
14154 if (newInnerCh == NULL)
14155 return MEMORY_E;
14156 }
14157
14158 /* note: The first HANDSHAKE_HEADER_SZ bytes are reserved for the header
14159 * but not initialized here. The header will be properly set later by
14160 * AddTls13HandShakeHeader() in DoTls13ClientHello(). */
14161
14162 /* copy everything up to EchOuterExtensions */
14163 newInnerChRef = newInnerCh + headerSz;
14164 copyLen = OPAQUE16_LEN + RAN_LEN;
14165 XMEMCPY(newInnerChRef, innerCh, copyLen);
14166 newInnerChRef += copyLen;
14167
14168 *newInnerChRef = ssl->session->sessionIDSz;
14169 newInnerChRef += OPAQUE8_LEN;
14170
14171 copyLen = ssl->session->sessionIDSz;
14172 XMEMCPY(newInnerChRef, ssl->session->sessionID, copyLen);
14173 newInnerChRef += copyLen;
14174
14175 if (!foundEchOuter) {
14176 WOLFSSL_MSG("ECH: no EchOuterExtensions extension found");
14177
14178 copyLen = innerChLen - OPAQUE16_LEN - RAN_LEN - OPAQUE8_LEN -
14179 sessionIdLen;
14180 XMEMCPY(newInnerChRef, innerCh + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN +
14181 sessionIdLen, copyLen);
14182 }
14183 else {
14184 innerExtIdx = headerSz + innerExtIdx - OPAQUE16_LEN -
14185 sessionIdLen + ssl->session->sessionIDSz;
14186
14187 copyLen = echOuterExtIdx - OPAQUE16_LEN - RAN_LEN - OPAQUE8_LEN -
14188 sessionIdLen;
14189 XMEMCPY(newInnerChRef, innerCh + OPAQUE16_LEN + RAN_LEN + OPAQUE8_LEN +
14190 sessionIdLen, copyLen);
14191 newInnerChRef += copyLen;
14192
14193 /* update extensions length in the new ClientHello */
14194 c16toa(innerExtLen - echOuterExtLen + (word16)extraSize,
14195 newInnerCh + innerExtIdx);
14196
14197 ret = TLSX_ECH_CopyOuterExtensions(outerCh, outerChLen, &newInnerChRef,
14198 &newInnerChLen, numOuterRefs, outerRefTypes);
14199 if (ret == 0) {
14200 /* copy remaining extensions after ech_outer_extensions */
14201 copyLen = innerChLen - (echOuterExtIdx + echOuterExtLen);
14202 XMEMCPY(newInnerChRef, innerCh + echOuterExtIdx + echOuterExtLen,
14203 copyLen);
14204
14205 WOLFSSL_MSG("ECH: expanded ech_outer_extensions successfully");
14206 }
14207 }
14208
14209 if (ret == 0) {
14210 XFREE(ech->innerClientHello, heap, DYNAMIC_TYPE_TMP_BUFFER);
14211 ech->innerClientHello = newInnerCh;
14212 ech->innerClientHelloLen = newInnerChLen;
14213 newInnerCh = NULL;
14214 }
14215
14216 if (newInnerCh != NULL)
14217 XFREE(newInnerCh, heap, DYNAMIC_TYPE_TMP_BUFFER);
14218
14219 return ret;
14220}
14221
14222/* return status after attempting to open the hpke encrypted ech extension, if
14223 * successful the inner client hello will be stored in
14224 * ech->innerClientHelloLen */
14225static int TLSX_ExtractEch(WOLFSSL_ECH* ech, WOLFSSL_EchConfig* echConfig,
14226 byte* aad, word32 aadLen, void* heap)
14227{
14228 int ret = 0;
14229 int i;
14230 int allocatedHpke = 0;
14231 word32 rawConfigLen = 0;
14232 byte* info = NULL;
14233 word32 infoLen = 0;
14234 if (ech == NULL || echConfig == NULL || aad == NULL)
14235 return BAD_FUNC_ARG;
14236 /* verify the kem and key len */
14237 if (wc_HpkeKemGetEncLen(echConfig->kemId) != ech->encLen)
14238 return BAD_FUNC_ARG;
14239 /* verify the cipher suite */
14240 for (i = 0; i < echConfig->numCipherSuites; i++) {
14241 if (echConfig->cipherSuites[i].kdfId == ech->cipherSuite.kdfId &&
14242 echConfig->cipherSuites[i].aeadId == ech->cipherSuite.aeadId) {
14243 break;
14244 }
14245 }
14246 if (i >= echConfig->numCipherSuites) {
14247 return BAD_FUNC_ARG;
14248 }
14249 /* check if hpke already exists, may if HelloRetryRequest */
14250 if (ech->hpke == NULL) {
14251 allocatedHpke = 1;
14252 ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER);
14253 if (ech->hpke == NULL)
14254 ret = MEMORY_E;
14255 /* init the hpke struct */
14256 if (ret == 0) {
14257 ret = wc_HpkeInit(ech->hpke, echConfig->kemId,
14258 ech->cipherSuite.kdfId, ech->cipherSuite.aeadId, heap);
14259 }
14260 if (ret == 0) {
14261 /* allocate hpkeContext */
14262 ech->hpkeContext =
14263 (HpkeBaseContext*)XMALLOC(sizeof(HpkeBaseContext),
14264 ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
14265 if (ech->hpkeContext == NULL)
14266 ret = MEMORY_E;
14267 }
14268 /* get the rawConfigLen */
14269 if (ret == 0)
14270 ret = GetEchConfig(echConfig, NULL, &rawConfigLen);
14271 if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E))
14272 ret = 0;
14273 /* create info */
14274 if (ret == 0) {
14275 infoLen = TLS_INFO_CONST_STRING_SZ + 1 + rawConfigLen;
14276 info = (byte*)XMALLOC(infoLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
14277
14278 if (info == NULL)
14279 ret = MEMORY_E;
14280 else {
14281 XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING,
14282 TLS_INFO_CONST_STRING_SZ + 1);
14283 ret = GetEchConfig(echConfig, info +
14284 TLS_INFO_CONST_STRING_SZ + 1, &rawConfigLen);
14285 }
14286 }
14287 /* init the context for opening */
14288 if (ret == 0) {
14289 ret = wc_HpkeInitOpenContext(ech->hpke, ech->hpkeContext,
14290 echConfig->receiverPrivkey, ech->enc, ech->encLen, info,
14291 infoLen);
14292 }
14293 }
14294 /* decrypt the ech payload */
14295 if (ret == 0) {
14296 ret = wc_HpkeContextOpenBase(ech->hpke, ech->hpkeContext, aad, aadLen,
14297 ech->outerClientPayload, ech->innerClientHelloLen,
14298 ech->innerClientHello + HANDSHAKE_HEADER_SZ);
14299 }
14300 /* only free hpke/hpkeContext if allocated in this call; otherwise preserve
14301 * them for clientHello2 */
14302 if (ret != 0 && allocatedHpke) {
14303 XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
14304 ech->hpke = NULL;
14305 XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER);
14306 ech->hpkeContext = NULL;
14307 }
14308
14309 if (info != NULL)
14310 XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER);
14311
14312 return ret;
14313}
14314
14315/* parse the ech extension, if internal update ech->state and return, if
14316 * external attempt to extract the inner client_hello, return the status */
14317static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size,
14318 byte msgType)
14319{
14320 int ret = 0;
14321 TLSX* echX;
14322 WOLFSSL_ECH* ech;
14323 WOLFSSL_EchConfig* echConfig;
14324 byte* aadCopy;
14325 byte* readBuf_p = (byte*)readBuf;
14326 word32 offset = 0;
14327 word16 len;
14328 word16 tmpVal16;
14329 word16 lenCh;
14330
14331 WOLFSSL_MSG("TLSX_ECH_Parse");
14332 if (ssl->options.disableECH) {
14333 WOLFSSL_MSG("TLSX_ECH_Parse: ECH disabled. Ignoring.");
14334 return 0;
14335 }
14336 if (size == 0)
14337 return BAD_FUNC_ARG;
14338
14339 /* retry configs */
14340 if (msgType == encrypted_extensions) {
14341 /* configs must only be sent on ECH rejection (RFC9849, Section 5) */
14342 if (ssl->options.echAccepted) {
14343 SendAlert(ssl, alert_fatal, unsupported_extension);
14344 WOLFSSL_ERROR_VERBOSE(UNSUPPORTED_EXTENSION);
14345 return UNSUPPORTED_EXTENSION;
14346 }
14347
14348 ret = SetRetryConfigs(ssl, readBuf, (word32)size);
14349 if (ret == WC_NO_ERR_TRACE(UNSUPPORTED_SUITE) ||
14350 ret == WC_NO_ERR_TRACE(UNSUPPORTED_PROTO_VERSION)) {
14351 WOLFSSL_MSG("ECH retry configs had 'bad version' or 'bad suite'");
14352 ret = 0;
14353 }
14354
14355 if (ssl->echConfigs == NULL) {
14356 /* on GREASE connection configs must be checked syntactically and
14357 * must not be saved (RFC 9849, Section 6.2.1) */
14358 FreeEchConfigs(ssl->echRetryConfigs, ssl->heap);
14359 ssl->echRetryConfigs = NULL;
14360 }
14361
14362 /* retry configs may only be accepted at the point when ECH_REQUIRED is
14363 * sent */
14364 ssl->options.echRetryConfigsAccepted = 0;
14365 }
14366 /* HRR with special confirmation */
14367 else if (msgType == hello_retry_request && ssl->echConfigs != NULL) {
14368 /* length must be 8 */
14369 if (size != ECH_ACCEPT_CONFIRMATION_SZ)
14370 return BUFFER_ERROR;
14371
14372 /* get extension */
14373 echX = TLSX_Find(ssl->extensions, TLSX_ECH);
14374 if (echX == NULL)
14375 return BAD_FUNC_ARG;
14376 ech = (WOLFSSL_ECH*)echX->data;
14377
14378 ech->confBuf = (byte*)readBuf;
14379 }
14380 else if (msgType == client_hello && ssl->ctx->echConfigs != NULL) {
14381 /* get extension */
14382 echX = TLSX_Find(ssl->extensions, TLSX_ECH);
14383 if (echX == NULL)
14384 return BAD_FUNC_ARG;
14385 ech = (WOLFSSL_ECH*)echX->data;
14386
14387 /* if the first ECH was rejected or CH1 did not have ECH then there is
14388 * no need to decrypt this one */
14389 if (!ssl->options.echAccepted && ssl->options.serverState ==
14390 SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
14391 ech->state = ECH_WRITE_RETRY_CONFIGS;
14392 return 0;
14393 }
14394
14395 /* read the ech parameters before the payload */
14396 ech->type = *readBuf_p;
14397 readBuf_p++;
14398 offset += 1;
14399 if (ssl->options.echProcessingInner && ech->type == ECH_TYPE_INNER) {
14400 ech->state = ECH_PARSED_INTERNAL;
14401 return 0;
14402 }
14403 else if ((!ssl->options.echProcessingInner &&
14404 ech->type != ECH_TYPE_OUTER) ||
14405 (ssl->options.echProcessingInner &&
14406 ech->type != ECH_TYPE_INNER)) {
14407 /* MUST process INNER in inner hello and OUTER in outer hello */
14408 return INVALID_PARAMETER;
14409 }
14410 /* Must have kdfId, aeadId, configId, enc len and payload len. */
14411 if (size < offset + 2 + 2 + 1 + 2 + 2) {
14412 return BUFFER_ERROR;
14413 }
14414 /* only get enc if we don't already have the hpke context */
14415 if (ech->hpkeContext == NULL) {
14416 /* kdfId */
14417 ato16(readBuf_p, &ech->cipherSuite.kdfId);
14418 readBuf_p += 2;
14419 offset += 2;
14420 /* aeadId */
14421 ato16(readBuf_p, &ech->cipherSuite.aeadId);
14422 readBuf_p += 2;
14423 offset += 2;
14424 /* configId */
14425 ech->configId = *readBuf_p;
14426 readBuf_p++;
14427 offset++;
14428 /* encLen */
14429 ato16(readBuf_p, &len);
14430 readBuf_p += 2;
14431 offset += 2;
14432 /* Check encLen isn't more than remaining bytes minus
14433 * payload length. */
14434 if (len > size - offset - 2) {
14435 return BUFFER_ERROR;
14436 }
14437 if (len > HPKE_Npk_MAX) {
14438 return BUFFER_ERROR;
14439 }
14440 /* read enc */
14441 XMEMCPY(ech->enc, readBuf_p, len);
14442 ech->encLen = len;
14443 }
14444 else {
14445 /* kdfId, aeadId, and configId must be the same as last time */
14446 /* kdfId */
14447 ato16(readBuf_p, &tmpVal16);
14448 if (tmpVal16 != ech->cipherSuite.kdfId) {
14449 return INVALID_PARAMETER;
14450 }
14451 readBuf_p += 2;
14452 offset += 2;
14453 /* aeadId */
14454 ato16(readBuf_p, &tmpVal16);
14455 if (tmpVal16 != ech->cipherSuite.aeadId) {
14456 return INVALID_PARAMETER;
14457 }
14458 readBuf_p += 2;
14459 offset += 2;
14460 /* configId */
14461 if (*readBuf_p != ech->configId) {
14462 return INVALID_PARAMETER;
14463 }
14464 readBuf_p++;
14465 offset++;
14466 /* on an HRR the enc value MUST be empty */
14467 ato16(readBuf_p, &len);
14468 if (len != 0) {
14469 return INVALID_PARAMETER;
14470 }
14471 readBuf_p += 2;
14472 offset += 2;
14473 }
14474 readBuf_p += len;
14475 offset += len;
14476 /* read payload (encrypted CH) len */
14477 ato16(readBuf_p, &lenCh);
14478 ech->innerClientHelloLen = lenCh;
14479 readBuf_p += 2;
14480 offset += 2;
14481 /* Check payload is no bigger than remaining bytes. */
14482 if (ech->innerClientHelloLen > size - offset) {
14483 return BUFFER_ERROR;
14484 }
14485 if (ech->innerClientHelloLen < WC_AES_BLOCK_SIZE) {
14486 return BUFFER_ERROR;
14487 }
14488 ech->innerClientHelloLen -= WC_AES_BLOCK_SIZE;
14489 ech->outerClientPayload = readBuf_p;
14490 /* make a copy of the aad */
14491 aadCopy = (byte*)XMALLOC(ech->aadLen, ssl->heap,
14492 DYNAMIC_TYPE_TMP_BUFFER);
14493 if (aadCopy == NULL)
14494 return MEMORY_E;
14495 XMEMCPY(aadCopy, ech->aad, ech->aadLen);
14496 /* set the ech payload of the copy to zeros */
14497 XMEMSET(aadCopy + (readBuf_p - ech->aad), 0,
14498 ech->innerClientHelloLen + WC_AES_BLOCK_SIZE);
14499 /* free the old ech when this is the second client hello */
14500 if (ech->innerClientHello != NULL)
14501 XFREE(ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
14502 /* allocate the inner payload buffer */
14503 ech->innerClientHello =
14504 (byte*)XMALLOC(ech->innerClientHelloLen + HANDSHAKE_HEADER_SZ,
14505 ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
14506 if (ech->innerClientHello == NULL) {
14507 XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
14508 return MEMORY_E;
14509 }
14510 /* try to decrypt with matching configId */
14511 echConfig = ssl->ctx->echConfigs;
14512 while (echConfig != NULL) {
14513 if (echConfig->configId == ech->configId) {
14514 ret = TLSX_ExtractEch(ech, echConfig, aadCopy, ech->aadLen,
14515 ssl->heap);
14516 break;
14517 }
14518 echConfig = echConfig->next;
14519 }
14520 /* otherwise, try to decrypt with all configs */
14521 if (echConfig == NULL || ret != 0) {
14522 echConfig = ssl->ctx->echConfigs;
14523 while (echConfig != NULL) {
14524 ret = TLSX_ExtractEch(ech, echConfig, aadCopy, ech->aadLen,
14525 ssl->heap);
14526 if (ret == 0)
14527 break;
14528 echConfig = echConfig->next;
14529 }
14530 }
14531 /* if we failed to extract/expand */
14532 if (ret != 0) {
14533 WOLFSSL_MSG("ECH rejected");
14534
14535 if (ssl->options.echAccepted == 1) {
14536 /* on SH2 this is fatal */
14537 SendAlert(ssl, alert_fatal, decrypt_error);
14538 WOLFSSL_ERROR_VERBOSE(DECRYPT_ERROR);
14539 ret = DECRYPT_ERROR;
14540 }
14541 else {
14542 /* on SH1 prepare to write retry configs */
14543 XFREE(ech->innerClientHello, ssl->heap,
14544 DYNAMIC_TYPE_TMP_BUFFER);
14545 ech->innerClientHello = NULL;
14546 ech->state = ECH_WRITE_RETRY_CONFIGS;
14547 ret = 0;
14548 }
14549 }
14550 else {
14551 ret = TLSX_ECH_CheckInnerPadding(ssl, ech);
14552 if (ret == 0) {
14553 /* expand EchOuterExtensions if present.
14554 * Also, if it exists, copy sessionID from outer hello */
14555 ret = TLSX_ECH_ExpandOuterExtensions(ssl, ech, ssl->heap);
14556 }
14557
14558 if (ret == 0){
14559 WOLFSSL_MSG("ECH accepted");
14560 ssl->options.echAccepted = 1;
14561 }
14562 else {
14563 WOLFSSL_MSG("ECH rejected");
14564 }
14565 }
14566 if (ret != 0) {
14567 XFREE(ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
14568 ech->innerClientHello = NULL;
14569 }
14570
14571 XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
14572 }
14573
14574 return ret;
14575}
14576
14577/* free the ech struct and the dynamic buffer it uses */
14578static void TLSX_ECH_Free(WOLFSSL_ECH* ech, void* heap)
14579{
14580 XFREE(ech->innerClientHello, heap, DYNAMIC_TYPE_TMP_BUFFER);
14581 if (ech->hpke != NULL) {
14582 if (ech->ephemeralKey != NULL)
14583 wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, ech->ephemeralKey,
14584 ech->hpke->heap);
14585 XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER);
14586 }
14587 if (ech->hpkeContext != NULL)
14588 XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER);
14589 if (ech->privateName != NULL)
14590 XFREE((char*)ech->privateName, heap, DYNAMIC_TYPE_TMP_BUFFER);
14591
14592 XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER);
14593 (void)heap;
14594}
14595
14596/* encrypt the client hello and store it in ech->outerClientPayload, return
14597 * status */
14598int TLSX_FinalizeEch(WOLFSSL_ECH* ech, byte* aad, word32 aadLen)
14599{
14600 int ret = 0;
14601 void* receiverPubkey = NULL;
14602 byte* info = NULL;
14603 int infoLen = 0;
14604 byte* aadCopy = NULL;
14605 /* setup hpke context to seal, should be done at most once per connection */
14606 if (ech->hpkeContext == NULL) {
14607 /* import the server public key */
14608 ret = wc_HpkeDeserializePublicKey(ech->hpke, &receiverPubkey,
14609 ech->echConfig->receiverPubkey, ech->encLen);
14610 if (ret == 0) {
14611 /* allocate hpke context */
14612 ech->hpkeContext =
14613 (HpkeBaseContext*)XMALLOC(sizeof(HpkeBaseContext),
14614 ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
14615 if (ech->hpkeContext == NULL)
14616 ret = MEMORY_E;
14617 }
14618 if (ret == 0) {
14619 /* create info */
14620 infoLen = TLS_INFO_CONST_STRING_SZ + 1 + ech->echConfig->rawLen;
14621 info = (byte*)XMALLOC(infoLen, ech->hpke->heap,
14622 DYNAMIC_TYPE_TMP_BUFFER);
14623 if (info == NULL)
14624 ret = MEMORY_E;
14625 }
14626 if (ret == 0) {
14627 /* puts the null byte in for me */
14628 XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING,
14629 TLS_INFO_CONST_STRING_SZ + 1);
14630 XMEMCPY(info + TLS_INFO_CONST_STRING_SZ + 1,
14631 ech->echConfig->raw, ech->echConfig->rawLen);
14632 /* init the context for seal with info and keys */
14633 ret = wc_HpkeInitSealContext(ech->hpke, ech->hpkeContext,
14634 ech->ephemeralKey, receiverPubkey, info, infoLen);
14635 }
14636 }
14637 if (ret == 0) {
14638 /* make a copy of the aad since we overwrite it */
14639 aadCopy = (byte*)XMALLOC(aadLen, ech->hpke->heap,
14640 DYNAMIC_TYPE_TMP_BUFFER);
14641 if (aadCopy == NULL) {
14642 ret = MEMORY_E;
14643 }
14644 }
14645 if (ret == 0) {
14646 XMEMCPY(aadCopy, aad, aadLen);
14647 /* seal the payload with context */
14648 ret = wc_HpkeContextSealBase(ech->hpke, ech->hpkeContext, aadCopy,
14649 aadLen, ech->innerClientHello,
14650 ech->innerClientHelloLen - ech->hpke->Nt, ech->outerClientPayload);
14651 }
14652 if (info != NULL)
14653 XFREE(info, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
14654 if (aadCopy != NULL)
14655 XFREE(aadCopy, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER);
14656 if (receiverPubkey != NULL)
14657 wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, receiverPubkey,
14658 ech->hpke->heap);
14659 return ret;
14660}
14661
14662#define GREASE_ECH_USE TLSX_GreaseECH_Use
14663#define ECH_USE TLSX_ECH_Use
14664#define SERVER_ECH_USE TLSX_ServerECH_Use
14665#define ECH_WRITE TLSX_ECH_Write
14666#define ECH_GET_SIZE TLSX_ECH_GetSize
14667#define ECH_PARSE TLSX_ECH_Parse
14668#define ECH_FREE TLSX_ECH_Free
14669
14670#endif
14671
14672/** Releases all extensions in the provided list. */
14673void TLSX_FreeAll(TLSX* list, void* heap)
14674{
14675 TLSX* extension;
14676
14677 while ((extension = list)) {
14678 list = extension->next;
14679
14680 switch (extension->type) {
14681#if defined(HAVE_RPK)
14682 case TLSX_CLIENT_CERTIFICATE_TYPE:
14683 WOLFSSL_MSG("Client Certificate Type extension free");
14684 /* nothing to do */
14685 break;
14686 case TLSX_SERVER_CERTIFICATE_TYPE:
14687 WOLFSSL_MSG("Server Certificate Type extension free");
14688 /* nothing to do */
14689 break;
14690#endif
14691
14692#ifdef HAVE_SNI
14693 case TLSX_SERVER_NAME:
14694 WOLFSSL_MSG("SNI extension free");
14695 SNI_FREE_ALL((SNI*)extension->data, heap);
14696 break;
14697#endif
14698
14699 case TLSX_TRUSTED_CA_KEYS:
14700 WOLFSSL_MSG("Trusted CA Indication extension free");
14701 TCA_FREE_ALL((TCA*)extension->data, heap);
14702 break;
14703
14704 case TLSX_MAX_FRAGMENT_LENGTH:
14705 WOLFSSL_MSG("Max Fragment Length extension free");
14706 MFL_FREE_ALL(extension->data, heap);
14707 break;
14708
14709 case TLSX_EXTENDED_MASTER_SECRET:
14710 WOLFSSL_MSG("Extended Master Secret free");
14711 /* Nothing to do. */
14712 break;
14713 case TLSX_TRUNCATED_HMAC:
14714 WOLFSSL_MSG("Truncated HMAC extension free");
14715 /* Nothing to do. */
14716 break;
14717
14718 case TLSX_SUPPORTED_GROUPS:
14719 WOLFSSL_MSG("Supported Groups extension free");
14720 EC_FREE_ALL((SupportedCurve*)extension->data, heap);
14721 break;
14722
14723 case TLSX_EC_POINT_FORMATS:
14724 WOLFSSL_MSG("Point Formats extension free");
14725 PF_FREE_ALL((PointFormat*)extension->data, heap);
14726 break;
14727
14728 case TLSX_STATUS_REQUEST:
14729 WOLFSSL_MSG("Certificate Status Request extension free");
14730 CSR_FREE_ALL((CertificateStatusRequest*)extension->data, heap);
14731 break;
14732
14733 case TLSX_STATUS_REQUEST_V2:
14734 WOLFSSL_MSG("Certificate Status Request v2 extension free");
14735 CSR2_FREE_ALL((CertificateStatusRequestItemV2*)extension->data,
14736 heap);
14737 break;
14738
14739 case TLSX_RENEGOTIATION_INFO:
14740 WOLFSSL_MSG("Secure Renegotiation extension free");
14741 SCR_FREE_ALL(extension->data, heap);
14742 break;
14743
14744 case TLSX_SESSION_TICKET:
14745 WOLFSSL_MSG("Session Ticket extension free");
14746 WOLF_STK_FREE(extension->data, heap);
14747 break;
14748
14749 case TLSX_APPLICATION_LAYER_PROTOCOL:
14750 WOLFSSL_MSG("ALPN extension free");
14751 ALPN_FREE_ALL((ALPN*)extension->data, heap);
14752 break;
14753#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
14754 case TLSX_SIGNATURE_ALGORITHMS:
14755 WOLFSSL_MSG("Signature Algorithms extension to free");
14756 SA_FREE_ALL((SignatureAlgorithms*)extension->data, heap);
14757 break;
14758#endif
14759#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
14760 case TLSX_ENCRYPT_THEN_MAC:
14761 WOLFSSL_MSG("Encrypt-Then-Mac extension free");
14762 break;
14763#endif
14764
14765#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
14766 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
14767 case TLSX_PRE_SHARED_KEY:
14768 WOLFSSL_MSG("Pre-Shared Key extension free");
14769 PSK_FREE_ALL((PreSharedKey*)extension->data, heap);
14770 break;
14771
14772 #ifdef WOLFSSL_TLS13
14773 case TLSX_PSK_KEY_EXCHANGE_MODES:
14774 WOLFSSL_MSG("PSK Key Exchange Modes extension free");
14775 break;
14776 #ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
14777 case TLSX_CERT_WITH_EXTERN_PSK:
14778 WOLFSSL_MSG("Cert with external PSK extension free");
14779 break;
14780 #endif
14781 #endif
14782 #endif
14783
14784 case TLSX_KEY_SHARE:
14785 WOLFSSL_MSG("Key Share extension free");
14786 KS_FREE_ALL((KeyShareEntry*)extension->data, heap);
14787 break;
14788#endif
14789#ifdef WOLFSSL_TLS13
14790 case TLSX_SUPPORTED_VERSIONS:
14791 WOLFSSL_MSG("Supported Versions extension free");
14792 break;
14793
14794 case TLSX_COOKIE:
14795 WOLFSSL_MSG("Cookie extension free");
14796 CKE_FREE_ALL((Cookie*)extension->data, heap);
14797 break;
14798
14799 #ifdef WOLFSSL_EARLY_DATA
14800 case TLSX_EARLY_DATA:
14801 WOLFSSL_MSG("Early Data extension free");
14802 break;
14803 #endif
14804
14805 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
14806 case TLSX_POST_HANDSHAKE_AUTH:
14807 WOLFSSL_MSG("Post-Handshake Authentication extension free");
14808 break;
14809 #endif
14810
14811 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
14812 case TLSX_SIGNATURE_ALGORITHMS_CERT:
14813 WOLFSSL_MSG("Signature Algorithms extension free");
14814 break;
14815 #endif
14816 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
14817 case TLSX_CERTIFICATE_AUTHORITIES:
14818 WOLFSSL_MSG("Certificate Authorities extension free");
14819 break;
14820 #endif
14821#endif
14822#ifdef WOLFSSL_SRTP
14823 case TLSX_USE_SRTP:
14824 WOLFSSL_MSG("SRTP extension free");
14825 SRTP_FREE((TlsxSrtp*)extension->data, heap);
14826 break;
14827#endif
14828
14829 #ifdef WOLFSSL_QUIC
14830 case TLSX_KEY_QUIC_TP_PARAMS:
14831 FALL_THROUGH;
14832 case TLSX_KEY_QUIC_TP_PARAMS_DRAFT:
14833 WOLFSSL_MSG("QUIC transport parameter free");
14834 QTP_FREE((QuicTransportParam*)extension->data, heap);
14835 break;
14836 #endif
14837
14838#ifdef WOLFSSL_DTLS_CID
14839 case TLSX_CONNECTION_ID:
14840 WOLFSSL_MSG("Connection ID extension free");
14841 CID_FREE((byte*)extension->data, heap);
14842 break;
14843#endif /* WOLFSSL_DTLS_CID */
14844#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
14845 case TLSX_ECH:
14846 WOLFSSL_MSG("ECH extension free");
14847 ECH_FREE((WOLFSSL_ECH*)extension->data, heap);
14848 break;
14849#endif
14850#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DUAL_ALG_CERTS)
14851 case TLSX_CKS:
14852 WOLFSSL_MSG("CKS extension free");
14853 /* nothing to do */
14854 break;
14855#endif
14856 default:
14857 break;
14858 }
14859
14860 XFREE(extension, heap, DYNAMIC_TYPE_TLSX);
14861 }
14862
14863 (void)heap;
14864}
14865
14866/** Checks if the tls extensions are supported based on the protocol version. */
14867int TLSX_SupportExtensions(WOLFSSL* ssl) {
14868 return ssl && (IsTLS(ssl) || ssl->version.major == DTLS_MAJOR);
14869}
14870
14871/** Tells the buffered size of the extensions in a list. */
14872static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
14873 word16* pLength)
14874{
14875 int ret = 0;
14876 TLSX* extension;
14877 /* Use a word32 accumulator so that an extension whose contribution
14878 * pushes the running total past 0xFFFF is detected rather than
14879 * silently wrapped (the TLS extensions block length prefix on the
14880 * wire is a 2-byte field). Callees that take a word16* accumulator
14881 * are invoked via a per-iteration shim (`cbShim`) and their delta
14882 * is added back into the word32 total.
14883 *
14884 * MAINTAINER NOTE: do NOT pass &length to any *_GET_SIZE function
14885 * that expects a `word16*` out-parameter -- that would be a type
14886 * mismatch (UB) and would silently bypass the overflow detection
14887 * below. When adding a new extension case, either:
14888 * - use `length += FOO_GET_SIZE(...)` when the helper returns a
14889 * word16 by value, or
14890 * - use the cbShim pattern: `cbShim = 0; ret = FOO_GET_SIZE(...,
14891 * &cbShim); length += cbShim;`
14892 */
14893 word32 length = 0;
14894 word16 cbShim = 0;
14895 byte isRequest = (msgType == client_hello ||
14896 msgType == certificate_request);
14897 (void)cbShim;
14898
14899 while ((extension = list)) {
14900 list = extension->next;
14901
14902 /* only extensions marked as response are sent back to the client. */
14903 if (!isRequest && !extension->resp)
14904 continue; /* skip! */
14905
14906 /* ssl level extensions are expected to override ctx level ones. */
14907 if (!IS_OFF(semaphore, TLSX_ToSemaphore((word16)extension->type)))
14908 continue; /* skip! */
14909
14910 /* extension type + extension data length. */
14911 length += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
14912
14913 switch (extension->type) {
14914#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DUAL_ALG_CERTS)
14915 case TLSX_CKS:
14916 length += ((WOLFSSL*)extension->data)->sigSpecSz ;
14917 break;
14918#endif
14919#ifdef HAVE_SNI
14920 case TLSX_SERVER_NAME:
14921 /* SNI only sends the name on the request. */
14922 if (isRequest)
14923 length += SNI_GET_SIZE((SNI*)extension->data);
14924 break;
14925#endif
14926
14927 case TLSX_TRUSTED_CA_KEYS:
14928 /* TCA only sends the list on the request. */
14929 if (isRequest) {
14930 word16 tcaSz = TCA_GET_SIZE((TCA*)extension->data);
14931 /* 0 on non-empty list means 16-bit overflow. */
14932 if (tcaSz == 0 && extension->data != NULL) {
14933 ret = LENGTH_ERROR;
14934 break;
14935 }
14936 length += tcaSz;
14937 }
14938 break;
14939
14940 case TLSX_MAX_FRAGMENT_LENGTH:
14941 length += MFL_GET_SIZE(extension->data);
14942 break;
14943
14944 case TLSX_EXTENDED_MASTER_SECRET:
14945 case TLSX_TRUNCATED_HMAC:
14946 /* always empty. */
14947 break;
14948
14949 case TLSX_SUPPORTED_GROUPS:
14950 length += EC_GET_SIZE((SupportedCurve*)extension->data);
14951 break;
14952
14953 case TLSX_EC_POINT_FORMATS:
14954 length += PF_GET_SIZE((PointFormat*)extension->data);
14955 break;
14956
14957 case TLSX_STATUS_REQUEST:
14958 length += CSR_GET_SIZE(
14959 (CertificateStatusRequest*)extension->data, isRequest);
14960 break;
14961
14962 case TLSX_STATUS_REQUEST_V2:
14963 length += CSR2_GET_SIZE(
14964 (CertificateStatusRequestItemV2*)extension->data,
14965 isRequest);
14966 break;
14967
14968 case TLSX_RENEGOTIATION_INFO:
14969 length += SCR_GET_SIZE((SecureRenegotiation*)extension->data,
14970 isRequest);
14971 break;
14972
14973 case TLSX_SESSION_TICKET:
14974 length += WOLF_STK_GET_SIZE((SessionTicket*)extension->data,
14975 isRequest);
14976 break;
14977
14978 case TLSX_APPLICATION_LAYER_PROTOCOL: {
14979 word16 alpnSz = ALPN_GET_SIZE((ALPN*)extension->data);
14980 /* 0 on non-empty list means 16-bit overflow. */
14981 if (alpnSz == 0 && extension->data != NULL) {
14982 ret = LENGTH_ERROR;
14983 break;
14984 }
14985 length += alpnSz;
14986 break;
14987 }
14988#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
14989 case TLSX_SIGNATURE_ALGORITHMS:
14990 length += SA_GET_SIZE(extension->data);
14991 break;
14992#endif
14993#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
14994 case TLSX_ENCRYPT_THEN_MAC:
14995 cbShim = 0;
14996 ret = ETM_GET_SIZE(msgType, &cbShim);
14997 length += cbShim;
14998 break;
14999#endif /* HAVE_ENCRYPT_THEN_MAC */
15000
15001#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
15002 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
15003 case TLSX_PRE_SHARED_KEY:
15004 cbShim = 0;
15005 ret = PSK_GET_SIZE((PreSharedKey*)extension->data, msgType,
15006 &cbShim);
15007 length += cbShim;
15008 break;
15009 #ifdef WOLFSSL_TLS13
15010 case TLSX_PSK_KEY_EXCHANGE_MODES:
15011 cbShim = 0;
15012 ret = PKM_GET_SIZE((byte)extension->val, msgType, &cbShim);
15013 length += cbShim;
15014 break;
15015 #ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
15016 case TLSX_CERT_WITH_EXTERN_PSK:
15017 cbShim = 0;
15018 ret = PSK_WITH_CERT_GET_SIZE(msgType, &cbShim);
15019 length += cbShim;
15020 break;
15021 #endif
15022 #endif
15023 #endif
15024 case TLSX_KEY_SHARE:
15025 length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType);
15026 break;
15027#endif
15028
15029#ifdef WOLFSSL_TLS13
15030 case TLSX_SUPPORTED_VERSIONS:
15031 cbShim = 0;
15032 ret = SV_GET_SIZE(extension->data, msgType, &cbShim);
15033 length += cbShim;
15034 break;
15035
15036 case TLSX_COOKIE:
15037 cbShim = 0;
15038 ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &cbShim);
15039 length += cbShim;
15040 break;
15041
15042 #ifdef WOLFSSL_EARLY_DATA
15043 case TLSX_EARLY_DATA:
15044 cbShim = 0;
15045 ret = EDI_GET_SIZE(msgType, &cbShim);
15046 length += cbShim;
15047 break;
15048 #endif
15049
15050 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
15051 case TLSX_POST_HANDSHAKE_AUTH:
15052 cbShim = 0;
15053 ret = PHA_GET_SIZE(msgType, &cbShim);
15054 length += cbShim;
15055 break;
15056 #endif
15057
15058 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
15059 case TLSX_SIGNATURE_ALGORITHMS_CERT:
15060 length += SAC_GET_SIZE(extension->data);
15061 break;
15062 #endif
15063
15064 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
15065 case TLSX_CERTIFICATE_AUTHORITIES: {
15066 word16 canSz = CAN_GET_SIZE(extension->data);
15067 /* 0 on non-empty list means 16-bit overflow. */
15068 if (canSz == 0) {
15069 ret = LENGTH_ERROR;
15070 break;
15071 }
15072 length += canSz;
15073 break;
15074 }
15075 #endif
15076#endif
15077#ifdef WOLFSSL_SRTP
15078 case TLSX_USE_SRTP:
15079 length += SRTP_GET_SIZE((TlsxSrtp*)extension->data);
15080 break;
15081#endif
15082
15083#ifdef HAVE_RPK
15084 case TLSX_CLIENT_CERTIFICATE_TYPE:
15085 length += CCT_GET_SIZE((WOLFSSL*)extension->data, msgType);
15086 break;
15087
15088 case TLSX_SERVER_CERTIFICATE_TYPE:
15089 length += SCT_GET_SIZE((WOLFSSL*)extension->data, msgType);
15090 break;
15091#endif /* HAVE_RPK */
15092
15093#ifdef WOLFSSL_QUIC
15094 case TLSX_KEY_QUIC_TP_PARAMS:
15095 FALL_THROUGH; /* followed by */
15096 case TLSX_KEY_QUIC_TP_PARAMS_DRAFT:
15097 length += QTP_GET_SIZE(extension);
15098 break;
15099#endif
15100#ifdef WOLFSSL_DTLS_CID
15101 case TLSX_CONNECTION_ID:
15102 length += CID_GET_SIZE((byte*)extension->data);
15103 break;
15104#endif /* WOLFSSL_DTLS_CID */
15105#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
15106 case TLSX_ECH:
15107 length += ECH_GET_SIZE((WOLFSSL_ECH*)extension->data, msgType);
15108 break;
15109#endif
15110 default:
15111 break;
15112 }
15113
15114 if (ret != 0)
15115 return ret;
15116
15117 /* Early exit: stop accumulating as soon as the running total
15118 * cannot possibly fit the 2-byte wire length. Check *before*
15119 * marking the extension as processed so the semaphore is not
15120 * left in an inconsistent state on the error path. */
15121 if (length > WOLFSSL_MAX_16BIT) {
15122 WOLFSSL_MSG("TLSX_GetSize extension length exceeds word16");
15123 return BUFFER_E;
15124 }
15125
15126 /* marks the extension as processed so ctx level */
15127 /* extensions don't overlap with ssl level ones. */
15128 TURN_ON(semaphore, TLSX_ToSemaphore((word16)extension->type));
15129 }
15130
15131 if ((word32)*pLength + length > WOLFSSL_MAX_16BIT) {
15132 WOLFSSL_MSG("TLSX_GetSize total extensions length exceeds word16");
15133 return BUFFER_E;
15134 }
15135
15136 *pLength += (word16)length;
15137
15138 return ret;
15139}
15140
15141/** Writes the extensions of a list in a buffer. */
15142static int TLSX_Write(TLSX* list, byte* output, byte* semaphore,
15143 byte msgType, word16* pOffset)
15144{
15145 int ret = 0;
15146 TLSX* extension;
15147 /* Use word32 to symmetrize with TLSX_GetSize -- a single extension can
15148 * contribute up to 0x10003 bytes (4-byte type/length header + 0xFFFF
15149 * payload), which would word16-overflow undetectably (e.g. wrap to a
15150 * value still above prevOffset). Per-iteration and aggregate bounds are
15151 * checked below before truncating back into the word16 wire fields.
15152 * Callees that take a word16* offset use the cbShim pattern (init to 0,
15153 * then add the returned delta to the word32 accumulator). */
15154 word32 offset = 0;
15155 word32 length_offset = 0;
15156 word32 prevOffset;
15157 word16 cbShim = 0;
15158 byte isRequest = (msgType == client_hello ||
15159 msgType == certificate_request);
15160 (void)cbShim;
15161
15162 while ((extension = list)) {
15163 list = extension->next;
15164
15165 /* only extensions marked as response are written in a response. */
15166 if (!isRequest && !extension->resp)
15167 continue; /* skip! */
15168
15169 /* ssl level extensions are expected to override ctx level ones. */
15170 if (!IS_OFF(semaphore, TLSX_ToSemaphore((word16)extension->type)))
15171 continue; /* skip! */
15172
15173 /* Snapshot offset to detect word16 wrap within this iteration;
15174 * see matching comment in TLSX_GetSize. */
15175 prevOffset = offset;
15176
15177 /* writes extension type. */
15178 c16toa((word16)extension->type, output + offset);
15179 offset += HELLO_EXT_TYPE_SZ + OPAQUE16_LEN;
15180 length_offset = offset;
15181
15182 /* extension data should be written internally. */
15183 switch (extension->type) {
15184#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DUAL_ALG_CERTS)
15185 case TLSX_CKS:
15186 WOLFSSL_MSG("CKS extension to write");
15187 offset += CKS_WRITE(((WOLFSSL*)extension->data),
15188 output + offset);
15189 break;
15190#endif
15191#ifdef HAVE_SNI
15192 case TLSX_SERVER_NAME:
15193 if (isRequest) {
15194 WOLFSSL_MSG("SNI extension to write");
15195 offset += SNI_WRITE((SNI*)extension->data, output + offset);
15196 }
15197 break;
15198#endif
15199
15200 case TLSX_TRUSTED_CA_KEYS:
15201 WOLFSSL_MSG("Trusted CA Indication extension to write");
15202 if (isRequest) {
15203 offset += TCA_WRITE((TCA*)extension->data, output + offset);
15204 }
15205 break;
15206
15207 case TLSX_MAX_FRAGMENT_LENGTH:
15208 WOLFSSL_MSG("Max Fragment Length extension to write");
15209 offset += MFL_WRITE((byte*)extension->data, output + offset);
15210 break;
15211
15212 case TLSX_EXTENDED_MASTER_SECRET:
15213 WOLFSSL_MSG("Extended Master Secret");
15214 /* always empty. */
15215 break;
15216
15217 case TLSX_TRUNCATED_HMAC:
15218 WOLFSSL_MSG("Truncated HMAC extension to write");
15219 /* always empty. */
15220 break;
15221
15222 case TLSX_SUPPORTED_GROUPS:
15223 WOLFSSL_MSG("Supported Groups extension to write");
15224 offset += EC_WRITE((SupportedCurve*)extension->data,
15225 output + offset);
15226 break;
15227
15228 case TLSX_EC_POINT_FORMATS:
15229 WOLFSSL_MSG("Point Formats extension to write");
15230 offset += PF_WRITE((PointFormat*)extension->data,
15231 output + offset);
15232 break;
15233
15234 case TLSX_STATUS_REQUEST:
15235 WOLFSSL_MSG("Certificate Status Request extension to write");
15236 ret = CSR_WRITE((CertificateStatusRequest*)extension->data,
15237 output + offset, isRequest);
15238 if (ret > 0) {
15239 offset += (word16)ret;
15240 ret = 0;
15241 }
15242 break;
15243
15244 case TLSX_STATUS_REQUEST_V2:
15245 WOLFSSL_MSG("Certificate Status Request v2 extension to write");
15246 ret = CSR2_WRITE(
15247 (CertificateStatusRequestItemV2*)extension->data,
15248 output + offset, isRequest);
15249 if (ret > 0) {
15250 offset += (word16)ret;
15251 ret = 0;
15252 }
15253 break;
15254
15255 case TLSX_RENEGOTIATION_INFO:
15256 WOLFSSL_MSG("Secure Renegotiation extension to write");
15257 offset += SCR_WRITE((SecureRenegotiation*)extension->data,
15258 output + offset, isRequest);
15259 break;
15260
15261 case TLSX_SESSION_TICKET:
15262 WOLFSSL_MSG("Session Ticket extension to write");
15263 offset += WOLF_STK_WRITE((SessionTicket*)extension->data,
15264 output + offset, isRequest);
15265 break;
15266
15267 case TLSX_APPLICATION_LAYER_PROTOCOL:
15268 WOLFSSL_MSG("ALPN extension to write");
15269 offset += ALPN_WRITE((ALPN*)extension->data, output + offset);
15270 break;
15271#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
15272 case TLSX_SIGNATURE_ALGORITHMS:
15273 WOLFSSL_MSG("Signature Algorithms extension to write");
15274 offset += SA_WRITE(extension->data, output + offset);
15275 break;
15276#endif
15277#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
15278 case TLSX_ENCRYPT_THEN_MAC:
15279 WOLFSSL_MSG("Encrypt-Then-Mac extension to write");
15280 cbShim = 0;
15281 ret = ETM_WRITE(extension->data, output, msgType, &cbShim);
15282 offset += cbShim;
15283 break;
15284#endif /* HAVE_ENCRYPT_THEN_MAC */
15285
15286#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
15287 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
15288 case TLSX_PRE_SHARED_KEY:
15289 WOLFSSL_MSG("Pre-Shared Key extension to write");
15290 cbShim = 0;
15291 ret = PSK_WRITE((PreSharedKey*)extension->data, output + offset,
15292 msgType, &cbShim);
15293 offset += cbShim;
15294 break;
15295
15296 #ifdef WOLFSSL_TLS13
15297 case TLSX_PSK_KEY_EXCHANGE_MODES:
15298 WOLFSSL_MSG("PSK Key Exchange Modes extension to write");
15299 cbShim = 0;
15300 ret = PKM_WRITE((byte)extension->val, output + offset, msgType,
15301 &cbShim);
15302 offset += cbShim;
15303 break;
15304 #ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
15305 case TLSX_CERT_WITH_EXTERN_PSK:
15306 WOLFSSL_MSG("Cert with external PSK extension to write");
15307 cbShim = 0;
15308 ret = PSK_WITH_CERT_WRITE(output + offset, msgType, &cbShim);
15309 offset += cbShim;
15310 break;
15311 #endif
15312 #endif
15313 #endif
15314 case TLSX_KEY_SHARE:
15315 WOLFSSL_MSG("Key Share extension to write");
15316 offset += KS_WRITE((KeyShareEntry*)extension->data,
15317 output + offset, msgType);
15318 break;
15319#endif
15320#ifdef WOLFSSL_TLS13
15321 case TLSX_SUPPORTED_VERSIONS:
15322 WOLFSSL_MSG("Supported Versions extension to write");
15323 cbShim = 0;
15324 ret = SV_WRITE(extension->data, output + offset, msgType,
15325 &cbShim);
15326 offset += cbShim;
15327 break;
15328
15329 case TLSX_COOKIE:
15330 WOLFSSL_MSG("Cookie extension to write");
15331 cbShim = 0;
15332 ret = CKE_WRITE((Cookie*)extension->data, output + offset,
15333 msgType, &cbShim);
15334 offset += cbShim;
15335 break;
15336
15337 #ifdef WOLFSSL_EARLY_DATA
15338 case TLSX_EARLY_DATA:
15339 WOLFSSL_MSG("Early Data extension to write");
15340 cbShim = 0;
15341 ret = EDI_WRITE(extension->val, output + offset, msgType,
15342 &cbShim);
15343 offset += cbShim;
15344 break;
15345 #endif
15346
15347 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
15348 case TLSX_POST_HANDSHAKE_AUTH:
15349 WOLFSSL_MSG("Post-Handshake Authentication extension to write");
15350 cbShim = 0;
15351 ret = PHA_WRITE(output + offset, msgType, &cbShim);
15352 offset += cbShim;
15353 break;
15354 #endif
15355
15356 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
15357 case TLSX_SIGNATURE_ALGORITHMS_CERT:
15358 WOLFSSL_MSG("Signature Algorithms extension to write");
15359 offset += SAC_WRITE(extension->data, output + offset);
15360 break;
15361 #endif
15362
15363 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
15364 case TLSX_CERTIFICATE_AUTHORITIES:
15365 WOLFSSL_MSG("Certificate Authorities extension to write");
15366 offset += CAN_WRITE(extension->data, output + offset);
15367 break;
15368 #endif
15369#endif
15370#ifdef WOLFSSL_SRTP
15371 case TLSX_USE_SRTP:
15372 WOLFSSL_MSG("SRTP extension to write");
15373 offset += SRTP_WRITE((TlsxSrtp*)extension->data, output+offset);
15374 break;
15375#endif
15376
15377#ifdef HAVE_RPK
15378 case TLSX_CLIENT_CERTIFICATE_TYPE:
15379 WOLFSSL_MSG("Client Certificate Type extension to write");
15380 offset += CCT_WRITE(extension->data, output + offset, msgType);
15381 break;
15382
15383 case TLSX_SERVER_CERTIFICATE_TYPE:
15384 WOLFSSL_MSG("Server Certificate Type extension to write");
15385 offset += SCT_WRITE(extension->data, output + offset, msgType);
15386 break;
15387#endif /* HAVE_RPK */
15388
15389#ifdef WOLFSSL_QUIC
15390 case TLSX_KEY_QUIC_TP_PARAMS:
15391 FALL_THROUGH;
15392 case TLSX_KEY_QUIC_TP_PARAMS_DRAFT:
15393 WOLFSSL_MSG("QUIC transport parameter to write");
15394 offset += QTP_WRITE((QuicTransportParam*)extension->data,
15395 output + offset);
15396 break;
15397#endif
15398#ifdef WOLFSSL_DTLS_CID
15399 case TLSX_CONNECTION_ID:
15400 WOLFSSL_MSG("Connection ID extension to write");
15401 offset += CID_WRITE((byte*)extension->data, output+offset);
15402 break;
15403
15404#endif /* WOLFSSL_DTLS_CID */
15405#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
15406 case TLSX_ECH:
15407 WOLFSSL_MSG("ECH extension to write");
15408 cbShim = 0;
15409 ret = ECH_WRITE((WOLFSSL_ECH*)extension->data, msgType,
15410 output + offset, &cbShim);
15411 offset += cbShim;
15412 break;
15413#endif
15414 default:
15415 break;
15416 }
15417
15418 /* Per-extension data length is a 2-byte wire field; reject any
15419 * single extension whose payload exceeds that before truncating. */
15420 if (offset - length_offset > WOLFSSL_MAX_16BIT) {
15421 WOLFSSL_MSG("TLSX_Write single extension length exceeds word16");
15422 return BUFFER_E;
15423 }
15424
15425 /* writes extension data length. */
15426 c16toa((word16)(offset - length_offset),
15427 output + length_offset - OPAQUE16_LEN);
15428
15429 /* marks the extension as processed so ctx level */
15430 /* extensions don't overlap with ssl level ones. */
15431 TURN_ON(semaphore, TLSX_ToSemaphore((word16)extension->type));
15432
15433 /* if we encountered an error propagate it */
15434 if (ret != 0)
15435 break;
15436
15437 if (offset <= prevOffset) {
15438 WOLFSSL_MSG("TLSX_Write extension made no progress");
15439 return BUFFER_E;
15440 }
15441 }
15442
15443 /* Only validate and commit the aggregate offset when the loop
15444 * completed without error; on the error path, leave *pOffset
15445 * unchanged and return the original failure reason so callers
15446 * see the real error instead of a masking BUFFER_E. */
15447 if (ret == 0) {
15448 if ((word32)*pOffset + offset > WOLFSSL_MAX_16BIT) {
15449 WOLFSSL_MSG("TLSX_Write total extensions length exceeds word16");
15450 return BUFFER_E;
15451 }
15452 *pOffset += (word16)offset;
15453 }
15454
15455 return ret;
15456}
15457
15458#ifdef HAVE_SUPPORTED_CURVES
15459
15460/* Populates the default supported groups / curves */
15461static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
15462{
15463 int ret = WOLFSSL_SUCCESS;
15464#ifdef WOLFSSL_TLS13
15465#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
15466 if (ssl->options.resuming && ssl->session->namedGroup != 0) {
15467 return TLSX_UseSupportedCurve(extensions, ssl->session->namedGroup,
15468 ssl->heap);
15469 }
15470#endif
15471
15472 if (ssl->numGroups != 0) {
15473 int i;
15474 for (i = 0; i < ssl->numGroups; i++) {
15475 ret = TLSX_UseSupportedCurve(extensions, ssl->group[i], ssl->heap);
15476 if (ret != WOLFSSL_SUCCESS)
15477 return ret;
15478 }
15479 return WOLFSSL_SUCCESS;
15480 }
15481#endif /* WOLFSSL_TLS13 */
15482
15483#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM) && \
15484 !defined(WOLFSSL_NO_ML_KEM) && defined(WOLFSSL_PQC_HYBRIDS)
15485 /* Prefer non-experimental PQ/T hybrid groups (only for TLS 1.3) */
15486 if (IsAtLeastTLSv1_3(ssl->version)) {
15487 #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE25519) && \
15488 ECC_MIN_KEY_SZ <= 256
15489 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM768,
15490 ssl->heap);
15491 if (ret != WOLFSSL_SUCCESS) return ret;
15492 #endif
15493 #if !defined(WOLFSSL_NO_ML_KEM_1024) && defined(HAVE_ECC) && \
15494 (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \
15495 ECC_MIN_KEY_SZ <= 384
15496 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM1024,
15497 ssl->heap);
15498 if (ret != WOLFSSL_SUCCESS) return ret;
15499 #endif
15500 #if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_ECC) && \
15501 (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \
15502 ECC_MIN_KEY_SZ <= 256
15503 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM768,
15504 ssl->heap);
15505 if (ret != WOLFSSL_SUCCESS) return ret;
15506 #endif
15507 }
15508#endif
15509
15510#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM) && \
15511 !defined(WOLFSSL_NO_ML_KEM) && !defined(WOLFSSL_NO_ML_KEM_1024) && \
15512 !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
15513 if (IsAtLeastTLSv1_3(ssl->version)) {
15514 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_1024,
15515 ssl->heap);
15516 if (ret != WOLFSSL_SUCCESS) return ret;
15517 }
15518#endif
15519
15520#if defined(HAVE_ECC)
15521 /* list in order by strength, since not all servers choose by strength */
15522 #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
15523 #ifndef NO_ECC_SECP
15524 ret = TLSX_UseSupportedCurve(extensions,
15525 WOLFSSL_ECC_SECP521R1, ssl->heap);
15526 if (ret != WOLFSSL_SUCCESS) return ret;
15527 #endif
15528 #endif
15529 #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
15530 #ifdef HAVE_ECC_BRAINPOOL
15531 if (IsAtLeastTLSv1_3(ssl->version)) {
15532 /* TLS 1.3 BrainpoolP512 curve */
15533 ret = TLSX_UseSupportedCurve(extensions,
15534 WOLFSSL_ECC_BRAINPOOLP512R1TLS13, ssl->heap);
15535 if (ret != WOLFSSL_SUCCESS) return ret;
15536
15537 /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */
15538 if (ssl->options.downgrade &&
15539 (ssl->options.minDowngrade <= TLSv1_2_MINOR ||
15540 ssl->options.minDowngrade <= DTLSv1_2_MINOR)) {
15541 ret = TLSX_UseSupportedCurve(extensions,
15542 WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap);
15543 if (ret != WOLFSSL_SUCCESS) return ret;
15544 }
15545 }
15546 else {
15547 /* TLS 1.2 only */
15548 ret = TLSX_UseSupportedCurve(extensions,
15549 WOLFSSL_ECC_BRAINPOOLP512R1, ssl->heap);
15550 if (ret != WOLFSSL_SUCCESS) return ret;
15551 }
15552 #endif
15553 #endif
15554#endif
15555
15556#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM) && \
15557 !defined(WOLFSSL_NO_ML_KEM) && !defined(WOLFSSL_NO_ML_KEM_768) && \
15558 !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
15559 if (IsAtLeastTLSv1_3(ssl->version)) {
15560 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_768,
15561 ssl->heap);
15562 if (ret != WOLFSSL_SUCCESS) return ret;
15563 }
15564#endif
15565
15566#if defined(HAVE_ECC)
15567 #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
15568 #ifndef NO_ECC_SECP
15569 ret = TLSX_UseSupportedCurve(extensions,
15570 WOLFSSL_ECC_SECP384R1, ssl->heap);
15571 if (ret != WOLFSSL_SUCCESS) return ret;
15572 #endif
15573 #ifdef HAVE_ECC_BRAINPOOL
15574 if (IsAtLeastTLSv1_3(ssl->version)) {
15575 /* TLS 1.3 BrainpoolP384 curve */
15576 ret = TLSX_UseSupportedCurve(extensions,
15577 WOLFSSL_ECC_BRAINPOOLP384R1TLS13, ssl->heap);
15578 if (ret != WOLFSSL_SUCCESS) return ret;
15579
15580 /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */
15581 if (ssl->options.downgrade &&
15582 (ssl->options.minDowngrade <= TLSv1_2_MINOR ||
15583 ssl->options.minDowngrade <= DTLSv1_2_MINOR)) {
15584 ret = TLSX_UseSupportedCurve(extensions,
15585 WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap);
15586 if (ret != WOLFSSL_SUCCESS) return ret;
15587 }
15588 }
15589 else {
15590 /* TLS 1.2 only */
15591 ret = TLSX_UseSupportedCurve(extensions,
15592 WOLFSSL_ECC_BRAINPOOLP384R1, ssl->heap);
15593 if (ret != WOLFSSL_SUCCESS) return ret;
15594 }
15595 #endif
15596 #endif
15597#endif /* HAVE_ECC */
15598
15599#ifndef HAVE_FIPS
15600 #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
15601 ret = TLSX_UseSupportedCurve(extensions,
15602 WOLFSSL_ECC_X448, ssl->heap);
15603 if (ret != WOLFSSL_SUCCESS) return ret;
15604 #endif
15605#endif /* HAVE_FIPS */
15606
15607#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM) && \
15608 !defined(WOLFSSL_NO_ML_KEM) && !defined(WOLFSSL_NO_ML_KEM_512) && \
15609 !defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE)
15610 if (IsAtLeastTLSv1_3(ssl->version)) {
15611 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_512,
15612 ssl->heap);
15613 if (ret != WOLFSSL_SUCCESS) return ret;
15614 }
15615#endif
15616
15617#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
15618 #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
15619 #ifndef NO_ECC_SECP
15620 ret = TLSX_UseSupportedCurve(extensions,
15621 WOLFSSL_ECC_SECP256R1, ssl->heap);
15622 if (ret != WOLFSSL_SUCCESS) return ret;
15623 #endif
15624 #ifdef HAVE_ECC_KOBLITZ
15625 ret = TLSX_UseSupportedCurve(extensions,
15626 WOLFSSL_ECC_SECP256K1, ssl->heap);
15627 if (ret != WOLFSSL_SUCCESS) return ret;
15628 #endif
15629 #ifdef HAVE_ECC_BRAINPOOL
15630 if (IsAtLeastTLSv1_3(ssl->version)) {
15631 /* TLS 1.3 BrainpoolP256 curve */
15632 ret = TLSX_UseSupportedCurve(extensions,
15633 WOLFSSL_ECC_BRAINPOOLP256R1TLS13, ssl->heap);
15634 if (ret != WOLFSSL_SUCCESS) return ret;
15635
15636 /* If TLS 1.2 is allowed, also add the TLS 1.2 curve */
15637 if (ssl->options.downgrade &&
15638 (ssl->options.minDowngrade <= TLSv1_2_MINOR ||
15639 ssl->options.minDowngrade <= DTLSv1_2_MINOR)) {
15640 ret = TLSX_UseSupportedCurve(extensions,
15641 WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap);
15642 if (ret != WOLFSSL_SUCCESS) return ret;
15643 }
15644 }
15645 else {
15646 /* TLS 1.2 only */
15647 ret = TLSX_UseSupportedCurve(extensions,
15648 WOLFSSL_ECC_BRAINPOOLP256R1, ssl->heap);
15649 if (ret != WOLFSSL_SUCCESS) return ret;
15650 }
15651 #endif
15652 #ifdef WOLFSSL_SM2
15653 ret = TLSX_UseSupportedCurve(extensions,
15654 WOLFSSL_ECC_SM2P256V1, ssl->heap);
15655 if (ret != WOLFSSL_SUCCESS) return ret;
15656 #endif
15657 #endif
15658#endif /* HAVE_ECC */
15659
15660#ifndef HAVE_FIPS
15661 #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
15662 ret = TLSX_UseSupportedCurve(extensions,
15663 WOLFSSL_ECC_X25519, ssl->heap);
15664 if (ret != WOLFSSL_SUCCESS) return ret;
15665 #endif
15666#endif /* HAVE_FIPS */
15667
15668#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
15669 #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
15670 #ifndef NO_ECC_SECP
15671 ret = TLSX_UseSupportedCurve(extensions,
15672 WOLFSSL_ECC_SECP224R1, ssl->heap);
15673 if (ret != WOLFSSL_SUCCESS) return ret;
15674 #endif
15675 #ifdef HAVE_ECC_KOBLITZ
15676 ret = TLSX_UseSupportedCurve(extensions,
15677 WOLFSSL_ECC_SECP224K1, ssl->heap);
15678 if (ret != WOLFSSL_SUCCESS) return ret;
15679 #endif
15680 #endif
15681
15682 #ifndef HAVE_FIPS
15683 #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
15684 #ifndef NO_ECC_SECP
15685 ret = TLSX_UseSupportedCurve(extensions,
15686 WOLFSSL_ECC_SECP192R1, ssl->heap);
15687 if (ret != WOLFSSL_SUCCESS) return ret;
15688 #endif
15689 #ifdef HAVE_ECC_KOBLITZ
15690 ret = TLSX_UseSupportedCurve(extensions,
15691 WOLFSSL_ECC_SECP192K1, ssl->heap);
15692 if (ret != WOLFSSL_SUCCESS) return ret;
15693 #endif
15694 #endif
15695 #if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
15696 #ifndef NO_ECC_SECP
15697 ret = TLSX_UseSupportedCurve(extensions,
15698 WOLFSSL_ECC_SECP160R1, ssl->heap);
15699 if (ret != WOLFSSL_SUCCESS) return ret;
15700 #endif
15701 #ifdef HAVE_ECC_SECPR2
15702 ret = TLSX_UseSupportedCurve(extensions,
15703 WOLFSSL_ECC_SECP160R2, ssl->heap);
15704 if (ret != WOLFSSL_SUCCESS) return ret;
15705 #endif
15706 #ifdef HAVE_ECC_KOBLITZ
15707 ret = TLSX_UseSupportedCurve(extensions,
15708 WOLFSSL_ECC_SECP160K1, ssl->heap);
15709 if (ret != WOLFSSL_SUCCESS) return ret;
15710 #endif
15711 #endif
15712 #endif /* HAVE_FIPS */
15713#endif /* HAVE_ECC */
15714
15715#ifndef NO_DH
15716 /* Add FFDHE supported groups. */
15717 #ifdef HAVE_FFDHE_8192
15718 if (8192/8 >= ssl->options.minDhKeySz &&
15719 8192/8 <= ssl->options.maxDhKeySz) {
15720 ret = TLSX_UseSupportedCurve(extensions,
15721 WOLFSSL_FFDHE_8192, ssl->heap);
15722 if (ret != WOLFSSL_SUCCESS)
15723 return ret;
15724 }
15725 #endif
15726 #ifdef HAVE_FFDHE_6144
15727 if (6144/8 >= ssl->options.minDhKeySz &&
15728 6144/8 <= ssl->options.maxDhKeySz) {
15729 ret = TLSX_UseSupportedCurve(extensions,
15730 WOLFSSL_FFDHE_6144, ssl->heap);
15731 if (ret != WOLFSSL_SUCCESS)
15732 return ret;
15733 }
15734 #endif
15735 #ifdef HAVE_FFDHE_4096
15736 if (4096/8 >= ssl->options.minDhKeySz &&
15737 4096/8 <= ssl->options.maxDhKeySz) {
15738 ret = TLSX_UseSupportedCurve(extensions,
15739 WOLFSSL_FFDHE_4096, ssl->heap);
15740 if (ret != WOLFSSL_SUCCESS)
15741 return ret;
15742 }
15743 #endif
15744 #ifdef HAVE_FFDHE_3072
15745 if (3072/8 >= ssl->options.minDhKeySz &&
15746 3072/8 <= ssl->options.maxDhKeySz) {
15747 ret = TLSX_UseSupportedCurve(extensions,
15748 WOLFSSL_FFDHE_3072, ssl->heap);
15749 if (ret != WOLFSSL_SUCCESS)
15750 return ret;
15751 }
15752 #endif
15753 #ifdef HAVE_FFDHE_2048
15754 if (2048/8 >= ssl->options.minDhKeySz &&
15755 2048/8 <= ssl->options.maxDhKeySz) {
15756 ret = TLSX_UseSupportedCurve(extensions,
15757 WOLFSSL_FFDHE_2048, ssl->heap);
15758 if (ret != WOLFSSL_SUCCESS)
15759 return ret;
15760 }
15761 #endif
15762#endif
15763
15764#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM) && \
15765 !defined(WOLFSSL_NO_ML_KEM) && defined(WOLFSSL_EXTRA_PQC_HYBRIDS)
15766 if (IsAtLeastTLSv1_3(ssl->version)) {
15767#if !defined(WOLFSSL_NO_ML_KEM_1024) && defined(HAVE_ECC) && \
15768 (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
15769 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP521R1MLKEM1024,
15770 ssl->heap);
15771 if (ret != WOLFSSL_SUCCESS) return ret;
15772#endif
15773#if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_ECC) && \
15774 (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
15775 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP384R1MLKEM768,
15776 ssl->heap);
15777 if (ret != WOLFSSL_SUCCESS) return ret;
15778#endif
15779#if !defined(WOLFSSL_NO_ML_KEM_768) && defined(HAVE_CURVE448) && \
15780 ECC_MIN_KEY_SZ <= 448
15781 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448MLKEM768,
15782 ssl->heap);
15783 if (ret != WOLFSSL_SUCCESS) return ret;
15784#endif
15785#if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_ECC) && \
15786 (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
15787 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_SECP256R1MLKEM512,
15788 ssl->heap);
15789 if (ret != WOLFSSL_SUCCESS) return ret;
15790#endif
15791#if !defined(WOLFSSL_NO_ML_KEM_512) && defined(HAVE_CURVE25519) && \
15792 ECC_MIN_KEY_SZ <= 256
15793 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519MLKEM512,
15794 ssl->heap);
15795 if (ret != WOLFSSL_SUCCESS) return ret;
15796#endif
15797 }
15798#endif
15799
15800#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM) && \
15801 defined(WOLFSSL_MLKEM_KYBER)
15802 if (IsAtLeastTLSv1_3(ssl->version)) {
15803#ifdef WOLFSSL_KYBER1024
15804 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL5,
15805 ssl->heap);
15806 if (ret != WOLFSSL_SUCCESS) return ret;
15807#if defined(HAVE_ECC) && (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && \
15808 ECC_MIN_KEY_SZ <= 521
15809 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_LEVEL5,
15810 ssl->heap);
15811 if (ret != WOLFSSL_SUCCESS) return ret;
15812#endif
15813#endif
15814#ifdef WOLFSSL_KYBER768
15815 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL3,
15816 ssl->heap);
15817 if (ret != WOLFSSL_SUCCESS) return ret;
15818#if defined(HAVE_ECC) && (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \
15819 ECC_MIN_KEY_SZ <= 384
15820 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_KYBER_LEVEL3,
15821 ssl->heap);
15822 if (ret != WOLFSSL_SUCCESS) return ret;
15823#endif
15824#if defined(HAVE_ECC) && (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \
15825 ECC_MIN_KEY_SZ <= 256
15826 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL3,
15827 ssl->heap);
15828 if (ret != WOLFSSL_SUCCESS) return ret;
15829#endif
15830#if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
15831 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL3,
15832 ssl->heap);
15833 if (ret != WOLFSSL_SUCCESS) return ret;
15834#endif
15835#if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448
15836 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448_KYBER_LEVEL3,
15837 ssl->heap);
15838 if (ret != WOLFSSL_SUCCESS) return ret;
15839#endif
15840#endif
15841#ifdef WOLFSSL_KYBER512
15842 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1,
15843 ssl->heap);
15844 if (ret != WOLFSSL_SUCCESS) return ret;
15845#if defined(HAVE_ECC) && (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \
15846 ECC_MIN_KEY_SZ <= 256
15847 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL1,
15848 ssl->heap);
15849 if (ret != WOLFSSL_SUCCESS) return ret;
15850#endif
15851#if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256
15852 ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL1,
15853 ssl->heap);
15854 if (ret != WOLFSSL_SUCCESS) return ret;
15855#endif
15856#endif
15857 }
15858#endif
15859
15860 (void)ssl;
15861 (void)extensions;
15862
15863 return ret;
15864}
15865
15866#endif /* HAVE_SUPPORTED_CURVES */
15867
15868int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
15869{
15870 int ret = 0;
15871 byte* public_key = NULL;
15872 word16 public_key_len = 0;
15873#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
15874 int usingPSK = 0;
15875#endif
15876#if defined(HAVE_SUPPORTED_CURVES) && defined(WOLFSSL_TLS13)
15877 TLSX* extension = NULL;
15878 word16 namedGroup = WOLFSSL_NAMED_GROUP_INVALID;
15879#endif
15880
15881 /* server will add extension depending on what is parsed from client */
15882 if (!isServer) {
15883#if defined(HAVE_RPK)
15884 ret = TLSX_ClientCertificateType_Use(ssl, isServer);
15885 if (ret != 0)
15886 return ret;
15887
15888 ret = TLSX_ServerCertificateType_Use(ssl, isServer);
15889 if (ret != 0)
15890 return ret;
15891#endif /* HAVE_RPK */
15892
15893#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY) && \
15894 !defined(WOLFSSL_NO_TLS12)
15895 if (!ssl->options.disallowEncThenMac) {
15896 ret = TLSX_EncryptThenMac_Use(ssl);
15897 if (ret != 0)
15898 return ret;
15899 }
15900#endif
15901
15902#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
15903 defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES)
15904 if (!ssl->options.userCurves && !ssl->ctx->userCurves) {
15905 if (TLSX_Find(ssl->ctx->extensions,
15906 TLSX_SUPPORTED_GROUPS) == NULL) {
15907 ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions);
15908 if (ret != WOLFSSL_SUCCESS)
15909 return ret;
15910 }
15911 }
15912 if ((!IsAtLeastTLSv1_3(ssl->version) || ssl->options.downgrade) &&
15913 TLSX_Find(ssl->ctx->extensions, TLSX_EC_POINT_FORMATS) == NULL &&
15914 TLSX_Find(ssl->extensions, TLSX_EC_POINT_FORMATS) == NULL) {
15915 ret = TLSX_UsePointFormat(&ssl->extensions,
15916 WOLFSSL_EC_PF_UNCOMPRESSED, ssl->heap);
15917 if (ret != WOLFSSL_SUCCESS)
15918 return ret;
15919 }
15920#endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
15921
15922#ifdef WOLFSSL_SRTP
15923 if (ssl->options.dtls && ssl->dtlsSrtpProfiles != 0) {
15924 WOLFSSL_MSG("Adding DTLS SRTP extension");
15925 if ((ret = TLSX_UseSRTP(&ssl->extensions, ssl->dtlsSrtpProfiles,
15926 ssl->heap)) != 0) {
15927 return ret;
15928 }
15929 }
15930#endif
15931#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DUAL_ALG_CERTS)
15932 if ((IsAtLeastTLSv1_3(ssl->version)) && (ssl->sigSpec != NULL)) {
15933 WOLFSSL_MSG("Adding CKS extension");
15934 if ((ret = TLSX_UseCKS(&ssl->extensions, ssl, ssl->heap)) != 0) {
15935 return ret;
15936 }
15937 }
15938#endif
15939 } /* is not server */
15940
15941#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
15942 WOLFSSL_MSG("Adding signature algorithms extension");
15943 if ((ret = TLSX_SetSignatureAlgorithms(&ssl->extensions, ssl, ssl->heap))
15944 != 0) {
15945 return ret;
15946 }
15947#else
15948 ret = 0;
15949#endif
15950#ifdef WOLFSSL_TLS13
15951 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
15952 if (IsAtLeastTLSv1_3(ssl->version) &&
15953 SSL_PRIORITY_CA_NAMES(ssl) != NULL) {
15954 WOLFSSL_MSG("Adding certificate authorities extension");
15955 if ((ret = TLSX_Push(&ssl->extensions,
15956 TLSX_CERTIFICATE_AUTHORITIES, ssl, ssl->heap)) != 0) {
15957 return ret;
15958 }
15959 }
15960 #endif
15961 if (!isServer && IsAtLeastTLSv1_3(ssl->version)) {
15962 /* Add mandatory TLS v1.3 extension: supported version */
15963 WOLFSSL_MSG("Adding supported versions extension");
15964 if ((ret = TLSX_SetSupportedVersions(&ssl->extensions, ssl,
15965 ssl->heap)) != 0) {
15966 return ret;
15967 }
15968
15969 #if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && \
15970 !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)
15971 if (TLSX_Find(ssl->ctx->extensions, TLSX_SUPPORTED_GROUPS) == NULL) {
15972 /* Put in DH groups for TLS 1.3 only. */
15973 ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions);
15974 if (ret != WOLFSSL_SUCCESS)
15975 return ret;
15976 /* ret value will be overwritten in !NO_PSK case */
15977 #ifdef NO_PSK
15978 ret = 0;
15979 #endif
15980 }
15981 #endif /* !(HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
15982
15983 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
15984 if (ssl->certHashSigAlgoSz > 0) {
15985 WOLFSSL_MSG("Adding signature algorithms cert extension");
15986 if ((ret = TLSX_SetSignatureAlgorithmsCert(&ssl->extensions,
15987 ssl, ssl->heap)) != 0) {
15988 return ret;
15989 }
15990 }
15991 #endif
15992
15993 #if defined(HAVE_SUPPORTED_CURVES)
15994 extension = TLSX_Find(ssl->extensions, TLSX_KEY_SHARE);
15995 if (extension == NULL) {
15996 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
15997 if (ssl->options.resuming && ssl->session->namedGroup != 0)
15998 namedGroup = ssl->session->namedGroup;
15999 else
16000 #endif
16001 if (ssl->numGroups > 0) {
16002 int set = 0;
16003 int i, j;
16004
16005 /* try to find the highest element in ssl->group[]
16006 * that is contained in preferredGroup[].
16007 */
16008 namedGroup = preferredGroup[0];
16009 for (i = 0; i < ssl->numGroups && !set; i++) {
16010 for (j = 0; preferredGroup[j] != WOLFSSL_NAMED_GROUP_INVALID; j++) {
16011 if (preferredGroup[j] == ssl->group[i]) {
16012 namedGroup = ssl->group[i];
16013 set = 1;
16014 break;
16015 }
16016 }
16017 }
16018 if (!set)
16019 namedGroup = WOLFSSL_NAMED_GROUP_INVALID;
16020 }
16021 else {
16022 /* Choose the most preferred group. */
16023 namedGroup = preferredGroup[0];
16024 }
16025 }
16026 else {
16027 KeyShareEntry* kse = (KeyShareEntry*)extension->data;
16028 if (kse)
16029 namedGroup = kse->group;
16030 }
16031 if (namedGroup != WOLFSSL_NAMED_GROUP_INVALID) {
16032 ret = TLSX_KeyShare_Use(ssl, namedGroup, 0, NULL, NULL,
16033 &ssl->extensions);
16034 if (ret != 0)
16035 return ret;
16036 }
16037 #endif /* HAVE_SUPPORTED_CURVES */
16038
16039 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16040 TLSX_Remove(&ssl->extensions, TLSX_PRE_SHARED_KEY, ssl->heap);
16041 #endif
16042 #if defined(HAVE_SESSION_TICKET)
16043 if (ssl->options.resuming && ssl->session->ticketLen > 0
16044 #if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
16045 && !ssl->options.certWithExternPsk
16046 #endif
16047 ) {
16048 WOLFSSL_SESSION* sess = ssl->session;
16049 #ifdef WOLFSSL_32BIT_MILLI_TIME
16050 word32 now, milli;
16051 #else
16052 word64 now, milli;
16053 #endif
16054
16055 /* Determine the MAC algorithm for the cipher suite used. */
16056 ssl->options.cipherSuite0 = sess->cipherSuite0;
16057 ssl->options.cipherSuite = sess->cipherSuite;
16058 ret = SetCipherSpecs(ssl);
16059 if (ret != 0)
16060 return ret;
16061 now = (word64)TimeNowInMilliseconds();
16062 if (now == 0)
16063 return GETTIME_ERROR;
16064 #ifdef WOLFSSL_32BIT_MILLI_TIME
16065 if (now < sess->ticketSeen)
16066 milli = (0xFFFFFFFFU - sess->ticketSeen) + 1 + now;
16067 else
16068 milli = now - sess->ticketSeen;
16069 milli += sess->ticketAdd;
16070
16071 /* Pre-shared key is mandatory extension for resumption. */
16072 ret = TLSX_PreSharedKey_Use(&ssl->extensions, sess->ticket,
16073 sess->ticketLen, milli, ssl->specs.mac_algorithm,
16074 ssl->options.cipherSuite0, ssl->options.cipherSuite, 1,
16075 NULL, ssl->heap);
16076 #else
16077 milli = now - sess->ticketSeen + sess->ticketAdd;
16078
16079 /* Pre-shared key is mandatory extension for resumption. */
16080 ret = TLSX_PreSharedKey_Use(&ssl->extensions, sess->ticket,
16081 sess->ticketLen, (word32)milli, ssl->specs.mac_algorithm,
16082 ssl->options.cipherSuite0, ssl->options.cipherSuite, 1,
16083 NULL, ssl->heap);
16084 #endif
16085 if (ret != 0)
16086 return ret;
16087
16088 usingPSK = 1;
16089 }
16090 #endif
16091 #ifndef NO_PSK
16092 #ifndef WOLFSSL_PSK_ONE_ID
16093 if (ssl->options.client_psk_cs_cb != NULL) {
16094 int i;
16095 const Suites* suites = WOLFSSL_SUITES(ssl);
16096 for (i = 0; i < suites->suiteSz; i += 2) {
16097 byte cipherSuite0 = suites->suites[i + 0];
16098 byte cipherSuite = suites->suites[i + 1];
16099 unsigned int keySz;
16100 #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS
16101 int cnt = 0;
16102 #endif
16103
16104 #ifdef HAVE_NULL_CIPHER
16105 if (cipherSuite0 == ECC_BYTE ||
16106 cipherSuite0 == ECDHE_PSK_BYTE) {
16107 if (cipherSuite != TLS_SHA256_SHA256 &&
16108 cipherSuite != TLS_SHA384_SHA384) {
16109 continue;
16110 }
16111 }
16112 else
16113 #endif
16114 #if (defined(WOLFSSL_SM4_GCM) || defined(WOLFSSL_SM4_CCM)) && \
16115 defined(WOLFSSL_SM3)
16116 if (cipherSuite0 == CIPHER_BYTE) {
16117 if ((cipherSuite != TLS_SM4_GCM_SM3) &&
16118 (cipherSuite != TLS_SM4_CCM_SM3)) {
16119 continue;
16120 }
16121 }
16122 else
16123 #endif
16124 if (cipherSuite0 != TLS13_BYTE)
16125 continue;
16126
16127 #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS
16128 do {
16129 ssl->arrays->client_identity[0] = cnt;
16130 #endif
16131
16132 ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
16133 keySz = ssl->options.client_psk_cs_cb(
16134 ssl, ssl->arrays->server_hint,
16135 ssl->arrays->client_identity, MAX_PSK_ID_LEN,
16136 ssl->arrays->psk_key, MAX_PSK_KEY_LEN,
16137 GetCipherNameInternal(cipherSuite0, cipherSuite));
16138 if (keySz > 0) {
16139 ssl->arrays->psk_keySz = keySz;
16140 ret = TLSX_PreSharedKey_Use(&ssl->extensions,
16141 (byte*)ssl->arrays->client_identity,
16142 (word16)XSTRLEN(ssl->arrays->client_identity),
16143 0, SuiteMac(WOLFSSL_SUITES(ssl)->suites + i),
16144 cipherSuite0, cipherSuite, 0, NULL, ssl->heap);
16145 if (ret != 0)
16146 return ret;
16147 #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS
16148 cnt++;
16149 #endif
16150 }
16151 #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS
16152 }
16153 while (keySz > 0);
16154 #endif
16155 }
16156
16157 usingPSK = 1;
16158 }
16159 else
16160 #endif
16161 if (ssl->options.client_psk_cb != NULL ||
16162 ssl->options.client_psk_tls13_cb != NULL) {
16163 /* Default cipher suite. */
16164 byte cipherSuite0 = TLS13_BYTE;
16165 byte cipherSuite = WOLFSSL_DEF_PSK_CIPHER;
16166 int cipherSuiteFlags = WOLFSSL_CIPHER_SUITE_FLAG_NONE;
16167 const char* cipherName = NULL;
16168
16169 if (ssl->options.client_psk_tls13_cb != NULL) {
16170 ssl->arrays->psk_keySz = ssl->options.client_psk_tls13_cb(
16171 ssl, ssl->arrays->server_hint,
16172 ssl->arrays->client_identity, MAX_PSK_ID_LEN,
16173 ssl->arrays->psk_key, MAX_PSK_KEY_LEN, &cipherName);
16174 if (GetCipherSuiteFromName(cipherName, &cipherSuite0,
16175 &cipherSuite, NULL, NULL, &cipherSuiteFlags) != 0) {
16176 return PSK_KEY_ERROR;
16177 }
16178 }
16179 else {
16180 ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
16181 ssl->arrays->server_hint, ssl->arrays->client_identity,
16182 MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
16183 }
16184 if (
16185 #ifdef OPENSSL_EXTRA
16186 /* OpenSSL treats a PSK key length of 0
16187 * to indicate no PSK available.
16188 */
16189 ssl->arrays->psk_keySz == 0 ||
16190 #endif
16191 (ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN &&
16192 (int)ssl->arrays->psk_keySz != WC_NO_ERR_TRACE(USE_HW_PSK))) {
16193 #ifndef OPENSSL_EXTRA
16194 ret = PSK_KEY_ERROR;
16195 #endif
16196 }
16197 else {
16198 ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
16199
16200 ssl->options.cipherSuite0 = cipherSuite0;
16201 ssl->options.cipherSuite = cipherSuite;
16202 (void)cipherSuiteFlags;
16203 ret = SetCipherSpecs(ssl);
16204 if (ret == 0) {
16205 ret = TLSX_PreSharedKey_Use(
16206 &ssl->extensions,
16207 (byte*)ssl->arrays->client_identity,
16208 (word16)XSTRLEN(ssl->arrays->client_identity),
16209 0, ssl->specs.mac_algorithm,
16210 cipherSuite0, cipherSuite, 0,
16211 NULL, ssl->heap);
16212 }
16213 if (ret == 0)
16214 usingPSK = 1;
16215 }
16216 if (ret != 0)
16217 return ret;
16218 }
16219 #endif /* !NO_PSK */
16220 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16221
16222 /* Some servers do not generate session tickets unless
16223 * the extension is seen in a non-resume client hello.
16224 * We used to send it only if we were otherwise using PSK.
16225 * Now always send it. Define NO_TLSX_PSKKEM_PLAIN_ANNOUNCE
16226 * to revert to the old behaviour. */
16227 #ifdef NO_TLSX_PSKKEM_PLAIN_ANNOUNCE
16228 if (usingPSK)
16229 #endif
16230 {
16231 byte modes = 0;
16232
16233 (void)usingPSK;
16234 /* Pre-shared key modes: mandatory extension for resumption. */
16235 #ifdef HAVE_SUPPORTED_CURVES
16236 if (!ssl->options.onlyPskDheKe)
16237 #endif
16238 {
16239 modes = 1 << PSK_KE;
16240 }
16241 #if !defined(NO_DH) || defined(HAVE_ECC) || \
16242 defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
16243 if (!ssl->options.noPskDheKe) {
16244 modes |= 1 << PSK_DHE_KE;
16245 }
16246 #endif
16247 #if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
16248 if (ssl->options.certWithExternPsk) {
16249 /* RFC8773bis requires psk_dhe_ke with cert_with_extern_psk. */
16250 modes |= 1 << PSK_DHE_KE;
16251 }
16252 #endif
16253 ret = TLSX_PskKeyModes_Use(ssl, modes);
16254 if (ret != 0)
16255 return ret;
16256 }
16257
16258 #if defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
16259 if (usingPSK && ssl->options.certWithExternPsk) {
16260 ret = TLSX_CertWithExternPsk_Use(ssl);
16261 if (ret != 0)
16262 return ret;
16263 /* Require server confirmation before using cert-with-PSK path. */
16264 ssl->options.certWithExternPsk = 0;
16265 }
16266 #endif
16267 #endif
16268 #if defined(WOLFSSL_POST_HANDSHAKE_AUTH)
16269 if (!isServer && ssl->options.postHandshakeAuth) {
16270 ret = TLSX_PostHandAuth_Use(ssl);
16271 if (ret != 0)
16272 return ret;
16273 }
16274 #endif
16275#if defined(HAVE_ECH)
16276 /* GREASE ECH */
16277 if (!ssl->options.disableECH) {
16278 if (ssl->echConfigs == NULL) {
16279 ret = GREASE_ECH_USE(&(ssl->extensions), ssl->heap,
16280 ssl->rng);
16281 }
16282 else if (ssl->echConfigs != NULL) {
16283 ret = ECH_USE(ssl->echConfigs, &(ssl->extensions),
16284 ssl->heap, ssl->rng);
16285 }
16286 }
16287#endif
16288 }
16289#if defined(HAVE_ECH)
16290 else if (IsAtLeastTLSv1_3(ssl->version)) {
16291 if (ssl->ctx->echConfigs != NULL && !ssl->options.disableECH) {
16292 ret = SERVER_ECH_USE(&(ssl->extensions), ssl->heap,
16293 ssl->ctx->echConfigs);
16294
16295 if (ret == 0)
16296 TLSX_SetResponse(ssl, TLSX_ECH);
16297 }
16298 }
16299#endif
16300
16301#endif
16302
16303 (void)isServer;
16304 (void)public_key;
16305 (void)public_key_len;
16306 (void)ssl;
16307
16308 return ret;
16309}
16310
16311
16312#if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT)
16313
16314#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
16315static int TLSX_EchChangeSNI(WOLFSSL* ssl, TLSX** pEchX,
16316 char* serverName, TLSX** pServerNameX,
16317 TLSX*** pExtensions)
16318{
16319 int ret = 0;
16320 TLSX* echX = NULL;
16321 TLSX* serverNameX = NULL;
16322 TLSX** extensions = NULL;
16323
16324 /* calculate the rest of the extensions length with inner ech */
16325 if (ssl->extensions)
16326 echX = TLSX_Find(ssl->extensions, TLSX_ECH);
16327
16328 if (echX == NULL && ssl->ctx && ssl->ctx->extensions)
16329 /* if not NULL the semaphore will stop it from being counted */
16330 echX = TLSX_Find(ssl->ctx->extensions, TLSX_ECH);
16331
16332 /* if type is outer change sni to public name */
16333 if (echX != NULL &&
16334 ((WOLFSSL_ECH*)echX->data)->type == ECH_TYPE_OUTER &&
16335 (ssl->options.echAccepted ||
16336 ((WOLFSSL_ECH*)echX->data)->innerCount == 0)) {
16337 if (ssl->extensions) {
16338 serverNameX = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME);
16339
16340 if (serverNameX != NULL)
16341 extensions = &ssl->extensions;
16342 }
16343
16344 if (serverNameX == NULL && ssl->ctx && ssl->ctx->extensions) {
16345 serverNameX = TLSX_Find(ssl->ctx->extensions, TLSX_SERVER_NAME);
16346 if (serverNameX != NULL)
16347 extensions = &ssl->ctx->extensions;
16348 }
16349
16350 /* ECH requires an inner SNI to be present for ClientHelloInner.
16351 * Without it, fail instead of mutating extension lists. */
16352 if (serverNameX == NULL) {
16353 ret = BAD_FUNC_ARG;
16354 }
16355
16356 /* store the inner server name */
16357 if (ret == 0 && serverNameX != NULL) {
16358 char* hostName = ((SNI*)serverNameX->data)->data.host_name;
16359 word32 hostNameSz = (word32)XSTRLEN(hostName) + 1;
16360
16361 if (hostNameSz > WOLFSSL_HOST_NAME_MAX)
16362 ret = BAD_LENGTH_E;
16363 else
16364 XMEMCPY(serverName, hostName, hostNameSz);
16365 }
16366
16367 /* only swap the SNI if one was found; extensions is non-NULL if an
16368 * SNI entry was found on ssl->extensions or ctx->extensions */
16369 if (ret == 0 && extensions != NULL) {
16370 /* remove the inner server name */
16371 TLSX_Remove(extensions, TLSX_SERVER_NAME, ssl->heap);
16372
16373 /* set the public name as the server name */
16374 if ((ret = TLSX_UseSNI(extensions, WOLFSSL_SNI_HOST_NAME,
16375 ((WOLFSSL_ECH*)echX->data)->echConfig->publicName,
16376 XSTRLEN(((WOLFSSL_ECH*)echX->data)->echConfig->publicName),
16377 ssl->heap)) == WOLFSSL_SUCCESS)
16378 ret = 0;
16379 }
16380 }
16381 *pServerNameX = serverNameX;
16382 *pExtensions = extensions;
16383 *pEchX = echX;
16384 return ret;
16385}
16386
16387static int TLSX_EchRestoreSNI(WOLFSSL* ssl, char* serverName,
16388 TLSX* serverNameX, TLSX** extensions)
16389{
16390 int ret = 0;
16391
16392 /* always remove the publicName SNI we injected, regardless of whether
16393 * there was a prior inner SNI to restore */
16394 if (extensions != NULL)
16395 TLSX_Remove(extensions, TLSX_SERVER_NAME, ssl->heap);
16396
16397 if (serverNameX != NULL) {
16398 /* restore the inner server name */
16399 ret = TLSX_UseSNI(extensions, WOLFSSL_SNI_HOST_NAME,
16400 serverName, XSTRLEN(serverName), ssl->heap);
16401
16402 if (ret == WOLFSSL_SUCCESS)
16403 ret = 0;
16404 }
16405 return ret;
16406}
16407
16408/* Returns 1 if the extension may be encoded into ech_outer_extensions,
16409 * 0 otherwise */
16410static int TLSX_ECH_IsEncodable(word16 type)
16411{
16412 /* supported_versions being here prevents the inner hello from advertising
16413 * a version less than TLS1.3 */
16414 switch (type) {
16415 case TLSX_SERVER_NAME:
16416 case TLSX_APPLICATION_LAYER_PROTOCOL:
16417 case TLSX_SUPPORTED_VERSIONS:
16418 case TLSX_ECH:
16419#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16420 case TLSX_PRE_SHARED_KEY:
16421#endif
16422#ifdef WOLFSSL_EARLY_DATA
16423 case TLSX_EARLY_DATA:
16424#endif
16425 return 0;
16426 default:
16427 return 1;
16428 }
16429}
16430
16431/* find extensions that can be encoded into ech_outer_extensions.
16432 * If output is non-NULL, then write the encoded form.
16433 *
16434 * Layout of OuterExtensions (RFC 9849, S5.1):
16435 * 2-byte extension_type + 2-byte extension_data length +
16436 * 1-byte list length + 2*count bytes of extension types
16437 */
16438static int TLSX_ECH_BuildOuterExtensions(WOLFSSL* ssl, const byte* semaphore,
16439 byte msgType, byte* output, word16* pOffset, word16* outCount,
16440 byte* encodeMask)
16441{
16442 TLSX* list;
16443 TLSX* extension;
16444 byte* typesStart = NULL;
16445 int listIdx;
16446 word16 count = 0;
16447 byte isRequest = (msgType == client_hello ||
16448 msgType == certificate_request);
16449 byte seen[SEMAPHORE_SIZE];
16450
16451 /* backup semaphore so it can be aliased by encodeMask */
16452 XMEMCPY(seen, semaphore, SEMAPHORE_SIZE);
16453
16454 if (output != NULL && pOffset != NULL) {
16455 typesStart = output + *pOffset
16456 + HELLO_EXT_TYPE_SZ + OPAQUE16_LEN + OPAQUE8_LEN;
16457 }
16458
16459 for (listIdx = 0; listIdx < 2; listIdx++) {
16460 list = (listIdx == 0) ? ssl->extensions :
16461 (ssl->ctx != NULL ? ssl->ctx->extensions : NULL);
16462 for (extension = list; extension != NULL; extension = extension->next) {
16463 word16 type = (word16)extension->type;
16464 word16 semIdx = TLSX_ToSemaphore(type);
16465
16466 /* OuterExtensions is <2..254>, so reference at most 127 types */
16467 if (count >= 127) {
16468 WOLFSSL_MSG("ECH: cannot encode more than 127 extensions");
16469 break;
16470 }
16471
16472 if (!isRequest && !extension->resp)
16473 continue;
16474 if (!IS_OFF(seen, semIdx))
16475 continue;
16476 TURN_ON(seen, semIdx);
16477 if (!TLSX_ECH_IsEncodable(type))
16478 continue;
16479
16480 if (typesStart != NULL)
16481 c16toa(type, typesStart + count * OPAQUE16_LEN);
16482 count++;
16483 TURN_ON(encodeMask, semIdx);
16484 }
16485 }
16486
16487 if (count > 0 && pOffset != NULL) {
16488 word16 listLen = (word16)(OPAQUE16_LEN * count);
16489 word16 blockSz = (word16)(HELLO_EXT_TYPE_SZ + OPAQUE16_LEN
16490 + OPAQUE8_LEN + listLen);
16491 if ((word32)*pOffset + blockSz > WOLFSSL_MAX_16BIT) {
16492 WOLFSSL_MSG("ECH OuterExtensions overflows extensions length");
16493 return BUFFER_E;
16494 }
16495 if (output != NULL) {
16496 byte* hdr = output + *pOffset;
16497 c16toa(TLSXT_ECH_OUTER_EXTENSIONS, hdr);
16498 c16toa((word16)(OPAQUE8_LEN + listLen), hdr + OPAQUE16_LEN);
16499 hdr[OPAQUE16_LEN + OPAQUE16_LEN] = (byte)listLen;
16500 }
16501
16502 /* accumulate offset even if nothing is written */
16503 *pOffset += blockSz;
16504 }
16505
16506 *outCount = count;
16507 return 0;
16508}
16509
16510/* because the size of ech depends on the size of other extensions we need to
16511 * get the size with ech special and process ech last, return status */
16512static int TLSX_GetSizeWithEch(WOLFSSL* ssl, byte* semaphore, byte msgType,
16513 word16* pLength)
16514{
16515 int ret = 0, r = 0;
16516 TLSX* echX = NULL;
16517 TLSX* serverNameX = NULL;
16518 TLSX** extensions = NULL;
16519 WOLFSSL_ECH* ech = NULL;
16520 word16 count = 0;
16521 WC_DECLARE_VAR(serverName, char, WOLFSSL_HOST_NAME_MAX, 0);
16522
16523 WC_ALLOC_VAR_EX(serverName, char, WOLFSSL_HOST_NAME_MAX, NULL,
16524 DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
16525
16526 r = TLSX_EchChangeSNI(ssl, &echX, serverName, &serverNameX, &extensions);
16527
16528 if (echX != NULL)
16529 ech = (WOLFSSL_ECH*)echX->data;
16530
16531 /* If ECH won't be written exclude it from the size calculation */
16532 if (r == 0 && !ssl->options.echAccepted && ech != NULL &&
16533 ech->innerCount != 0) {
16534 TURN_ON(semaphore, TLSX_ToSemaphore(echX->type));
16535 }
16536
16537 /* if encoding, then count encoded form of inner ClientHello.
16538 * `semaphore` is in/out so encodable extensions will later be ignored */
16539 if (r == 0 && ech != NULL && ech->type == ECH_TYPE_INNER &&
16540 ech->writeEncoded) {
16541 ret = TLSX_ECH_BuildOuterExtensions(ssl, semaphore, msgType,
16542 NULL, pLength, &count, semaphore);
16543 }
16544 if (r == 0 && ret == 0 && ssl->extensions)
16545 ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, pLength);
16546 if (r == 0 && ret == 0 && ssl->ctx && ssl->ctx->extensions)
16547 ret = TLSX_GetSize(ssl->ctx->extensions, semaphore, msgType, pLength);
16548 if (r == 0)
16549 r = TLSX_EchRestoreSNI(ssl, serverName, serverNameX, extensions);
16550
16551 WC_FREE_VAR_EX(serverName, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16552 if (ret == 0 && r != 0)
16553 ret = r;
16554 return ret;
16555}
16556#endif
16557
16558/** Tells the buffered size of extensions to be sent into the client hello. */
16559int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word32* pLength)
16560{
16561 int ret = 0;
16562 word16 length = 0;
16563 byte semaphore[SEMAPHORE_SIZE] = {0};
16564
16565 if (!TLSX_SupportExtensions(ssl))
16566 return 0;
16567 if (msgType == client_hello) {
16568 EC_VALIDATE_REQUEST(ssl, semaphore);
16569 PF_VALIDATE_REQUEST(ssl, semaphore);
16570#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
16571 if (WOLFSSL_SUITES(ssl)->hashSigAlgoSz == 0)
16572 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
16573#endif
16574#if defined(WOLFSSL_TLS13)
16575 if (!IsAtLeastTLSv1_2(ssl)) {
16576 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
16577 }
16578 #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
16579 if (!IsAtLeastTLSv1_3(ssl->version)) {
16580 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
16581 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16582 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
16583 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
16584 #endif
16585 #ifdef WOLFSSL_EARLY_DATA
16586 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
16587 #endif
16588 #ifdef WOLFSSL_SEND_HRR_COOKIE
16589 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
16590 #endif
16591 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
16592 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
16593 #endif
16594 }
16595 #endif
16596 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
16597 if (!IsAtLeastTLSv1_3(ssl->version) ||
16598 SSL_CA_NAMES(ssl) == NULL) {
16599 TURN_ON(semaphore,
16600 TLSX_ToSemaphore(TLSX_CERTIFICATE_AUTHORITIES));
16601 }
16602 #endif
16603#endif /* WOLFSSL_TLS13 */
16604 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
16605 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
16606 if (!SSL_CM(ssl)->ocspStaplingEnabled) {
16607 /* mark already sent, so it won't send it */
16608 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
16609 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
16610 }
16611 #endif
16612 }
16613
16614#ifdef WOLFSSL_TLS13
16615 #ifndef NO_CERTS
16616 else if (msgType == certificate_request) {
16617 /* Don't send out any extension except those that are turned off. */
16618 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
16619#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
16620 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
16621#endif
16622#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
16623 if (SSL_PRIORITY_CA_NAMES(ssl) != NULL) {
16624 TURN_OFF(semaphore,
16625 TLSX_ToSemaphore(TLSX_CERTIFICATE_AUTHORITIES));
16626 }
16627#endif
16628 /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP, OID_FILTERS
16629 * TLSX_STATUS_REQUEST
16630 */
16631 }
16632 #endif
16633#if defined(HAVE_ECH)
16634 if (ssl->echConfigs != NULL && !ssl->options.disableECH
16635 && msgType == client_hello) {
16636 ret = TLSX_GetSizeWithEch(ssl, semaphore, msgType, &length);
16637 if (ret != 0)
16638 return ret;
16639 }
16640 else
16641#endif /* HAVE_ECH */
16642#endif /* WOLFSSL_TLS13 */
16643 {
16644 if (ssl->extensions) {
16645 ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length);
16646 if (ret != 0)
16647 return ret;
16648 }
16649 if (ssl->ctx && ssl->ctx->extensions) {
16650 ret = TLSX_GetSize(ssl->ctx->extensions, semaphore, msgType,
16651 &length);
16652 if (ret != 0)
16653 return ret;
16654 }
16655 }
16656
16657#ifdef HAVE_EXTENDED_MASTER
16658 if (msgType == client_hello && ssl->options.haveEMS &&
16659 (!IsAtLeastTLSv1_3(ssl->version) || ssl->options.downgrade)) {
16660 length += HELLO_EXT_SZ;
16661 }
16662#endif
16663
16664 /* The TLS extensions block length prefix is a 2-byte field, so any
16665 * accumulated total above 0xFFFF must be rejected rather than silently
16666 * truncating and producing a short, malformed handshake message. */
16667 if (length > (word16)(WOLFSSL_MAX_16BIT - OPAQUE16_LEN)) {
16668 WOLFSSL_MSG("TLSX_GetRequestSize extensions exceed word16");
16669 return BUFFER_E;
16670 }
16671 if (length)
16672 length += OPAQUE16_LEN; /* for total length storage. */
16673
16674 *pLength += length;
16675
16676 return ret;
16677}
16678
16679#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
16680/* return status after writing the extensions with ech written last */
16681static int TLSX_WriteWithEch(WOLFSSL* ssl, byte* output, byte* semaphore,
16682 byte msgType, word16* pOffset)
16683{
16684 int r = 0, ret = 0;
16685 TLSX* echX = NULL;
16686 TLSX* serverNameX = NULL;
16687 TLSX** extensions = NULL;
16688 WOLFSSL_ECH* ech = NULL;
16689 WC_DECLARE_VAR(serverName, char, WOLFSSL_HOST_NAME_MAX, 0);
16690
16691 WC_ALLOC_VAR_EX(serverName, char, WOLFSSL_HOST_NAME_MAX, NULL,
16692 DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
16693 r = TLSX_EchChangeSNI(ssl, &echX, serverName, &serverNameX, &extensions);
16694 ret = r;
16695 if (ret == 0 && echX != NULL) {
16696 ech = (WOLFSSL_ECH*)echX->data;
16697 /* turn ech on so it doesn't write, then write it last */
16698 TURN_ON(semaphore, TLSX_ToSemaphore(echX->type));
16699 }
16700
16701 /* for ECH inner, print the encodable block first, then the non-encodables.
16702 * This allows the same transcript to be produced on either side
16703 * (the transcript is over the expanded form). */
16704 if (ret == 0 && ech != NULL && ech->type == ECH_TYPE_INNER) {
16705 byte encodeMask[SEMAPHORE_SIZE];
16706 byte* mask = ech->writeEncoded ? semaphore : encodeMask;
16707 word16 count = 0;
16708 int i;
16709
16710 XMEMSET(encodeMask, 0, SEMAPHORE_SIZE);
16711
16712 ret = TLSX_ECH_BuildOuterExtensions(ssl, semaphore, msgType,
16713 ech->writeEncoded ? output : NULL,
16714 ech->writeEncoded ? pOffset : NULL,
16715 &count, mask);
16716 if (ret == 0 && count >= 1 && !ech->writeEncoded) {
16717 /* expanded: print encodable block normally */
16718 for (i = 0; i < SEMAPHORE_SIZE; i++) {
16719 semaphore[i] |= encodeMask[i];
16720 encodeMask[i] = (byte)~encodeMask[i];
16721 }
16722 if (ssl->extensions) {
16723 ret = TLSX_Write(ssl->extensions, output + *pOffset,
16724 encodeMask, msgType, pOffset);
16725 }
16726 if (ret == 0 && ssl->ctx && ssl->ctx->extensions) {
16727 ret = TLSX_Write(ssl->ctx->extensions, output + *pOffset,
16728 encodeMask, msgType, pOffset);
16729 }
16730 }
16731 }
16732
16733 /* print non-encodable block */
16734 if (ret == 0 && ssl->extensions) {
16735 ret = TLSX_Write(ssl->extensions, output + *pOffset, semaphore,
16736 msgType, pOffset);
16737 }
16738 if (ret == 0 && ssl->ctx && ssl->ctx->extensions) {
16739 ret = TLSX_Write(ssl->ctx->extensions, output + *pOffset, semaphore,
16740 msgType, pOffset);
16741 }
16742
16743 /* only write ECH if there is a shot at acceptance */
16744 if (ret == 0 && echX != NULL &&
16745 (ssl->options.echAccepted ||
16746 ((WOLFSSL_ECH*)echX->data)->innerCount == 0)) {
16747 if (echX != NULL) {
16748 /* turn off and write it last */
16749 TURN_OFF(semaphore, TLSX_ToSemaphore(echX->type));
16750 }
16751
16752 if (ret == 0 && ssl->extensions) {
16753 ret = TLSX_Write(ssl->extensions, output + *pOffset, semaphore,
16754 msgType, pOffset);
16755 }
16756
16757 if (ret == 0 && ssl->ctx && ssl->ctx->extensions) {
16758 ret = TLSX_Write(ssl->ctx->extensions, output + *pOffset, semaphore,
16759 msgType, pOffset);
16760 }
16761 }
16762
16763 if (r == 0)
16764 r = TLSX_EchRestoreSNI(ssl, serverName, serverNameX, extensions);
16765 WC_FREE_VAR_EX(serverName, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
16766
16767 if (ret == 0 && r != 0)
16768 ret = r;
16769 return ret;
16770}
16771#endif
16772
16773/** Writes the extensions to be sent into the client hello. */
16774int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word32* pOffset)
16775{
16776 int ret = 0;
16777 word16 offset = 0;
16778 byte semaphore[SEMAPHORE_SIZE] = {0};
16779
16780 if (!TLSX_SupportExtensions(ssl) || output == NULL)
16781 return 0;
16782
16783 offset += OPAQUE16_LEN; /* extensions length */
16784
16785 if (msgType == client_hello) {
16786 EC_VALIDATE_REQUEST(ssl, semaphore);
16787 PF_VALIDATE_REQUEST(ssl, semaphore);
16788#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
16789 if (WOLFSSL_SUITES(ssl)->hashSigAlgoSz == 0)
16790 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
16791#endif
16792#ifdef WOLFSSL_TLS13
16793 if (!IsAtLeastTLSv1_2(ssl)) {
16794 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
16795 }
16796 #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
16797 if (!IsAtLeastTLSv1_3(ssl->version)) {
16798 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
16799 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16800 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
16801 #endif
16802 #ifdef WOLFSSL_EARLY_DATA
16803 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
16804 #endif
16805 #ifdef WOLFSSL_SEND_HRR_COOKIE
16806 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
16807 #endif
16808 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
16809 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_POST_HANDSHAKE_AUTH));
16810 #endif
16811 #ifdef WOLFSSL_DUAL_ALG_CERTS
16812 TURN_ON(semaphore,
16813 TLSX_ToSemaphore(TLSX_CKS));
16814 #endif
16815 }
16816 #endif
16817 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
16818 if (!IsAtLeastTLSv1_3(ssl->version) || SSL_CA_NAMES(ssl) == NULL) {
16819 TURN_ON(semaphore,
16820 TLSX_ToSemaphore(TLSX_CERTIFICATE_AUTHORITIES));
16821 }
16822 #endif
16823 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16824 /* Must write Pre-shared Key extension at the end in TLS v1.3.
16825 * Must not write out Pre-shared Key extension in earlier versions of
16826 * protocol.
16827 */
16828 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
16829 #endif
16830#endif /* WOLFSSL_TLS13 */
16831 #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
16832 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
16833 /* mark already sent, so it won't send it */
16834 if (!SSL_CM(ssl)->ocspStaplingEnabled) {
16835 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
16836 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
16837 }
16838 #endif
16839 }
16840#ifdef WOLFSSL_TLS13
16841 #ifndef NO_CERTS
16842 else if (msgType == certificate_request) {
16843 /* Don't send out any extension except those that are turned off. */
16844 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
16845#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
16846 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
16847#endif
16848#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
16849 if (SSL_PRIORITY_CA_NAMES(ssl) != NULL) {
16850 TURN_OFF(semaphore,
16851 TLSX_ToSemaphore(TLSX_CERTIFICATE_AUTHORITIES));
16852 }
16853#endif
16854 /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP, TLSX_OID_FILTERS
16855 * TLSX_STATUS_REQUEST
16856 */
16857 }
16858 #endif
16859#endif
16860#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
16861 if (ssl->echConfigs != NULL && !ssl->options.disableECH
16862 && msgType == client_hello) {
16863 ret = TLSX_WriteWithEch(ssl, output, semaphore,
16864 msgType, &offset);
16865 if (ret != 0)
16866 return ret;
16867 }
16868 else
16869#endif
16870 {
16871 if (ssl->extensions) {
16872 ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
16873 msgType, &offset);
16874 if (ret != 0)
16875 return ret;
16876 }
16877 if (ssl->ctx && ssl->ctx->extensions) {
16878 ret = TLSX_Write(ssl->ctx->extensions, output + offset, semaphore,
16879 msgType, &offset);
16880 if (ret != 0)
16881 return ret;
16882 }
16883 }
16884
16885#ifdef HAVE_EXTENDED_MASTER
16886 if (msgType == client_hello && ssl->options.haveEMS &&
16887 (!IsAtLeastTLSv1_3(ssl->version) || ssl->options.downgrade)) {
16888 WOLFSSL_MSG("EMS extension to write");
16889 c16toa(HELLO_EXT_EXTMS, output + offset);
16890 offset += HELLO_EXT_TYPE_SZ;
16891 c16toa(0, output + offset);
16892 offset += HELLO_EXT_SZ_SZ;
16893 }
16894#endif
16895
16896#ifdef WOLFSSL_TLS13
16897 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16898 if (msgType == client_hello && IsAtLeastTLSv1_3(ssl->version)) {
16899 /* Write out what we can of Pre-shared key extension. */
16900 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
16901 ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
16902 client_hello, &offset);
16903 if (ret != 0)
16904 return ret;
16905 }
16906 #endif
16907#endif
16908
16909 /* Wrap detection for the TLSX_Write calls above is handled inside
16910 * TLSX_Write itself: any iteration that would push the local word16
16911 * offset past 0xFFFF returns BUFFER_E so we never reach here with a
16912 * truncated value. The TLS extensions block length prefix on the
16913 * wire is a 2-byte field, matching this invariant. */
16914
16915 if (offset > OPAQUE16_LEN || msgType != client_hello)
16916 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
16917
16918 *pOffset += offset;
16919
16920 return ret;
16921}
16922#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */
16923
16924#if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_SERVER)
16925
16926/** Tells the buffered size of extensions to be sent into the server hello. */
16927int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength)
16928{
16929 int ret = 0;
16930 word16 length = 0;
16931 byte semaphore[SEMAPHORE_SIZE] = {0};
16932
16933 switch (msgType) {
16934#ifndef NO_WOLFSSL_SERVER
16935 case server_hello:
16936 PF_VALIDATE_RESPONSE(ssl, semaphore);
16937 #ifdef WOLFSSL_TLS13
16938 if (IsAtLeastTLSv1_3(ssl->version)) {
16939 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
16940 TURN_OFF(semaphore,
16941 TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
16942 #if defined(HAVE_SUPPORTED_CURVES)
16943 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16944 if (!ssl->options.noPskDheKe)
16945 #endif
16946 {
16947 /* Expect KeyShare extension in ServerHello. */
16948 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
16949 }
16950 #endif
16951 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16952 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
16953 #ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
16954 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
16955 #endif
16956 #endif
16957 }
16958 #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
16959 else {
16960 #ifdef HAVE_SUPPORTED_CURVES
16961 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
16962 #endif
16963 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16964 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
16965 #endif
16966 }
16967 #endif
16968 #ifdef WOLFSSL_DTLS_CID
16969 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
16970 #endif
16971 #endif /* WOLFSSL_TLS13 */
16972 break;
16973
16974 #ifdef WOLFSSL_TLS13
16975 case hello_retry_request:
16976 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
16977 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
16978 #ifdef HAVE_SUPPORTED_CURVES
16979 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
16980 if (!ssl->options.noPskDheKe)
16981 #endif
16982 {
16983 /* Expect KeyShare extension in HelloRetryRequest. */
16984 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
16985 }
16986 #endif
16987 #ifdef WOLFSSL_SEND_HRR_COOKIE
16988 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
16989 #endif
16990#ifdef HAVE_ECH
16991 /* send the special confirmation */
16992 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_ECH));
16993#endif
16994 break;
16995 #endif
16996
16997 #ifdef WOLFSSL_TLS13
16998 case encrypted_extensions:
16999 /* Send out all extension except those that are turned on. */
17000 #ifdef HAVE_ECC
17001 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
17002 #endif
17003 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
17004 #ifdef HAVE_SESSION_TICKET
17005 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
17006 #endif
17007 #ifdef HAVE_SUPPORTED_CURVES
17008 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
17009 #endif
17010 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
17011 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
17012 #ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
17013 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
17014 #endif
17015 #endif
17016 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
17017 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
17018 #endif
17019 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
17020 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
17021 #endif
17022 #if defined(HAVE_SERVER_RENEGOTIATION_INFO)
17023 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_RENEGOTIATION_INFO));
17024 #endif
17025 #ifdef WOLFSSL_DTLS_CID
17026 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
17027 #endif /* WOLFSSL_DTLS_CID */
17028 break;
17029
17030 #ifdef WOLFSSL_EARLY_DATA
17031 case session_ticket:
17032 if (ssl->options.tls1_3) {
17033 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
17034 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
17035 }
17036 break;
17037 #endif
17038 #endif
17039#endif
17040
17041#ifdef WOLFSSL_TLS13
17042 #ifndef NO_CERTS
17043 case certificate:
17044 /* Don't send out any extension except those that are turned off. */
17045 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
17046 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
17047 /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
17048 * TLSX_SERVER_CERTIFICATE_TYPE
17049 */
17050 break;
17051 #endif
17052#endif
17053 }
17054
17055#ifdef HAVE_EXTENDED_MASTER
17056 if (ssl->options.haveEMS && msgType == server_hello &&
17057 !IsAtLeastTLSv1_3(ssl->version)) {
17058 length += HELLO_EXT_SZ;
17059 }
17060#endif
17061
17062 if (TLSX_SupportExtensions(ssl)) {
17063 ret = TLSX_GetSize(ssl->extensions, semaphore, msgType, &length);
17064 if (ret != 0)
17065 return ret;
17066 }
17067
17068 /* All the response data is set at the ssl object only, so no ctx here. */
17069
17070 if (length || msgType != server_hello)
17071 length += OPAQUE16_LEN; /* for total length storage. */
17072
17073 *pLength += length;
17074
17075 return ret;
17076}
17077
17078/** Writes the server hello extensions into a buffer. */
17079int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset)
17080{
17081 int ret = 0;
17082 word16 offset = 0;
17083
17084 if (TLSX_SupportExtensions(ssl) && output) {
17085 byte semaphore[SEMAPHORE_SIZE] = {0};
17086
17087 switch (msgType) {
17088#ifndef NO_WOLFSSL_SERVER
17089 case server_hello:
17090 PF_VALIDATE_RESPONSE(ssl, semaphore);
17091 #ifdef WOLFSSL_TLS13
17092 if (IsAtLeastTLSv1_3(ssl->version)) {
17093 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
17094 TURN_OFF(semaphore,
17095 TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
17096 #ifdef HAVE_SUPPORTED_CURVES
17097 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
17098 if (!ssl->options.noPskDheKe)
17099 #endif
17100 {
17101 /* Write out KeyShare in ServerHello. */
17102 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
17103 }
17104 #endif
17105 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
17106 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
17107 #ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
17108 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
17109 #endif
17110 #endif
17111 }
17112 else
17113 #endif /* WOLFSSL_TLS13 */
17114 {
17115 #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
17116 #ifdef HAVE_SUPPORTED_CURVES
17117 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
17118 #endif
17119 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
17120 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
17121 #endif
17122 #endif
17123 WC_DO_NOTHING; /* avoid empty brackets */
17124 }
17125 #ifdef WOLFSSL_DTLS_CID
17126 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
17127 #endif /* WOLFSSL_DTLS_CID */
17128 break;
17129
17130 #ifdef WOLFSSL_TLS13
17131 case hello_retry_request:
17132 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
17133 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
17134 #ifdef HAVE_SUPPORTED_CURVES
17135 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
17136 if (!ssl->options.noPskDheKe)
17137 #endif
17138 {
17139 /* Write out KeyShare in HelloRetryRequest. */
17140 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
17141 }
17142 #endif
17143 break;
17144 #endif
17145
17146 #ifdef WOLFSSL_TLS13
17147 case encrypted_extensions:
17148 /* Send out all extension except those that are turned on. */
17149 #ifdef HAVE_ECC
17150 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
17151 #endif
17152 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
17153 #ifdef HAVE_SESSION_TICKET
17154 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
17155 #endif
17156 #ifdef HAVE_SUPPORTED_CURVES
17157 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
17158 #endif
17159 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
17160 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
17161 #ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
17162 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
17163 #endif
17164 #endif
17165 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
17166 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
17167 #endif
17168 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
17169 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST_V2));
17170 #endif
17171 #if defined(HAVE_SERVER_RENEGOTIATION_INFO)
17172 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_RENEGOTIATION_INFO));
17173 #endif
17174 #ifdef WOLFSSL_DTLS_CID
17175 TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_CONNECTION_ID));
17176 #endif /* WOLFSSL_DTLS_CID */
17177 break;
17178
17179 #ifdef WOLFSSL_EARLY_DATA
17180 case session_ticket:
17181 if (ssl->options.tls1_3) {
17182 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
17183 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_EARLY_DATA));
17184 }
17185 break;
17186 #endif
17187 #endif
17188#endif
17189
17190 #ifdef WOLFSSL_TLS13
17191 #ifndef NO_CERTS
17192 case certificate:
17193 /* Don't send out any extension except those that are turned
17194 * off. */
17195 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
17196 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_STATUS_REQUEST));
17197 /* TODO: TLSX_SIGNED_CERTIFICATE_TIMESTAMP,
17198 * TLSX_SERVER_CERTIFICATE_TYPE
17199 */
17200 break;
17201 #endif
17202 #endif
17203
17204 default:
17205 break;
17206 }
17207
17208 offset += OPAQUE16_LEN; /* extensions length */
17209
17210 ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
17211 msgType, &offset);
17212 if (ret != 0)
17213 return ret;
17214
17215#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
17216 if (msgType == hello_retry_request) {
17217 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
17218 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE));
17219 ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
17220 msgType, &offset);
17221 if (ret != 0)
17222 return ret;
17223 }
17224#endif
17225
17226#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
17227 /* write ECH last to promote interop with other implementations */
17228 if (msgType == hello_retry_request) {
17229 XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
17230 TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_ECH));
17231 ret = TLSX_Write(ssl->extensions, output + offset, semaphore,
17232 msgType, &offset);
17233 if (ret != 0)
17234 return ret;
17235 }
17236#endif
17237
17238#ifdef HAVE_EXTENDED_MASTER
17239 if (ssl->options.haveEMS && msgType == server_hello &&
17240 !IsAtLeastTLSv1_3(ssl->version)) {
17241 WOLFSSL_MSG("EMS extension to write");
17242 c16toa(HELLO_EXT_EXTMS, output + offset);
17243 offset += HELLO_EXT_TYPE_SZ;
17244 c16toa(0, output + offset);
17245 offset += HELLO_EXT_SZ_SZ;
17246 }
17247#endif
17248
17249 if (offset > OPAQUE16_LEN || msgType != server_hello)
17250 c16toa(offset - OPAQUE16_LEN, output); /* extensions length */
17251 }
17252
17253 if (pOffset)
17254 *pOffset += offset;
17255
17256 return ret;
17257}
17258
17259#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_SERVER */
17260
17261#ifdef WOLFSSL_TLS13
17262int TLSX_ParseVersion(WOLFSSL* ssl, const byte* input, word16 length,
17263 byte msgType, int* found)
17264{
17265 int ret = 0;
17266 int offset = 0;
17267
17268 *found = 0;
17269 while (offset < (int)length) {
17270 word16 type;
17271 word16 size;
17272
17273 if (offset + (2 * OPAQUE16_LEN) > length) {
17274 ret = BUFFER_ERROR;
17275 break;
17276 }
17277
17278 ato16(input + offset, &type);
17279 offset += HELLO_EXT_TYPE_SZ;
17280
17281 ato16(input + offset, &size);
17282 offset += OPAQUE16_LEN;
17283
17284 if (offset + size > length) {
17285 ret = BUFFER_ERROR;
17286 break;
17287 }
17288
17289 if (type == TLSX_SUPPORTED_VERSIONS) {
17290 *found = 1;
17291
17292 WOLFSSL_MSG("Supported Versions extension received");
17293
17294 ret = SV_PARSE(ssl, input + offset, size, msgType, &ssl->version,
17295 &ssl->options, &ssl->extensions);
17296 break;
17297 }
17298
17299 offset += size;
17300 }
17301
17302 return ret;
17303}
17304#endif
17305/* Jump Table to check minimum size values for client case in TLSX_Parse */
17306#ifndef NO_WOLFSSL_SERVER
17307static word16 TLSX_GetMinSize_Client(word16* type)
17308{
17309 switch (*type) {
17310 case TLSXT_SERVER_NAME:
17311 return WOLFSSL_SNI_MIN_SIZE_CLIENT;
17312 case TLSXT_EARLY_DATA:
17313 return WOLFSSL_EDI_MIN_SIZE_CLIENT;
17314 case TLSXT_MAX_FRAGMENT_LENGTH:
17315 return WOLFSSL_MFL_MIN_SIZE_CLIENT;
17316 case TLSXT_TRUSTED_CA_KEYS:
17317 return WOLFSSL_TCA_MIN_SIZE_CLIENT;
17318 case TLSXT_TRUNCATED_HMAC:
17319 return WOLFSSL_THM_MIN_SIZE_CLIENT;
17320 case TLSXT_STATUS_REQUEST:
17321 return WOLFSSL_CSR_MIN_SIZE_CLIENT;
17322 case TLSXT_SUPPORTED_GROUPS:
17323 return WOLFSSL_EC_MIN_SIZE_CLIENT;
17324 case TLSXT_EC_POINT_FORMATS:
17325 return WOLFSSL_PF_MIN_SIZE_CLIENT;
17326 case TLSXT_SIGNATURE_ALGORITHMS:
17327 return WOLFSSL_SA_MIN_SIZE_CLIENT;
17328 case TLSXT_USE_SRTP:
17329 return WOLFSSL_SRTP_MIN_SIZE_CLIENT;
17330 case TLSXT_APPLICATION_LAYER_PROTOCOL:
17331 return WOLFSSL_ALPN_MIN_SIZE_CLIENT;
17332 case TLSXT_STATUS_REQUEST_V2:
17333 return WOLFSSL_CSR2_MIN_SIZE_CLIENT;
17334 case TLSXT_CLIENT_CERTIFICATE:
17335 return WOLFSSL_CCT_MIN_SIZE_CLIENT;
17336 case TLSXT_SERVER_CERTIFICATE:
17337 return WOLFSSL_SCT_MIN_SIZE_CLIENT;
17338 case TLSXT_ENCRYPT_THEN_MAC:
17339 return WOLFSSL_ETM_MIN_SIZE_CLIENT;
17340 case TLSXT_SESSION_TICKET:
17341 return WOLFSSL_STK_MIN_SIZE_CLIENT;
17342 case TLSXT_PRE_SHARED_KEY:
17343 return WOLFSSL_PSK_MIN_SIZE_CLIENT;
17344 case TLSXT_COOKIE:
17345 return WOLFSSL_CKE_MIN_SIZE_CLIENT;
17346 case TLSXT_PSK_KEY_EXCHANGE_MODES:
17347 return WOLFSSL_PKM_MIN_SIZE_CLIENT;
17348 case TLSXT_CERT_WITH_EXTERN_PSK:
17349 return WOLFSSL_CWEP_MIN_SIZE_CLIENT;
17350 case TLSXT_CERTIFICATE_AUTHORITIES:
17351 return WOLFSSL_CAN_MIN_SIZE_CLIENT;
17352 case TLSXT_POST_HANDSHAKE_AUTH:
17353 return WOLFSSL_PHA_MIN_SIZE_CLIENT;
17354 case TLSXT_SIGNATURE_ALGORITHMS_CERT:
17355 return WOLFSSL_SA_MIN_SIZE_CLIENT;
17356 case TLSXT_KEY_SHARE:
17357 return WOLFSSL_KS_MIN_SIZE_CLIENT;
17358 case TLSXT_CONNECTION_ID:
17359 return WOLFSSL_CID_MIN_SIZE_CLIENT;
17360 case TLSXT_RENEGOTIATION_INFO:
17361 return WOLFSSL_SCR_MIN_SIZE_CLIENT;
17362 case TLSXT_KEY_QUIC_TP_PARAMS_DRAFT:
17363 return WOLFSSL_QTP_MIN_SIZE_CLIENT;
17364 case TLSXT_ECH:
17365 return WOLFSSL_ECH_MIN_SIZE_CLIENT;
17366 default:
17367 return 0;
17368 }
17369}
17370 #define TLSX_GET_MIN_SIZE_CLIENT(type) TLSX_GetMinSize_Client(type)
17371#else
17372 #define TLSX_GET_MIN_SIZE_CLIENT(type) 0
17373#endif
17374
17375
17376#ifndef NO_WOLFSSL_CLIENT
17377/* Jump Table to check minimum size values for server case in TLSX_Parse */
17378static word16 TLSX_GetMinSize_Server(const word16 *type)
17379{
17380 switch (*type) {
17381 case TLSXT_SERVER_NAME:
17382 return WOLFSSL_SNI_MIN_SIZE_SERVER;
17383 case TLSXT_EARLY_DATA:
17384 return WOLFSSL_EDI_MIN_SIZE_SERVER;
17385 case TLSXT_MAX_FRAGMENT_LENGTH:
17386 return WOLFSSL_MFL_MIN_SIZE_SERVER;
17387 case TLSXT_TRUSTED_CA_KEYS:
17388 return WOLFSSL_TCA_MIN_SIZE_SERVER;
17389 case TLSXT_TRUNCATED_HMAC:
17390 return WOLFSSL_THM_MIN_SIZE_SERVER;
17391 case TLSXT_STATUS_REQUEST:
17392 return WOLFSSL_CSR_MIN_SIZE_SERVER;
17393 case TLSXT_SUPPORTED_GROUPS:
17394 return WOLFSSL_EC_MIN_SIZE_SERVER;
17395 case TLSXT_EC_POINT_FORMATS:
17396 return WOLFSSL_PF_MIN_SIZE_SERVER;
17397 case TLSXT_SIGNATURE_ALGORITHMS:
17398 return WOLFSSL_SA_MIN_SIZE_SERVER;
17399 case TLSXT_USE_SRTP:
17400 return WOLFSSL_SRTP_MIN_SIZE_SERVER;
17401 case TLSXT_APPLICATION_LAYER_PROTOCOL:
17402 return WOLFSSL_ALPN_MIN_SIZE_SERVER;
17403 case TLSXT_STATUS_REQUEST_V2:
17404 return WOLFSSL_CSR2_MIN_SIZE_SERVER;
17405 case TLSXT_CLIENT_CERTIFICATE:
17406 return WOLFSSL_CCT_MIN_SIZE_SERVER;
17407 case TLSXT_SERVER_CERTIFICATE:
17408 return WOLFSSL_SCT_MIN_SIZE_SERVER;
17409 case TLSXT_ENCRYPT_THEN_MAC:
17410 return WOLFSSL_ETM_MIN_SIZE_SERVER;
17411 case TLSXT_SESSION_TICKET:
17412 return WOLFSSL_STK_MIN_SIZE_SERVER;
17413 case TLSXT_PRE_SHARED_KEY:
17414 return WOLFSSL_PSK_MIN_SIZE_SERVER;
17415 case TLSXT_COOKIE:
17416 return WOLFSSL_CKE_MIN_SIZE_SERVER;
17417 case TLSXT_PSK_KEY_EXCHANGE_MODES:
17418 return WOLFSSL_PKM_MIN_SIZE_SERVER;
17419 case TLSXT_CERT_WITH_EXTERN_PSK:
17420 return WOLFSSL_CWEP_MIN_SIZE_SERVER;
17421 case TLSXT_CERTIFICATE_AUTHORITIES:
17422 return WOLFSSL_CAN_MIN_SIZE_SERVER;
17423 case TLSXT_POST_HANDSHAKE_AUTH:
17424 return WOLFSSL_PHA_MIN_SIZE_SERVER;
17425 case TLSXT_SIGNATURE_ALGORITHMS_CERT:
17426 return WOLFSSL_SA_MIN_SIZE_SERVER;
17427 case TLSXT_KEY_SHARE:
17428 return WOLFSSL_KS_MIN_SIZE_SERVER;
17429 case TLSXT_CONNECTION_ID:
17430 return WOLFSSL_CID_MIN_SIZE_SERVER;
17431 case TLSXT_RENEGOTIATION_INFO:
17432 return WOLFSSL_SCR_MIN_SIZE_SERVER;
17433 case TLSXT_KEY_QUIC_TP_PARAMS_DRAFT:
17434 return WOLFSSL_QTP_MIN_SIZE_SERVER;
17435 case TLSXT_ECH:
17436 return WOLFSSL_ECH_MIN_SIZE_SERVER;
17437 default:
17438 return 0;
17439 }
17440}
17441 #define TLSX_GET_MIN_SIZE_SERVER(type) TLSX_GetMinSize_Server(type)
17442#else
17443 #define TLSX_GET_MIN_SIZE_SERVER(type) 0
17444#endif
17445
17446
17447/** Parses a buffer of TLS extensions. */
17448WOLFSSL_TEST_VIS int TLSX_Parse(WOLFSSL* ssl, const byte* input, word16 length,
17449 byte msgType, Suites *suites)
17450{
17451 int ret = 0;
17452 word16 offset = 0;
17453 byte isRequest = (msgType == client_hello ||
17454 msgType == certificate_request);
17455
17456#ifdef HAVE_EXTENDED_MASTER
17457 byte pendingEMS = 0;
17458#endif
17459#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
17460 int pskDone = 0;
17461#endif
17462#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
17463 !defined(NO_PSK)
17464 int secondClientHello = 0;
17465 int prevHasPskWithCert = 0;
17466#endif
17467 byte seenType[SEMAPHORE_SIZE]; /* Seen known extensions. */
17468
17469 if (!ssl || !input || (isRequest && !suites))
17470 return BAD_FUNC_ARG;
17471
17472 /* No known extensions seen yet. */
17473 XMEMSET(seenType, 0, sizeof(seenType));
17474#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
17475 !defined(NO_PSK)
17476 if (IsAtLeastTLSv1_3(ssl->version) && msgType == client_hello &&
17477 ssl->msgsReceived.got_client_hello == 2) {
17478 secondClientHello = 1;
17479 prevHasPskWithCert =
17480 TLSX_Find(ssl->extensions, TLSX_CERT_WITH_EXTERN_PSK) != NULL;
17481 }
17482#endif
17483
17484 while (ret == 0 && offset < length) {
17485 word16 type;
17486 word16 size;
17487
17488#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
17489 if (msgType == client_hello && pskDone) {
17490 WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
17491 return PSK_KEY_ERROR;
17492 }
17493#endif
17494
17495 if (length - offset < HELLO_EXT_TYPE_SZ + OPAQUE16_LEN)
17496 return BUFFER_ERROR;
17497
17498 ato16(input + offset, &type);
17499 offset += HELLO_EXT_TYPE_SZ;
17500
17501 ato16(input + offset, &size);
17502 offset += OPAQUE16_LEN;
17503
17504 /* Check we have a bit for extension type. */
17505 if ((type <= 62) || (type == TLSX_RENEGOTIATION_INFO)
17506 #ifdef WOLFSSL_QUIC
17507 || (type == TLSX_KEY_QUIC_TP_PARAMS_DRAFT)
17508 #endif
17509 #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
17510 || (type == TLSX_ECH)
17511 #endif
17512 #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DUAL_ALG_CERTS)
17513 || (type == TLSX_CKS)
17514 #endif
17515 )
17516 {
17517 /* Detect duplicate recognized extensions. */
17518 if (IS_OFF(seenType, TLSX_ToSemaphore(type))) {
17519 TURN_ON(seenType, TLSX_ToSemaphore(type));
17520 }
17521 else {
17522 return DUPLICATE_TLS_EXT_E;
17523 }
17524 }
17525
17526 if (length - offset < size)
17527 return BUFFER_ERROR;
17528
17529 /* Check minimum size required for TLSX, even if disabled */
17530 switch (msgType) {
17531 #ifndef NO_WOLFSSL_SERVER
17532 case client_hello:
17533 if (size < TLSX_GET_MIN_SIZE_CLIENT(&type)){
17534 WOLFSSL_MSG("Minimum TLSX Size Requirement not Satisfied");
17535 return BUFFER_ERROR;
17536 }
17537 break;
17538 #endif
17539 #ifndef NO_WOLFSSL_CLIENT
17540 case server_hello:
17541 case hello_retry_request:
17542 if (size < TLSX_GET_MIN_SIZE_SERVER(&type)){
17543 WOLFSSL_MSG("Minimum TLSX Size Requirement not Satisfied");
17544 return BUFFER_ERROR;
17545 }
17546 break;
17547 #endif
17548 default:
17549 break;
17550 }
17551
17552#ifdef WOLFSSL_TLS13
17553 /* RFC 8446 4.4.2: extensions in a Certificate message MUST
17554 * correspond to ones offered in our prior ClientHello (client) or
17555 * CertificateRequest (server). Reject anything we did not offer. */
17556 if (msgType == certificate &&
17557 IsAtLeastTLSv1_3(ssl->version) &&
17558 TLSX_Find(ssl->extensions, (TLSX_Type)type) == NULL) {
17559 WOLFSSL_MSG("Cert-msg extension not offered in CH/CR");
17560 SendAlert(ssl, alert_fatal, unsupported_extension);
17561 WOLFSSL_ERROR_VERBOSE(UNSUPPORTED_EXTENSION);
17562 return UNSUPPORTED_EXTENSION;
17563 }
17564#endif
17565
17566 switch (type) {
17567#ifdef HAVE_SNI
17568 case TLSX_SERVER_NAME:
17569 WOLFSSL_MSG("SNI extension received");
17570 #ifdef WOLFSSL_DEBUG_TLS
17571 WOLFSSL_BUFFER(input + offset, size);
17572 #endif
17573
17574#ifdef WOLFSSL_TLS13
17575 if (IsAtLeastTLSv1_3(ssl->version)) {
17576 if (msgType != client_hello &&
17577 msgType != encrypted_extensions)
17578 return EXT_NOT_ALLOWED;
17579 }
17580 else
17581#endif
17582 {
17583 if (msgType != client_hello &&
17584 msgType != server_hello)
17585 return EXT_NOT_ALLOWED;
17586 }
17587 ret = SNI_PARSE(ssl, input + offset, size, isRequest);
17588 break;
17589#endif
17590
17591 case TLSX_TRUSTED_CA_KEYS:
17592 WOLFSSL_MSG("Trusted CA extension received");
17593 #ifdef WOLFSSL_DEBUG_TLS
17594 WOLFSSL_BUFFER(input + offset, size);
17595 #endif
17596
17597#ifdef WOLFSSL_TLS13
17598 /* RFC 8446 4.2.4 states trusted_ca_keys is not used
17599 in TLS 1.3. */
17600 if (IsAtLeastTLSv1_3(ssl->version)) {
17601 break;
17602 }
17603 else
17604#endif
17605 {
17606 if (msgType != client_hello &&
17607 msgType != server_hello)
17608 return EXT_NOT_ALLOWED;
17609 }
17610 ret = TCA_PARSE(ssl, input + offset, size, isRequest);
17611 break;
17612
17613 case TLSX_MAX_FRAGMENT_LENGTH:
17614 WOLFSSL_MSG("Max Fragment Length extension received");
17615 #ifdef WOLFSSL_DEBUG_TLS
17616 WOLFSSL_BUFFER(input + offset, size);
17617 #endif
17618
17619#ifdef WOLFSSL_TLS13
17620 if (IsAtLeastTLSv1_3(ssl->version)) {
17621 if (msgType != client_hello &&
17622 msgType != encrypted_extensions) {
17623 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17624 return EXT_NOT_ALLOWED;
17625 }
17626 }
17627 else
17628#endif
17629 {
17630 if (msgType != client_hello &&
17631 msgType != server_hello) {
17632 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17633 return EXT_NOT_ALLOWED;
17634 }
17635 }
17636 ret = MFL_PARSE(ssl, input + offset, size, isRequest);
17637 break;
17638
17639 case TLSX_TRUNCATED_HMAC:
17640 WOLFSSL_MSG("Truncated HMAC extension received");
17641 #ifdef WOLFSSL_DEBUG_TLS
17642 WOLFSSL_BUFFER(input + offset, size);
17643 #endif
17644
17645#ifdef WOLFSSL_TLS13
17646 if (IsAtLeastTLSv1_3(ssl->version))
17647 break;
17648#endif
17649 if (msgType != client_hello)
17650 return EXT_NOT_ALLOWED;
17651 ret = THM_PARSE(ssl, input + offset, size, isRequest);
17652 break;
17653
17654 case TLSX_SUPPORTED_GROUPS:
17655 WOLFSSL_MSG("Supported Groups extension received");
17656 #ifdef WOLFSSL_DEBUG_TLS
17657 WOLFSSL_BUFFER(input + offset, size);
17658 #endif
17659
17660#ifdef WOLFSSL_TLS13
17661 if (IsAtLeastTLSv1_3(ssl->version)) {
17662 if (msgType != client_hello &&
17663 msgType != encrypted_extensions) {
17664 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17665 return EXT_NOT_ALLOWED;
17666 }
17667 }
17668 else
17669#endif
17670 {
17671 if (msgType != client_hello) {
17672 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17673 return EXT_NOT_ALLOWED;
17674 }
17675 }
17676 ret = EC_PARSE(ssl, input + offset, size, isRequest,
17677 &ssl->extensions);
17678 break;
17679#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DUAL_ALG_CERTS)
17680 case TLSX_CKS:
17681 WOLFSSL_MSG("CKS extension received");
17682 if (msgType != client_hello &&
17683 msgType != encrypted_extensions) {
17684 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17685 return EXT_NOT_ALLOWED;
17686 }
17687 ret = TLSX_CKS_Parse(ssl, (byte *)(input + offset), size,
17688 &ssl->extensions);
17689 break;
17690#endif /* WOLFSSL_DUAL_ALG_CERTS */
17691 case TLSX_EC_POINT_FORMATS:
17692 WOLFSSL_MSG("Point Formats extension received");
17693 #ifdef WOLFSSL_DEBUG_TLS
17694 WOLFSSL_BUFFER(input + offset, size);
17695 #endif
17696
17697#ifdef WOLFSSL_TLS13
17698 if (IsAtLeastTLSv1_3(ssl->version))
17699 break;
17700#endif
17701 if (msgType != client_hello &&
17702 msgType != server_hello) {
17703 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17704 return EXT_NOT_ALLOWED;
17705 }
17706
17707 ret = PF_PARSE(ssl, input + offset, size, isRequest);
17708 break;
17709
17710 case TLSX_STATUS_REQUEST:
17711 WOLFSSL_MSG("Certificate Status Request extension received");
17712 #ifdef WOLFSSL_DEBUG_TLS
17713 WOLFSSL_BUFFER(input + offset, size);
17714 #endif
17715
17716#ifdef WOLFSSL_TLS13
17717 if (IsAtLeastTLSv1_3(ssl->version)) {
17718 if (msgType != client_hello &&
17719 msgType != certificate_request &&
17720 msgType != certificate)
17721 return EXT_NOT_ALLOWED;
17722 }
17723 else
17724 #endif
17725 {
17726 if (msgType != client_hello &&
17727 msgType != server_hello)
17728 return EXT_NOT_ALLOWED;
17729 }
17730 ret = CSR_PARSE(ssl, input + offset, size, isRequest);
17731 break;
17732
17733 case TLSX_STATUS_REQUEST_V2:
17734 WOLFSSL_MSG("Certificate Status Request v2 extension received");
17735 #ifdef WOLFSSL_DEBUG_TLS
17736 WOLFSSL_BUFFER(input + offset, size);
17737 #endif
17738
17739#if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
17740 if (IsAtLeastTLSv1_3(ssl->version)) {
17741 if (msgType != client_hello &&
17742 msgType != certificate_request &&
17743 msgType != certificate)
17744 return EXT_NOT_ALLOWED;
17745 }
17746 else
17747#endif
17748 {
17749 if (msgType != client_hello &&
17750 msgType != server_hello)
17751 return EXT_NOT_ALLOWED;
17752 }
17753 ret = CSR2_PARSE(ssl, input + offset, size, isRequest);
17754 break;
17755
17756#ifdef HAVE_EXTENDED_MASTER
17757 case HELLO_EXT_EXTMS:
17758 WOLFSSL_MSG("Extended Master Secret extension received");
17759 #ifdef WOLFSSL_DEBUG_TLS
17760 WOLFSSL_BUFFER(input + offset, size);
17761 #endif
17762
17763#if defined(WOLFSSL_TLS13)
17764 if (IsAtLeastTLSv1_3(ssl->version))
17765 break;
17766#endif
17767 if (msgType != client_hello &&
17768 msgType != server_hello)
17769 return EXT_NOT_ALLOWED;
17770 if (size != 0)
17771 return BUFFER_ERROR;
17772
17773#ifndef NO_WOLFSSL_SERVER
17774 if (isRequest)
17775 ssl->options.haveEMS = 1;
17776#endif
17777 pendingEMS = 1;
17778 break;
17779#endif
17780
17781 case TLSX_RENEGOTIATION_INFO:
17782 WOLFSSL_MSG("Secure Renegotiation extension received");
17783 #ifdef WOLFSSL_DEBUG_TLS
17784 WOLFSSL_BUFFER(input + offset, size);
17785 #endif
17786
17787#ifdef WOLFSSL_TLS13
17788 if (IsAtLeastTLSv1_3(ssl->version))
17789 break;
17790#endif
17791 if (msgType != client_hello &&
17792 msgType != server_hello)
17793 return EXT_NOT_ALLOWED;
17794 ret = SCR_PARSE(ssl, input + offset, size, isRequest);
17795 break;
17796
17797 case TLSX_SESSION_TICKET:
17798 WOLFSSL_MSG("Session Ticket extension received");
17799 #ifdef WOLFSSL_DEBUG_TLS
17800 WOLFSSL_BUFFER(input + offset, size);
17801 #endif
17802
17803#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
17804 if (IsAtLeastTLSv1_3(ssl->version)) {
17805 if (msgType != client_hello)
17806 return EXT_NOT_ALLOWED;
17807 }
17808 else
17809#endif
17810 {
17811 if (msgType != client_hello &&
17812 msgType != server_hello)
17813 return EXT_NOT_ALLOWED;
17814 }
17815 ret = WOLF_STK_PARSE(ssl, input + offset, size, isRequest);
17816 break;
17817
17818 case TLSX_APPLICATION_LAYER_PROTOCOL:
17819 WOLFSSL_MSG("ALPN extension received");
17820
17821 #ifdef WOLFSSL_DEBUG_TLS
17822 WOLFSSL_BUFFER(input + offset, size);
17823 #endif
17824
17825#if defined(WOLFSSL_TLS13) && defined(HAVE_ALPN)
17826 if (IsAtLeastTLSv1_3(ssl->version)) {
17827 if (msgType != client_hello &&
17828 msgType != encrypted_extensions)
17829 return EXT_NOT_ALLOWED;
17830 }
17831 else
17832#endif
17833 {
17834 if (msgType != client_hello &&
17835 msgType != server_hello)
17836 return EXT_NOT_ALLOWED;
17837 }
17838 ret = ALPN_PARSE(ssl, input + offset, size, isRequest);
17839 break;
17840#if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
17841 case TLSX_SIGNATURE_ALGORITHMS:
17842 WOLFSSL_MSG("Signature Algorithms extension received");
17843 #ifdef WOLFSSL_DEBUG_TLS
17844 WOLFSSL_BUFFER(input + offset, size);
17845 #endif
17846
17847 if (!IsAtLeastTLSv1_2(ssl))
17848 break;
17849 #ifdef WOLFSSL_TLS13
17850 if (IsAtLeastTLSv1_3(ssl->version)) {
17851 if (msgType != client_hello &&
17852 msgType != certificate_request)
17853 return EXT_NOT_ALLOWED;
17854 }
17855 else
17856 #endif
17857 {
17858 if (msgType != client_hello)
17859 return EXT_NOT_ALLOWED;
17860 }
17861 ret = SA_PARSE(ssl, input + offset, size, isRequest, suites);
17862 break;
17863#endif
17864
17865#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
17866 case TLSX_ENCRYPT_THEN_MAC:
17867 WOLFSSL_MSG("Encrypt-Then-Mac extension received");
17868
17869 /* Ignore for TLS 1.3+ */
17870 if (IsAtLeastTLSv1_3(ssl->version))
17871 break;
17872 if (msgType != client_hello &&
17873 msgType != server_hello)
17874 return EXT_NOT_ALLOWED;
17875
17876 ret = ETM_PARSE(ssl, input + offset, size, msgType);
17877 break;
17878#endif /* HAVE_ENCRYPT_THEN_MAC */
17879
17880#ifdef WOLFSSL_TLS13
17881 case TLSX_SUPPORTED_VERSIONS:
17882 WOLFSSL_MSG("Skipping Supported Versions - already processed");
17883 #ifdef WOLFSSL_DEBUG_TLS
17884 WOLFSSL_BUFFER(input + offset, size);
17885 #endif
17886 if (msgType != client_hello &&
17887 msgType != server_hello &&
17888 msgType != hello_retry_request)
17889 return EXT_NOT_ALLOWED;
17890
17891 break;
17892
17893 case TLSX_COOKIE:
17894 WOLFSSL_MSG("Cookie extension received");
17895 #ifdef WOLFSSL_DEBUG_TLS
17896 WOLFSSL_BUFFER(input + offset, size);
17897 #endif
17898 if (!IsAtLeastTLSv1_3(ssl->version))
17899 break;
17900
17901 if (msgType != client_hello &&
17902 msgType != hello_retry_request) {
17903 return EXT_NOT_ALLOWED;
17904 }
17905
17906 ret = CKE_PARSE(ssl, input + offset, size, msgType);
17907 break;
17908
17909 #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
17910 case TLSX_PRE_SHARED_KEY:
17911 WOLFSSL_MSG("Pre-Shared Key extension received");
17912 #ifdef WOLFSSL_DEBUG_TLS
17913 WOLFSSL_BUFFER(input + offset, size);
17914 #endif
17915
17916 if (!IsAtLeastTLSv1_3(ssl->version))
17917 break;
17918
17919 if (msgType != client_hello &&
17920 msgType != server_hello) {
17921 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17922 return EXT_NOT_ALLOWED;
17923 }
17924
17925 ret = PSK_PARSE(ssl, input + offset, size, msgType);
17926 pskDone = 1;
17927 break;
17928
17929 case TLSX_PSK_KEY_EXCHANGE_MODES:
17930 WOLFSSL_MSG("PSK Key Exchange Modes extension received");
17931 #ifdef WOLFSSL_DEBUG_TLS
17932 WOLFSSL_BUFFER(input + offset, size);
17933 #endif
17934
17935 if (!IsAtLeastTLSv1_3(ssl->version))
17936 break;
17937
17938 if (msgType != client_hello) {
17939 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17940 return EXT_NOT_ALLOWED;
17941 }
17942
17943 ret = PKM_PARSE(ssl, input + offset, size, msgType);
17944 break;
17945
17946 #ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
17947 case TLSX_CERT_WITH_EXTERN_PSK:
17948 WOLFSSL_MSG("Cert with external PSK extension received");
17949 #ifdef WOLFSSL_DEBUG_TLS
17950 WOLFSSL_BUFFER(input + offset, size);
17951 #endif
17952
17953 if (!IsAtLeastTLSv1_3(ssl->version))
17954 break;
17955
17956 if (msgType != client_hello && msgType != server_hello) {
17957 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17958 return EXT_NOT_ALLOWED;
17959 }
17960 if (size != 0) {
17961 WOLFSSL_ERROR_VERBOSE(BUFFER_ERROR);
17962 return BUFFER_ERROR;
17963 }
17964
17965 ret = PSK_WITH_CERT_PARSE(ssl, msgType);
17966 break;
17967 #endif
17968 #endif
17969
17970 #ifdef WOLFSSL_EARLY_DATA
17971 case TLSX_EARLY_DATA:
17972 WOLFSSL_MSG("Early Data extension received");
17973 #ifdef WOLFSSL_DEBUG_TLS
17974 WOLFSSL_BUFFER(input + offset, size);
17975 #endif
17976
17977 if (!IsAtLeastTLSv1_3(ssl->version))
17978 break;
17979
17980 if (msgType != client_hello && msgType != session_ticket &&
17981 msgType != encrypted_extensions) {
17982 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
17983 return EXT_NOT_ALLOWED;
17984 }
17985 ret = EDI_PARSE(ssl, input + offset, size, msgType);
17986 break;
17987 #endif
17988
17989 #ifdef WOLFSSL_POST_HANDSHAKE_AUTH
17990 case TLSX_POST_HANDSHAKE_AUTH:
17991 WOLFSSL_MSG("Post Handshake Authentication extension received");
17992 #ifdef WOLFSSL_DEBUG_TLS
17993 WOLFSSL_BUFFER(input + offset, size);
17994 #endif
17995
17996 if (!IsAtLeastTLSv1_3(ssl->version))
17997 break;
17998
17999 if (msgType != client_hello) {
18000 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18001 return EXT_NOT_ALLOWED;
18002 }
18003
18004 ret = PHA_PARSE(ssl, input + offset, size, msgType);
18005 break;
18006 #endif
18007
18008 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_SIGALG)
18009 case TLSX_SIGNATURE_ALGORITHMS_CERT:
18010 WOLFSSL_MSG("Signature Algorithms extension received");
18011 #ifdef WOLFSSL_DEBUG_TLS
18012 WOLFSSL_BUFFER(input + offset, size);
18013 #endif
18014
18015 if (!IsAtLeastTLSv1_3(ssl->version))
18016 break;
18017
18018 if (msgType != client_hello &&
18019 msgType != certificate_request) {
18020 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18021 return EXT_NOT_ALLOWED;
18022 }
18023
18024 ret = SAC_PARSE(ssl, input + offset, size, isRequest);
18025 break;
18026 #endif
18027
18028 #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CA_NAMES)
18029 case TLSX_CERTIFICATE_AUTHORITIES:
18030 WOLFSSL_MSG("Certificate Authorities extension received");
18031 #ifdef WOLFSSL_DEBUG_TLS
18032 WOLFSSL_BUFFER(input + offset, size);
18033 #endif
18034
18035 if (!IsAtLeastTLSv1_3(ssl->version))
18036 break;
18037
18038 if (msgType != client_hello &&
18039 msgType != certificate_request) {
18040 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18041 return EXT_NOT_ALLOWED;
18042 }
18043
18044 ret = CAN_PARSE(ssl, input + offset, size, isRequest);
18045 break;
18046 #endif
18047
18048 case TLSX_KEY_SHARE:
18049 WOLFSSL_MSG("Key Share extension received");
18050 #ifdef WOLFSSL_DEBUG_TLS
18051 WOLFSSL_BUFFER(input + offset, size);
18052 #endif
18053
18054 #ifdef HAVE_SUPPORTED_CURVES
18055 if (!IsAtLeastTLSv1_3(ssl->version))
18056 break;
18057
18058 if (msgType != client_hello && msgType != server_hello &&
18059 msgType != hello_retry_request) {
18060 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18061 return EXT_NOT_ALLOWED;
18062 }
18063 #endif
18064
18065 ret = KS_PARSE(ssl, input + offset, size, msgType);
18066 break;
18067#endif
18068#ifdef WOLFSSL_SRTP
18069 case TLSX_USE_SRTP:
18070 WOLFSSL_MSG("Use SRTP extension received");
18071
18072#if defined(WOLFSSL_TLS13)
18073 if (IsAtLeastTLSv1_3(ssl->version)) {
18074 if (msgType != client_hello &&
18075 msgType != encrypted_extensions)
18076 return EXT_NOT_ALLOWED;
18077 }
18078 else
18079#endif
18080 {
18081 if (msgType != client_hello &&
18082 msgType != server_hello)
18083 return EXT_NOT_ALLOWED;
18084 }
18085 ret = SRTP_PARSE(ssl, input + offset, size, isRequest);
18086 break;
18087#endif
18088#ifdef WOLFSSL_QUIC
18089 case TLSX_KEY_QUIC_TP_PARAMS:
18090 FALL_THROUGH;
18091 case TLSX_KEY_QUIC_TP_PARAMS_DRAFT:
18092 WOLFSSL_MSG("QUIC transport parameter received");
18093 #ifdef WOLFSSL_DEBUG_TLS
18094 WOLFSSL_BUFFER(input + offset, size);
18095 #endif
18096
18097 if (IsAtLeastTLSv1_3(ssl->version) &&
18098 msgType != client_hello &&
18099 msgType != encrypted_extensions) {
18100 return EXT_NOT_ALLOWED;
18101 }
18102 else if (!IsAtLeastTLSv1_3(ssl->version) &&
18103 msgType == encrypted_extensions) {
18104 return EXT_NOT_ALLOWED;
18105 }
18106 else if (WOLFSSL_IS_QUIC(ssl)) {
18107 ret = QTP_PARSE(ssl, input + offset, size, type, msgType);
18108 }
18109 else {
18110 WOLFSSL_MSG("QUIC transport param TLS extension type, but no QUIC");
18111 return EXT_NOT_ALLOWED; /* be safe, this should not happen */
18112 }
18113 break;
18114#endif /* WOLFSSL_QUIC */
18115#if defined(WOLFSSL_DTLS_CID)
18116 case TLSX_CONNECTION_ID:
18117 if (msgType != client_hello && msgType != server_hello)
18118 return EXT_NOT_ALLOWED;
18119
18120 WOLFSSL_MSG("ConnectionID extension received");
18121 ret = CID_PARSE(ssl, input + offset, size, isRequest);
18122 break;
18123
18124#endif /* defined(WOLFSSL_DTLS_CID) */
18125#if defined(HAVE_RPK)
18126 case TLSX_CLIENT_CERTIFICATE_TYPE:
18127 WOLFSSL_MSG("Client Certificate Type extension received");
18128#if defined(WOLFSSL_TLS13)
18129 /* RFC 8446, Section 4.2 (Extensions), client_certificate_type
18130 and server_certificate_type MUST be sent in ClientHello(CH)
18131 or EncryptedExtensions(EE) */
18132 if (IsAtLeastTLSv1_3(ssl->version)) {
18133 if (msgType != client_hello &&
18134 msgType != encrypted_extensions) {
18135 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18136 return EXT_NOT_ALLOWED;
18137 }
18138 }
18139 else
18140#endif
18141 {
18142 /* TLS 1.2: allowed in CH and SH (RFC 7250) */
18143 if (msgType != client_hello &&
18144 msgType != server_hello) {
18145 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18146 return EXT_NOT_ALLOWED;
18147 }
18148 }
18149 ret = CCT_PARSE(ssl, input + offset, size, msgType);
18150 break;
18151
18152 case TLSX_SERVER_CERTIFICATE_TYPE:
18153 WOLFSSL_MSG("Server Certificate Type extension received");
18154#if defined(WOLFSSL_TLS13)
18155 /* RFC 8446, Section 4.2 (Extensions) */
18156 if (IsAtLeastTLSv1_3(ssl->version)) {
18157 if (msgType != client_hello &&
18158 msgType != encrypted_extensions) {
18159 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18160 return EXT_NOT_ALLOWED;
18161 }
18162 }
18163 else
18164#endif
18165 {
18166 /* TLS 1.2: allowed in CH and SH (RFC 7250) */
18167 if (msgType != client_hello &&
18168 msgType != server_hello) {
18169 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18170 return EXT_NOT_ALLOWED;
18171 }
18172 }
18173 ret = SCT_PARSE(ssl, input + offset, size, msgType);
18174 break;
18175#endif /* HAVE_RPK */
18176#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
18177 case TLSX_ECH:
18178 WOLFSSL_MSG("ECH extension received");
18179 if (!IsAtLeastTLSv1_3(ssl->version))
18180 break;
18181
18182 if (msgType != client_hello &&
18183 msgType != encrypted_extensions &&
18184 msgType != hello_retry_request) {
18185 return EXT_NOT_ALLOWED;
18186 }
18187
18188 ret = ECH_PARSE(ssl, input + offset, size, msgType);
18189 break;
18190 case TLSXT_ECH_OUTER_EXTENSIONS:
18191 /* RFC 9849 s5.1: ech_outer_extensions MUST only appear in
18192 * the EncodedClientHelloInner */
18193 WOLFSSL_MSG("ech_outer_extensions in plaintext message");
18194 WOLFSSL_ERROR_VERBOSE(INVALID_PARAMETER);
18195 return INVALID_PARAMETER;
18196#endif
18197 default:
18198 WOLFSSL_MSG("Unknown TLS extension type");
18199#if defined(WOLFSSL_TLS13)
18200 /* RFC 8446 Sec. 4.2: a TLS 1.3 client MUST abort with an
18201 * unsupported_extension alert when it receives an extension
18202 * "response" that was not advertised in the ClientHello. The
18203 * rule applies only to messages whose extensions are responses
18204 * to the ClientHello: ServerHello, HelloRetryRequest,
18205 * EncryptedExtensions and Certificate.
18206 *
18207 * Extensions in CertificateRequest and NewSessionTicket are
18208 * independent server-initiated payloads, not responses, and
18209 * per RFC 8701 (GREASE) the server MAY include unknown
18210 * (GREASE) extension types there which the client MUST treat
18211 * like any other unknown value (i.e. ignore them). */
18212 if (IsAtLeastTLSv1_3(ssl->version) &&
18213 (msgType == server_hello ||
18214 msgType == hello_retry_request ||
18215 msgType == encrypted_extensions ||
18216 msgType == certificate)) {
18217 SendAlert((WOLFSSL*)ssl, alert_fatal, unsupported_extension);
18218 WOLFSSL_ERROR_VERBOSE(UNSUPPORTED_EXTENSION);
18219 return UNSUPPORTED_EXTENSION;
18220 }
18221#endif
18222 }
18223
18224 /* offset should be updated here! */
18225 offset += size;
18226 }
18227
18228#ifdef HAVE_EXTENDED_MASTER
18229 if (IsAtLeastTLSv1_3(ssl->version) &&
18230 (msgType == hello_retry_request || msgType == hello_verify_request)) {
18231 /* Don't change EMS status until server_hello received.
18232 * Second ClientHello must have same extensions.
18233 */
18234 }
18235 else if (!isRequest && ssl->options.haveEMS && !pendingEMS)
18236 ssl->options.haveEMS = 0;
18237#endif
18238#if defined(WOLFSSL_TLS13) && !defined(NO_PSK)
18239 if (IsAtLeastTLSv1_3(ssl->version) && msgType == server_hello &&
18240 IS_OFF(seenType, TLSX_ToSemaphore(TLSX_KEY_SHARE))) {
18241 ssl->options.noPskDheKe = 1;
18242 }
18243#endif
18244#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
18245 !defined(NO_PSK)
18246 if (IsAtLeastTLSv1_3(ssl->version)) {
18247 int hasPskWithCert = !IS_OFF(seenType,
18248 TLSX_ToSemaphore(TLSX_CERT_WITH_EXTERN_PSK));
18249 if (hasPskWithCert && ssl->options.certWithExternPsk) {
18250 int hasPsk = !IS_OFF(seenType, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
18251 int hasPskModes = !IS_OFF(seenType,
18252 TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
18253 int hasKeyShare = !IS_OFF(seenType, TLSX_ToSemaphore(TLSX_KEY_SHARE));
18254 int hasSg = !IS_OFF(seenType,
18255 TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
18256 int hasSigAlg = !IS_OFF(seenType,
18257 TLSX_ToSemaphore(TLSX_SIGNATURE_ALGORITHMS));
18258#ifdef WOLFSSL_EARLY_DATA
18259 int hasEarlyData = !IS_OFF(seenType, TLSX_ToSemaphore(TLSX_EARLY_DATA));
18260#endif
18261
18262 if (msgType == client_hello && isRequest) {
18263 TLSX* pskm;
18264 /* RFC8773bis: CH2 after HRR must keep CH1's extension set. */
18265 if (secondClientHello && !prevHasPskWithCert) {
18266 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18267 return EXT_NOT_ALLOWED;
18268 }
18269 /* RFC8773bis: cert_with_extern_psk depends on these extensions. */
18270 if (!hasPsk || !hasPskModes || !hasKeyShare || !hasSg ||
18271 !hasSigAlg) {
18272 WOLFSSL_ERROR_VERBOSE(EXT_MISSING);
18273 return EXT_MISSING;
18274 }
18275#ifdef WOLFSSL_EARLY_DATA
18276 /* External PSK + certificate mode forbids 0-RTT in CH.
18277 * When WOLFSSL_EARLY_DATA is not defined there is no parser
18278 * case for TLSX_EARLY_DATA, so an incoming early_data
18279 * extension is treated as unknown and ignored per RFC 8446
18280 * Sect. 4.2 - no additional check is needed in that case. */
18281 if (hasEarlyData) {
18282 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18283 return EXT_NOT_ALLOWED;
18284 }
18285#endif
18286 pskm = TLSX_Find(ssl->extensions, TLSX_PSK_KEY_EXCHANGE_MODES);
18287 /* RFC8773bis requires client support for psk_dhe_ke mode. */
18288 if (pskm == NULL || (pskm->val & (1 << PSK_DHE_KE)) == 0) {
18289 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18290 return EXT_NOT_ALLOWED;
18291 }
18292 }
18293 else if (msgType == server_hello && !isRequest) {
18294 /* SH confirming cert_with_extern_psk must also confirm PSK and KSE. */
18295 if (!hasPsk || !hasKeyShare) {
18296 WOLFSSL_ERROR_VERBOSE(EXT_MISSING);
18297 return EXT_MISSING;
18298 }
18299 }
18300 }
18301 else if (msgType == client_hello && isRequest && secondClientHello &&
18302 prevHasPskWithCert) {
18303 /* RFC8773bis: reject dropping the extension in CH2 after HRR. */
18304 WOLFSSL_ERROR_VERBOSE(EXT_NOT_ALLOWED);
18305 return EXT_NOT_ALLOWED;
18306 }
18307 }
18308#endif
18309#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
18310 /* RFC 8446 Section 9.2: ClientHello with KeyShare must
18311 * contain SupportedGroups and vice-versa. */
18312 if (IsAtLeastTLSv1_3(ssl->version) && msgType == client_hello && isRequest) {
18313 int hasKeyShare = !IS_OFF(seenType, TLSX_ToSemaphore(TLSX_KEY_SHARE));
18314 int hasSupportedGroups = !IS_OFF(seenType,
18315 TLSX_ToSemaphore(TLSX_SUPPORTED_GROUPS));
18316
18317 if (hasKeyShare && !hasSupportedGroups) {
18318 WOLFSSL_MSG("ClientHello with KeyShare extension missing required "
18319 "SupportedGroups extension");
18320 return INCOMPLETE_DATA;
18321 }
18322 if (hasSupportedGroups && !hasKeyShare) {
18323 WOLFSSL_MSG("ClientHello with SupportedGroups extension missing "
18324 "required KeyShare extension");
18325 return INCOMPLETE_DATA;
18326 }
18327 }
18328#endif
18329
18330 if (ret == 0)
18331 ret = SNI_VERIFY_PARSE(ssl, isRequest);
18332 if (ret == 0)
18333 ret = TCA_VERIFY_PARSE(ssl, isRequest);
18334
18335 WOLFSSL_LEAVE("Leaving TLSX_Parse", ret);
18336 return ret;
18337}
18338
18339/* undefining semaphore macros */
18340#undef IS_OFF
18341#undef TURN_ON
18342#undef SEMAPHORE_SIZE
18343
18344#endif /* HAVE_TLS_EXTENSIONS */
18345
18346#ifndef NO_WOLFSSL_CLIENT
18347
18348 WOLFSSL_METHOD* wolfTLS_client_method(void)
18349 {
18350 return wolfTLS_client_method_ex(NULL);
18351 }
18352 WOLFSSL_METHOD* wolfTLS_client_method_ex(void* heap)
18353 {
18354 WOLFSSL_METHOD* method =
18355 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18356 heap, DYNAMIC_TYPE_METHOD);
18357 (void)heap;
18358 WOLFSSL_ENTER("TLS_client_method_ex");
18359 if (method) {
18360 #if defined(WOLFSSL_TLS13)
18361 InitSSL_Method(method, MakeTLSv1_3());
18362 #elif !defined(WOLFSSL_NO_TLS12)
18363 InitSSL_Method(method, MakeTLSv1_2());
18364 #elif !defined(NO_OLD_TLS)
18365 InitSSL_Method(method, MakeTLSv1_1());
18366 #elif defined(WOLFSSL_ALLOW_TLSV10)
18367 InitSSL_Method(method, MakeTLSv1());
18368 #else
18369 #error No TLS version enabled! Consider using NO_TLS or WOLFCRYPT_ONLY.
18370 #endif
18371
18372 method->downgrade = 1;
18373 method->side = WOLFSSL_CLIENT_END;
18374 }
18375 return method;
18376 }
18377
18378#ifndef NO_OLD_TLS
18379 #ifdef WOLFSSL_ALLOW_TLSV10
18380 WOLFSSL_METHOD* wolfTLSv1_client_method(void)
18381 {
18382 return wolfTLSv1_client_method_ex(NULL);
18383 }
18384 WOLFSSL_METHOD* wolfTLSv1_client_method_ex(void* heap)
18385 {
18386 WOLFSSL_METHOD* method =
18387 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18388 heap, DYNAMIC_TYPE_METHOD);
18389 (void)heap;
18390 WOLFSSL_ENTER("TLSv1_client_method_ex");
18391 if (method)
18392 InitSSL_Method(method, MakeTLSv1());
18393 return method;
18394 }
18395 #endif /* WOLFSSL_ALLOW_TLSV10 */
18396
18397 WOLFSSL_METHOD* wolfTLSv1_1_client_method(void)
18398 {
18399 return wolfTLSv1_1_client_method_ex(NULL);
18400 }
18401 WOLFSSL_METHOD* wolfTLSv1_1_client_method_ex(void* heap)
18402 {
18403 WOLFSSL_METHOD* method =
18404 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18405 heap, DYNAMIC_TYPE_METHOD);
18406 (void)heap;
18407 WOLFSSL_ENTER("TLSv1_1_client_method_ex");
18408 if (method)
18409 InitSSL_Method(method, MakeTLSv1_1());
18410 return method;
18411 }
18412#endif /* !NO_OLD_TLS */
18413
18414#ifndef WOLFSSL_NO_TLS12
18415 WOLFSSL_ABI
18416 WOLFSSL_METHOD* wolfTLSv1_2_client_method(void)
18417 {
18418 return wolfTLSv1_2_client_method_ex(NULL);
18419 }
18420 WOLFSSL_METHOD* wolfTLSv1_2_client_method_ex(void* heap)
18421 {
18422 WOLFSSL_METHOD* method =
18423 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18424 heap, DYNAMIC_TYPE_METHOD);
18425 (void)heap;
18426 WOLFSSL_ENTER("TLSv1_2_client_method_ex");
18427 if (method)
18428 InitSSL_Method(method, MakeTLSv1_2());
18429 return method;
18430 }
18431#endif /* WOLFSSL_NO_TLS12 */
18432
18433#ifdef WOLFSSL_TLS13
18434 /* The TLS v1.3 client method data.
18435 *
18436 * returns the method data for a TLS v1.3 client.
18437 */
18438 WOLFSSL_ABI
18439 WOLFSSL_METHOD* wolfTLSv1_3_client_method(void)
18440 {
18441 return wolfTLSv1_3_client_method_ex(NULL);
18442 }
18443
18444 /* The TLS v1.3 client method data.
18445 *
18446 * heap The heap used for allocation.
18447 * returns the method data for a TLS v1.3 client.
18448 */
18449 WOLFSSL_METHOD* wolfTLSv1_3_client_method_ex(void* heap)
18450 {
18451 WOLFSSL_METHOD* method = (WOLFSSL_METHOD*)
18452 XMALLOC(sizeof(WOLFSSL_METHOD), heap,
18453 DYNAMIC_TYPE_METHOD);
18454 (void)heap;
18455 WOLFSSL_ENTER("TLSv1_3_client_method_ex");
18456 if (method)
18457 InitSSL_Method(method, MakeTLSv1_3());
18458 return method;
18459 }
18460#endif /* WOLFSSL_TLS13 */
18461
18462#ifdef WOLFSSL_DTLS
18463
18464 WOLFSSL_METHOD* wolfDTLS_client_method(void)
18465 {
18466 return wolfDTLS_client_method_ex(NULL);
18467 }
18468 WOLFSSL_METHOD* wolfDTLS_client_method_ex(void* heap)
18469 {
18470 WOLFSSL_METHOD* method =
18471 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18472 heap, DYNAMIC_TYPE_METHOD);
18473 (void)heap;
18474 WOLFSSL_ENTER("DTLS_client_method_ex");
18475 if (method) {
18476 #if defined(WOLFSSL_DTLS13)
18477 InitSSL_Method(method, MakeDTLSv1_3());
18478 #elif !defined(WOLFSSL_NO_TLS12)
18479 InitSSL_Method(method, MakeDTLSv1_2());
18480 #elif !defined(NO_OLD_TLS)
18481 InitSSL_Method(method, MakeDTLSv1());
18482 #else
18483 #error No DTLS version enabled!
18484 #endif
18485
18486 method->downgrade = 1;
18487 method->side = WOLFSSL_CLIENT_END;
18488 }
18489 return method;
18490 }
18491
18492 #ifndef NO_OLD_TLS
18493 WOLFSSL_METHOD* wolfDTLSv1_client_method(void)
18494 {
18495 return wolfDTLSv1_client_method_ex(NULL);
18496 }
18497 WOLFSSL_METHOD* wolfDTLSv1_client_method_ex(void* heap)
18498 {
18499 WOLFSSL_METHOD* method =
18500 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18501 heap, DYNAMIC_TYPE_METHOD);
18502 (void)heap;
18503 WOLFSSL_ENTER("DTLSv1_client_method_ex");
18504 if (method)
18505 InitSSL_Method(method, MakeDTLSv1());
18506 return method;
18507 }
18508 #endif /* NO_OLD_TLS */
18509
18510 #ifndef WOLFSSL_NO_TLS12
18511 WOLFSSL_METHOD* wolfDTLSv1_2_client_method(void)
18512 {
18513 return wolfDTLSv1_2_client_method_ex(NULL);
18514 }
18515 WOLFSSL_METHOD* wolfDTLSv1_2_client_method_ex(void* heap)
18516 {
18517 WOLFSSL_METHOD* method =
18518 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18519 heap, DYNAMIC_TYPE_METHOD);
18520 (void)heap;
18521 WOLFSSL_ENTER("DTLSv1_2_client_method_ex");
18522 if (method)
18523 InitSSL_Method(method, MakeDTLSv1_2());
18524 (void)heap;
18525 return method;
18526 }
18527 #endif /* !WOLFSSL_NO_TLS12 */
18528#endif /* WOLFSSL_DTLS */
18529
18530#endif /* NO_WOLFSSL_CLIENT */
18531
18532
18533/* EITHER SIDE METHODS */
18534#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
18535 #ifndef NO_OLD_TLS
18536 #ifdef WOLFSSL_ALLOW_TLSV10
18537 /* Gets a WOLFSSL_METHOD type that is not set as client or server
18538 *
18539 * Returns a pointer to a WOLFSSL_METHOD struct
18540 */
18541 WOLFSSL_METHOD* wolfTLSv1_method(void)
18542 {
18543 return wolfTLSv1_method_ex(NULL);
18544 }
18545 WOLFSSL_METHOD* wolfTLSv1_method_ex(void* heap)
18546 {
18547 WOLFSSL_METHOD* m;
18548 WOLFSSL_ENTER("TLSv1_method");
18549 #ifndef NO_WOLFSSL_CLIENT
18550 m = wolfTLSv1_client_method_ex(heap);
18551 #else
18552 m = wolfTLSv1_server_method_ex(heap);
18553 #endif
18554 if (m != NULL) {
18555 m->side = WOLFSSL_NEITHER_END;
18556 }
18557
18558 return m;
18559 }
18560 #endif /* WOLFSSL_ALLOW_TLSV10 */
18561
18562 /* Gets a WOLFSSL_METHOD type that is not set as client or server
18563 *
18564 * Returns a pointer to a WOLFSSL_METHOD struct
18565 */
18566 WOLFSSL_METHOD* wolfTLSv1_1_method(void)
18567 {
18568 return wolfTLSv1_1_method_ex(NULL);
18569 }
18570 WOLFSSL_METHOD* wolfTLSv1_1_method_ex(void* heap)
18571 {
18572 WOLFSSL_METHOD* m;
18573 WOLFSSL_ENTER("TLSv1_1_method");
18574 #ifndef NO_WOLFSSL_CLIENT
18575 m = wolfTLSv1_1_client_method_ex(heap);
18576 #else
18577 m = wolfTLSv1_1_server_method_ex(heap);
18578 #endif
18579 if (m != NULL) {
18580 m->side = WOLFSSL_NEITHER_END;
18581 }
18582 return m;
18583 }
18584 #endif /* !NO_OLD_TLS */
18585
18586 #ifndef WOLFSSL_NO_TLS12
18587 /* Gets a WOLFSSL_METHOD type that is not set as client or server
18588 *
18589 * Returns a pointer to a WOLFSSL_METHOD struct
18590 */
18591 WOLFSSL_METHOD* wolfTLSv1_2_method(void)
18592 {
18593 return wolfTLSv1_2_method_ex(NULL);
18594 }
18595 WOLFSSL_METHOD* wolfTLSv1_2_method_ex(void* heap)
18596 {
18597 WOLFSSL_METHOD* m;
18598 WOLFSSL_ENTER("TLSv1_2_method");
18599 #ifndef NO_WOLFSSL_CLIENT
18600 m = wolfTLSv1_2_client_method_ex(heap);
18601 #else
18602 m = wolfTLSv1_2_server_method_ex(heap);
18603 #endif
18604 if (m != NULL) {
18605 m->side = WOLFSSL_NEITHER_END;
18606 }
18607 return m;
18608 }
18609 #endif /* !WOLFSSL_NO_TLS12 */
18610
18611 #ifdef WOLFSSL_TLS13
18612 /* Gets a WOLFSSL_METHOD type that is not set as client or server
18613 *
18614 * Returns a pointer to a WOLFSSL_METHOD struct
18615 */
18616 WOLFSSL_METHOD* wolfTLSv1_3_method(void)
18617 {
18618 return wolfTLSv1_3_method_ex(NULL);
18619 }
18620 WOLFSSL_METHOD* wolfTLSv1_3_method_ex(void* heap)
18621 {
18622 WOLFSSL_METHOD* m;
18623 WOLFSSL_ENTER("TLSv1_3_method");
18624 #ifndef NO_WOLFSSL_CLIENT
18625 m = wolfTLSv1_3_client_method_ex(heap);
18626 #else
18627 m = wolfTLSv1_3_server_method_ex(heap);
18628 #endif
18629 if (m != NULL) {
18630 m->side = WOLFSSL_NEITHER_END;
18631 }
18632 return m;
18633 }
18634 #endif /* WOLFSSL_TLS13 */
18635
18636#ifdef WOLFSSL_DTLS
18637 WOLFSSL_METHOD* wolfDTLS_method(void)
18638 {
18639 return wolfDTLS_method_ex(NULL);
18640 }
18641 WOLFSSL_METHOD* wolfDTLS_method_ex(void* heap)
18642 {
18643 WOLFSSL_METHOD* m;
18644 WOLFSSL_ENTER("DTLS_method_ex");
18645 #ifndef NO_WOLFSSL_CLIENT
18646 m = wolfDTLS_client_method_ex(heap);
18647 #else
18648 m = wolfDTLS_server_method_ex(heap);
18649 #endif
18650 if (m != NULL) {
18651 m->side = WOLFSSL_NEITHER_END;
18652 }
18653 return m;
18654 }
18655
18656 #ifndef NO_OLD_TLS
18657 WOLFSSL_METHOD* wolfDTLSv1_method(void)
18658 {
18659 return wolfDTLSv1_method_ex(NULL);
18660 }
18661 WOLFSSL_METHOD* wolfDTLSv1_method_ex(void* heap)
18662 {
18663 WOLFSSL_METHOD* m;
18664 WOLFSSL_ENTER("DTLSv1_method_ex");
18665 #ifndef NO_WOLFSSL_CLIENT
18666 m = wolfDTLSv1_client_method_ex(heap);
18667 #else
18668 m = wolfDTLSv1_server_method_ex(heap);
18669 #endif
18670 if (m != NULL) {
18671 m->side = WOLFSSL_NEITHER_END;
18672 }
18673 return m;
18674 }
18675 #endif /* !NO_OLD_TLS */
18676 #ifndef WOLFSSL_NO_TLS12
18677 WOLFSSL_METHOD* wolfDTLSv1_2_method(void)
18678 {
18679 return wolfDTLSv1_2_method_ex(NULL);
18680 }
18681 WOLFSSL_METHOD* wolfDTLSv1_2_method_ex(void* heap)
18682 {
18683 WOLFSSL_METHOD* m;
18684 WOLFSSL_ENTER("DTLSv1_2_method");
18685 #ifndef NO_WOLFSSL_CLIENT
18686 m = wolfDTLSv1_2_client_method_ex(heap);
18687 #else
18688 m = wolfDTLSv1_2_server_method_ex(heap);
18689 #endif
18690 if (m != NULL) {
18691 m->side = WOLFSSL_NEITHER_END;
18692 }
18693 return m;
18694 }
18695 #endif /* !WOLFSSL_NO_TLS12 */
18696 #ifdef WOLFSSL_DTLS13
18697 WOLFSSL_METHOD* wolfDTLSv1_3_method(void)
18698 {
18699 return wolfDTLSv1_3_method_ex(NULL);
18700 }
18701 WOLFSSL_METHOD* wolfDTLSv1_3_method_ex(void* heap)
18702 {
18703 WOLFSSL_METHOD* m;
18704 WOLFSSL_ENTER("DTLSv1_3_method");
18705 #ifndef NO_WOLFSSL_CLIENT
18706 m = wolfDTLSv1_3_client_method_ex(heap);
18707 #else
18708 m = wolfDTLSv1_3_server_method_ex(heap);
18709 #endif
18710 if (m != NULL) {
18711 m->side = WOLFSSL_NEITHER_END;
18712 }
18713 return m;
18714 }
18715 #endif /* WOLFSSL_DTLS13 */
18716#endif /* WOLFSSL_DTLS */
18717#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
18718
18719
18720#ifndef NO_WOLFSSL_SERVER
18721
18722 WOLFSSL_METHOD* wolfTLS_server_method(void)
18723 {
18724 return wolfTLS_server_method_ex(NULL);
18725 }
18726
18727 WOLFSSL_METHOD* wolfTLS_server_method_ex(void* heap)
18728 {
18729 WOLFSSL_METHOD* method =
18730 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18731 heap, DYNAMIC_TYPE_METHOD);
18732 (void)heap;
18733 WOLFSSL_ENTER("TLS_server_method_ex");
18734 if (method) {
18735 #if defined(WOLFSSL_TLS13)
18736 InitSSL_Method(method, MakeTLSv1_3());
18737 #elif !defined(WOLFSSL_NO_TLS12)
18738 InitSSL_Method(method, MakeTLSv1_2());
18739 #elif !defined(NO_OLD_TLS)
18740 InitSSL_Method(method, MakeTLSv1_1());
18741 #elif defined(WOLFSSL_ALLOW_TLSV10)
18742 InitSSL_Method(method, MakeTLSv1());
18743 #else
18744 #error No TLS version enabled! Consider using NO_TLS or WOLFCRYPT_ONLY.
18745 #endif
18746
18747 method->downgrade = 1;
18748 method->side = WOLFSSL_SERVER_END;
18749 }
18750 return method;
18751 }
18752
18753#ifndef NO_OLD_TLS
18754 #ifdef WOLFSSL_ALLOW_TLSV10
18755 WOLFSSL_METHOD* wolfTLSv1_server_method(void)
18756 {
18757 return wolfTLSv1_server_method_ex(NULL);
18758 }
18759 WOLFSSL_METHOD* wolfTLSv1_server_method_ex(void* heap)
18760 {
18761 WOLFSSL_METHOD* method =
18762 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18763 heap, DYNAMIC_TYPE_METHOD);
18764 (void)heap;
18765 WOLFSSL_ENTER("TLSv1_server_method_ex");
18766 if (method) {
18767 InitSSL_Method(method, MakeTLSv1());
18768 method->side = WOLFSSL_SERVER_END;
18769 }
18770 return method;
18771 }
18772 #endif /* WOLFSSL_ALLOW_TLSV10 */
18773
18774 WOLFSSL_METHOD* wolfTLSv1_1_server_method(void)
18775 {
18776 return wolfTLSv1_1_server_method_ex(NULL);
18777 }
18778 WOLFSSL_METHOD* wolfTLSv1_1_server_method_ex(void* heap)
18779 {
18780 WOLFSSL_METHOD* method =
18781 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18782 heap, DYNAMIC_TYPE_METHOD);
18783 (void)heap;
18784 WOLFSSL_ENTER("TLSv1_1_server_method_ex");
18785 if (method) {
18786 InitSSL_Method(method, MakeTLSv1_1());
18787 method->side = WOLFSSL_SERVER_END;
18788 }
18789 return method;
18790 }
18791#endif /* !NO_OLD_TLS */
18792
18793
18794#ifndef WOLFSSL_NO_TLS12
18795 WOLFSSL_ABI
18796 WOLFSSL_METHOD* wolfTLSv1_2_server_method(void)
18797 {
18798 return wolfTLSv1_2_server_method_ex(NULL);
18799 }
18800 WOLFSSL_METHOD* wolfTLSv1_2_server_method_ex(void* heap)
18801 {
18802 WOLFSSL_METHOD* method =
18803 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18804 heap, DYNAMIC_TYPE_METHOD);
18805 (void)heap;
18806 WOLFSSL_ENTER("TLSv1_2_server_method_ex");
18807 if (method) {
18808 InitSSL_Method(method, MakeTLSv1_2());
18809 method->side = WOLFSSL_SERVER_END;
18810 }
18811 return method;
18812 }
18813#endif /* !WOLFSSL_NO_TLS12 */
18814
18815#ifdef WOLFSSL_TLS13
18816 /* The TLS v1.3 server method data.
18817 *
18818 * returns the method data for a TLS v1.3 server.
18819 */
18820 WOLFSSL_ABI
18821 WOLFSSL_METHOD* wolfTLSv1_3_server_method(void)
18822 {
18823 return wolfTLSv1_3_server_method_ex(NULL);
18824 }
18825
18826 /* The TLS v1.3 server method data.
18827 *
18828 * heap The heap used for allocation.
18829 * returns the method data for a TLS v1.3 server.
18830 */
18831 WOLFSSL_METHOD* wolfTLSv1_3_server_method_ex(void* heap)
18832 {
18833 WOLFSSL_METHOD* method =
18834 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18835 heap, DYNAMIC_TYPE_METHOD);
18836 (void)heap;
18837 WOLFSSL_ENTER("TLSv1_3_server_method_ex");
18838 if (method) {
18839 InitSSL_Method(method, MakeTLSv1_3());
18840 method->side = WOLFSSL_SERVER_END;
18841 }
18842 return method;
18843 }
18844#endif /* WOLFSSL_TLS13 */
18845
18846#ifdef WOLFSSL_DTLS
18847 WOLFSSL_METHOD* wolfDTLS_server_method(void)
18848 {
18849 return wolfDTLS_server_method_ex(NULL);
18850 }
18851 WOLFSSL_METHOD* wolfDTLS_server_method_ex(void* heap)
18852 {
18853 WOLFSSL_METHOD* method =
18854 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18855 heap, DYNAMIC_TYPE_METHOD);
18856 (void)heap;
18857 WOLFSSL_ENTER("DTLS_server_method_ex");
18858 if (method) {
18859 #if defined(WOLFSSL_DTLS13)
18860 InitSSL_Method(method, MakeDTLSv1_3());
18861 #elif !defined(WOLFSSL_NO_TLS12)
18862 InitSSL_Method(method, MakeDTLSv1_2());
18863 #elif !defined(NO_OLD_TLS)
18864 InitSSL_Method(method, MakeDTLSv1());
18865 #else
18866 #error No DTLS version enabled!
18867 #endif
18868
18869 method->downgrade = 1;
18870 method->side = WOLFSSL_SERVER_END;
18871 }
18872 return method;
18873 }
18874
18875 #ifndef NO_OLD_TLS
18876 WOLFSSL_METHOD* wolfDTLSv1_server_method(void)
18877 {
18878 return wolfDTLSv1_server_method_ex(NULL);
18879 }
18880 WOLFSSL_METHOD* wolfDTLSv1_server_method_ex(void* heap)
18881 {
18882 WOLFSSL_METHOD* method =
18883 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18884 heap, DYNAMIC_TYPE_METHOD);
18885 (void)heap;
18886 WOLFSSL_ENTER("DTLSv1_server_method_ex");
18887 if (method) {
18888 InitSSL_Method(method, MakeDTLSv1());
18889 method->side = WOLFSSL_SERVER_END;
18890 }
18891 return method;
18892 }
18893 #endif /* !NO_OLD_TLS */
18894
18895 #ifndef WOLFSSL_NO_TLS12
18896 WOLFSSL_METHOD* wolfDTLSv1_2_server_method(void)
18897 {
18898 return wolfDTLSv1_2_server_method_ex(NULL);
18899 }
18900 WOLFSSL_METHOD* wolfDTLSv1_2_server_method_ex(void* heap)
18901 {
18902 WOLFSSL_METHOD* method =
18903 (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
18904 heap, DYNAMIC_TYPE_METHOD);
18905 WOLFSSL_ENTER("DTLSv1_2_server_method_ex");
18906 (void)heap;
18907 if (method) {
18908 InitSSL_Method(method, MakeDTLSv1_2());
18909 method->side = WOLFSSL_SERVER_END;
18910 }
18911 (void)heap;
18912 return method;
18913 }
18914 #endif /* !WOLFSSL_NO_TLS12 */
18915#endif /* WOLFSSL_DTLS */
18916
18917#endif /* NO_WOLFSSL_SERVER */
18918
18919#endif /* NO_TLS */
18920
18921#endif /* WOLFCRYPT_ONLY */