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/pk.c
raw
1/* pk.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#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24#include <wolfssl/internal.h>
25#ifndef WC_NO_RNG
26 #include <wolfssl/wolfcrypt/random.h>
27#endif
28
29#if !defined(WOLFSSL_PK_INCLUDED)
30 #ifndef WOLFSSL_IGNORE_FILE_WARN
31 #warning pk.c does not need to be compiled separately from ssl.c
32 #endif
33#else
34
35#ifndef NO_RSA
36 #include <wolfssl/wolfcrypt/rsa.h>
37#endif
38
39/*******************************************************************************
40 * COMMON FUNCTIONS
41 ******************************************************************************/
42
43/* Calculate the number of bytes require to represent a length value in ASN.
44 *
45 * @param [in] l Length value to use.
46 * @return Number of bytes required to represent length value.
47 */
48#define ASN_LEN_SIZE(l) \
49 (((l) < 128) ? 1 : (((l) < 256) ? 2 : 3))
50
51#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
52
53#ifndef NO_ASN
54
55#if (!defined(NO_FILESYSTEM) && (defined(OPENSSL_EXTRA) || \
56 defined(OPENSSL_ALL))) || (!defined(NO_BIO) && defined(OPENSSL_EXTRA))
57/* Convert the PEM encoding in the buffer to DER.
58 *
59 * @param [in] pem Buffer containing PEM encoded data.
60 * @param [in] pemSz Size of data in buffer in bytes.
61 * @param [in] cb Password callback when PEM encrypted.
62 * @param [in] pass NUL terminated string for passphrase when PEM
63 * encrypted.
64 * @param [in] keyType Type of key to match against PEM header/footer.
65 * @param [out] keyFormat Format of key.
66 * @param [out] der Buffer holding DER encoding.
67 * @return Negative on failure.
68 * @return Number of bytes consumed on success.
69 */
70static int pem_mem_to_der(const char* pem, int pemSz, wc_pem_password_cb* cb,
71 void* pass, int keyType, int* keyFormat, DerBuffer** der)
72{
73 WC_DECLARE_VAR(info, EncryptedInfo, 1, 0);
74 wc_pem_password_cb* localCb = NULL;
75 int ret = 0;
76
77 if (cb != NULL) {
78 localCb = cb;
79 }
80 else if (pass != NULL) {
81 localCb = wolfSSL_PEM_def_callback;
82 }
83
84#ifdef WOLFSSL_SMALL_STACK
85 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
86 DYNAMIC_TYPE_ENCRYPTEDINFO);
87 if (info == NULL) {
88 WOLFSSL_ERROR_MSG("Error getting memory for EncryptedInfo structure");
89 ret = MEMORY_E;
90 }
91#endif /* WOLFSSL_SMALL_STACK */
92
93 if (ret == 0) {
94 XMEMSET(info, 0, sizeof(EncryptedInfo));
95 info->passwd_cb = localCb;
96 info->passwd_userdata = pass;
97
98 /* Do not strip PKCS8 header */
99 ret = PemToDer((const unsigned char *)pem, pemSz, keyType, der, NULL,
100 info, keyFormat);
101 if (ret < 0) {
102 WOLFSSL_ERROR_MSG("Bad PEM To DER");
103 }
104 }
105 if (ret >= 0) {
106 ret = (int)info->consumed;
107 }
108
109 WC_FREE_VAR_EX(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
110
111 return ret;
112}
113#endif
114
115#if defined(OPENSSL_EXTRA) && (!defined(NO_RSA) || !defined(WOLFCRYPT_ONLY))
116#ifndef NO_BIO
117/* Read PEM data from a BIO and decode to DER in a new buffer.
118 *
119 * @param [in, out] bio BIO object to read with.
120 * @param [in] cb Password callback when PEM encrypted.
121 * @param [in] pass NUL terminated string for passphrase when PEM
122 * encrypted.
123 * @param [in] keyType Type of key to match against PEM header/footer.
124 * @param [out] keyFormat Format of key.
125 * @param [out] der Buffer holding DER encoding.
126 * @return Negative on failure.
127 * @return Number of bytes consumed on success.
128 */
129static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb,
130 void* pass, int keyType, int* keyFormat, DerBuffer** der)
131{
132 int ret;
133 char* mem = NULL;
134 int memSz;
135 int alloced = 0;
136
137 ret = wolfssl_read_bio(bio, &mem, &memSz, &alloced);
138 if (ret == 0) {
139 ret = pem_mem_to_der(mem, memSz, cb, pass, keyType, keyFormat, der);
140 /* Write left over data back to BIO if not a file BIO */
141 if ((ret > 0) && ((memSz - ret) > 0) &&
142 (bio->type != WOLFSSL_BIO_FILE)) {
143 int res;
144 if (!alloced) {
145 /* If wolfssl_read_bio() points mem at the buffer internal to
146 * bio, we need to dup it before calling wolfSSL_BIO_write(),
147 * because the latter may reallocate the bio, invalidating the
148 * mem pointer before reading from it.
149 */
150 char *mem_dup = (char *)XMALLOC((size_t)(memSz - ret),
151 NULL, DYNAMIC_TYPE_TMP_BUFFER);
152 if (mem_dup != NULL) {
153 XMEMCPY(mem_dup, mem + ret, (size_t)(memSz - ret));
154 res = wolfSSL_BIO_write(bio, mem_dup, memSz - ret);
155 mem = mem_dup;
156 alloced = 1;
157 }
158 else
159 res = MEMORY_E;
160 }
161 else
162 res = wolfSSL_BIO_write(bio, mem + ret, memSz - ret);
163 if (res != memSz - ret) {
164 WOLFSSL_ERROR_MSG("Unable to write back excess data");
165 if (res < 0) {
166 ret = res;
167 }
168 else {
169 ret = MEMORY_E;
170 }
171 }
172 }
173 if (alloced) {
174 XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
175 }
176 }
177
178 return ret;
179}
180#endif /* !NO_BIO */
181
182#if !defined(NO_FILESYSTEM)
183/* Read PEM data from a file and decode to DER in a new buffer.
184 *
185 * @param [in] fp File pointer to read with.
186 * @param [in] cb Password callback when PEM encrypted.
187 * @param [in] pass NUL terminated string for passphrase when PEM
188 * encrypted.
189 * @param [in] keyType Type of key to match against PEM header/footer.
190 * @param [out] keyFormat Format of key.
191 * @param [out] der Buffer holding DER encoding.
192 * @return Negative on failure.
193 * @return Number of bytes consumed on success.
194 */
195static int pem_read_file_key(XFILE fp, wc_pem_password_cb* cb, void* pass,
196 int keyType, int* keyFormat, DerBuffer** der)
197{
198 int ret;
199 char* mem = NULL;
200 int memSz;
201
202 ret = wolfssl_read_file(fp, &mem, &memSz);
203 if (ret == 0) {
204 ret = pem_mem_to_der(mem, memSz, cb, pass, keyType, keyFormat, der);
205 XFREE(mem, NULL, DYNAMIC_TYPE_OPENSSL);
206 }
207
208 return ret;
209}
210#endif /* !NO_FILESYSTEM */
211#endif
212
213#if defined(OPENSSL_EXTRA) && ((!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) \
214 || !defined(WOLFCRYPT_ONLY))
215/* Convert DER data to PEM in an allocated buffer.
216 *
217 * @param [in] der Buffer containing DER data.
218 * @param [in] derSz Size of DER data in bytes.
219 * @param [in] type Type of key being encoded.
220 * @param [in] heap Heap hint for dynamic memory allocation.
221 * @param [out] out Allocated buffer containing PEM.
222 * @param [out] outSz Size of PEM encoding.
223 * @return 1 on success.
224 * @return 0 on error.
225 */
226static int der_to_pem_alloc(const unsigned char* der, int derSz, int type,
227 void* heap, byte** out, int* outSz)
228{
229 int ret = 1;
230 int pemSz;
231 byte* pem = NULL;
232
233 (void)heap;
234
235 /* Convert DER to PEM - to get size. */
236 pemSz = wc_DerToPem(der, (word32)derSz, NULL, 0, type);
237 if (pemSz < 0) {
238 ret = 0;
239 }
240
241 if (ret == 1) {
242 /* Allocate memory for PEM to be encoded into. */
243 pem = (byte*)XMALLOC((size_t)pemSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
244 if (pem == NULL) {
245 ret = 0;
246 }
247 }
248
249 /* Convert DER to PEM. */
250 if ((ret == 1) && (wc_DerToPem(der, (word32)derSz, pem, (word32)pemSz,
251 type) < 0)) {
252 ret = 0;
253 XFREE(pem, heap, DYNAMIC_TYPE_TMP_BUFFER);
254 pem = NULL;
255 }
256
257 *out = pem;
258 *outSz = pemSz;
259 return ret;
260}
261
262#ifndef NO_BIO
263/* Write the DER data as PEM into BIO.
264 *
265 * @param [in] der Buffer containing DER data.
266 * @param [in] derSz Size of DER data in bytes.
267 * @param [in, out] bio BIO object to write with.
268 * @param [in] type Type of key being encoded.
269 * @return 1 on success.
270 * @return 0 on error.
271 */
272static int der_write_to_bio_as_pem(const unsigned char* der, int derSz,
273 WOLFSSL_BIO* bio, int type)
274{
275 int ret;
276 int pemSz;
277 byte* pem = NULL;
278
279 ret = der_to_pem_alloc(der, derSz, type, bio->heap, &pem, &pemSz);
280 if (ret == 1) {
281 int len = wolfSSL_BIO_write(bio, pem, pemSz);
282 if (len != pemSz) {
283 WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO");
284 ret = 0;
285 }
286 }
287
288 XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
289 return ret;
290}
291#endif
292#endif
293
294#if defined(OPENSSL_EXTRA) && \
295 ((!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) || \
296 (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || \
297 (defined(HAVE_ECC) && defined(WOLFSSL_KEY_GEN)))
298#if !defined(NO_FILESYSTEM)
299/* Write the DER data as PEM into file pointer.
300 *
301 * @param [in] der Buffer containing DER data.
302 * @param [in] derSz Size of DER data in bytes.
303 * @param [in] fp File pointer to write with.
304 * @param [in] type Type of key being encoded.
305 * @param [in] heap Heap hint for dynamic memory allocation.
306 * @return 1 on success.
307 * @return 0 on error.
308 */
309static int der_write_to_file_as_pem(const unsigned char* der, int derSz,
310 XFILE fp, int type, void* heap)
311{
312 int ret;
313 int pemSz;
314 byte* pem = NULL;
315
316 ret = der_to_pem_alloc(der, derSz, type, heap, &pem, &pemSz);
317 if (ret == 1) {
318 int len = (int)XFWRITE(pem, 1, (size_t)pemSz, fp);
319 if (len != pemSz) {
320 WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO");
321 ret = 0;
322 }
323 }
324
325 XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
326 return ret;
327}
328#endif
329#endif
330
331#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \
332 defined(WOLFSSL_PEM_TO_DER)
333/* Encrypt private key into PEM format.
334 *
335 * DER is encrypted in place.
336 *
337 * @param [in] der DER encoding of private key.
338 * @param [in] derSz Size of DER in bytes.
339 * @param [in] cipher EVP cipher.
340 * @param [in] passwd Password to use with encryption.
341 * @param [in] passedSz Size of password in bytes.
342 * @param [out] cipherInfo PEM cipher information lines.
343 * @param [in] maxDerSz Maximum size of DER buffer.
344 * @param [in] hashType Hash algorithm
345 * @return 1 on success.
346 * @return 0 on error.
347 */
348int EncryptDerKey(byte *der, int *derSz, const WOLFSSL_EVP_CIPHER* cipher,
349 unsigned char* passwd, int passwdSz, byte **cipherInfo, int maxDerSz,
350 int hashType)
351{
352 int ret = 0;
353 int paddingSz = 0;
354 word32 idx;
355 word32 cipherInfoSz = 0;
356 WC_DECLARE_VAR(info, EncryptedInfo, 1, 0);
357
358 WOLFSSL_ENTER("EncryptDerKey");
359
360 /* Validate parameters. */
361 if ((der == NULL) || (derSz == NULL) || (cipher == NULL) ||
362 (passwd == NULL) || (cipherInfo == NULL)) {
363 ret = BAD_FUNC_ARG;
364 }
365
366 #ifdef WOLFSSL_SMALL_STACK
367 if (ret == 0) {
368 /* Allocate encrypted info. */
369 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
370 DYNAMIC_TYPE_ENCRYPTEDINFO);
371 if (info == NULL) {
372 WOLFSSL_MSG("malloc failed");
373 ret = MEMORY_E;
374 }
375 }
376 #endif
377 if (ret == 0) {
378 /* Clear the encrypted info and set name. */
379 XMEMSET(info, 0, sizeof(EncryptedInfo));
380 XSTRNCPY(info->name, cipher, NAME_SZ - 1);
381 info->name[NAME_SZ - 1] = '\0'; /* null term */
382
383 /* Get encrypted info from name. */
384 ret = wc_EncryptedInfoGet(info, info->name);
385 if (ret != 0) {
386 WOLFSSL_MSG("unsupported cipher");
387 }
388 }
389
390 if (ret == 0) {
391 /* Generate a random salt. */
392 if (wolfSSL_RAND_bytes(info->iv, (int)info->ivSz) != 1) {
393 WOLFSSL_MSG("generate iv failed");
394 ret = WOLFSSL_FATAL_ERROR;
395 }
396 }
397
398 if (ret == 0) {
399 /* Calculate padding size - always a padding block. */
400 paddingSz = (int)info->ivSz - ((*derSz) % (int)info->ivSz);
401 /* Check der is big enough. */
402 if (maxDerSz < (*derSz) + paddingSz) {
403 WOLFSSL_MSG("not enough DER buffer allocated");
404 ret = BAD_FUNC_ARG;
405 }
406 }
407 if (ret == 0) {
408 /* Set padding bytes to padding length. */
409 XMEMSET(der + (*derSz), (byte)paddingSz, (size_t)paddingSz);
410 /* Add padding to DER size. */
411 (*derSz) += (int)paddingSz;
412
413 /* Encrypt DER buffer. */
414 ret = wc_BufferKeyEncrypt(info, der, (word32)*derSz, passwd, passwdSz,
415 hashType);
416 if (ret != 0) {
417 WOLFSSL_MSG("encrypt key failed");
418 }
419 }
420
421 if (ret == 0) {
422 /* Create cipher info : 'cipher_name,Salt(hex)' */
423 cipherInfoSz = (word32)(2 * info->ivSz + XSTRLEN(info->name) + 2);
424 /* Allocate memory for PEM encryption lines. */
425 *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL, DYNAMIC_TYPE_STRING);
426 if (*cipherInfo == NULL) {
427 WOLFSSL_MSG("malloc failed");
428 ret = MEMORY_E;
429 }
430 }
431 if (ret == 0) {
432 /* Copy in name and add on comma. */
433 XSTRLCPY((char*)*cipherInfo, info->name, cipherInfoSz);
434 XSTRLCAT((char*)*cipherInfo, ",", cipherInfoSz);
435
436 /* Find end of string. */
437 idx = (word32)XSTRLEN((char*)*cipherInfo);
438 /* Calculate remaining bytes. */
439 cipherInfoSz -= idx;
440
441 /* Encode IV into PEM encryption lines. */
442 ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo + idx,
443 &cipherInfoSz);
444 if (ret != 0) {
445 WOLFSSL_MSG("Base16_Encode failed");
446 XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_STRING);
447 *cipherInfo = NULL;
448 }
449 }
450
451 WC_FREE_VAR_EX(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
452 return ret == 0;
453}
454#endif /* OPENSSL_EXTRA && WOLFSSL_KEY_GEN && WOLFSSL_PEM_TO_DER */
455
456
457#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \
458 (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)) && \
459 (!defined(NO_RSA) || defined(HAVE_ECC))
460/* Encrypt the DER in PEM format.
461 *
462 * @param [in] der DER encoded private key.
463 * @param [in] derSz Size of DER in bytes.
464 * @param [in] cipher EVP cipher.
465 * @param [in] passwd Password to use in encryption.
466 * @param [in] passwdSz Size of password in bytes.
467 * @param [in] type PEM type of write out.
468 * @param [in] heap Dynamic memory hint.
469 * @param [out] out Allocated buffer containing PEM encoding.
470 * heap was NULL and dynamic type is DYNAMIC_TYPE_KEY.
471 * @param [out] outSz Size of PEM encoding in bytes.
472 * @return 1 on success.
473 * @return 0 on failure.
474 */
475static int der_to_enc_pem_alloc(unsigned char* der, int derSz,
476 const WOLFSSL_EVP_CIPHER *cipher, unsigned char *passwd, int passwdSz,
477 int type, void* heap, byte** out, int* outSz)
478{
479 int ret = 1;
480 byte* tmp = NULL;
481 byte* cipherInfo = NULL;
482 int pemSz = 0;
483 int derAllocSz = derSz;
484 int hashType = WC_HASH_TYPE_NONE;
485#if !defined(NO_MD5)
486 hashType = WC_MD5;
487#elif !defined(NO_SHA)
488 hashType = WC_SHA;
489#endif
490
491 /* Macro doesn't always use it. */
492 (void)heap;
493
494 /* Encrypt DER buffer if required. */
495 if ((ret == 1) && (passwd != NULL) && (passwdSz > 0) && (cipher != NULL)) {
496 int blockSz = wolfSSL_EVP_CIPHER_block_size(cipher);
497 byte *tmpBuf;
498
499 /* Add space for padding. */
500 #ifdef WOLFSSL_NO_REALLOC
501 tmpBuf = (byte*)XMALLOC((size_t)(derSz + blockSz), heap,
502 DYNAMIC_TYPE_TMP_BUFFER);
503 if (tmpBuf != NULL && der != NULL)
504 {
505 XMEMCPY(tmpBuf, der, (size_t)(derSz));
506 XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER);
507 der = NULL;
508 }
509 #else
510 tmpBuf = (byte*)XREALLOC(der, (size_t)(derSz + blockSz), heap,
511 DYNAMIC_TYPE_TMP_BUFFER);
512 #endif
513 if (tmpBuf == NULL) {
514 WOLFSSL_ERROR_MSG("Extending DER buffer failed");
515 ret = 0; /* der buffer is free'd at the end of the function */
516 }
517 else {
518 der = tmpBuf;
519 derAllocSz = derSz + blockSz;
520
521 /* Encrypt DER inline. */
522 ret = EncryptDerKey(der, &derSz, cipher, passwd, passwdSz,
523 &cipherInfo, derSz + blockSz, hashType);
524 if (ret != 1) {
525 WOLFSSL_ERROR_MSG("EncryptDerKey failed");
526 }
527 }
528 }
529
530 if (ret == 1) {
531 /* Calculate PEM encoding size. */
532 pemSz = wc_DerToPemEx(der, (word32)derSz, NULL, 0, cipherInfo, type);
533 if (pemSz <= 0) {
534 WOLFSSL_ERROR_MSG("wc_DerToPemEx failed");
535 ret = 0;
536 }
537 }
538 if (ret == 1) {
539 /* Allocate space for PEM encoding plus a NUL terminator. */
540 tmp = (byte*)XMALLOC((size_t)(pemSz + 1), NULL, DYNAMIC_TYPE_KEY);
541 if (tmp == NULL) {
542 WOLFSSL_ERROR_MSG("malloc failed");
543 ret = 0;
544 }
545 }
546 if (ret == 1) {
547 /* DER to PEM */
548 pemSz = wc_DerToPemEx(der, (word32)derSz, tmp, (word32)pemSz,
549 cipherInfo, type);
550 if (pemSz <= 0) {
551 WOLFSSL_ERROR_MSG("wc_DerToPemEx failed");
552 ret = 0;
553 }
554 }
555 if (ret == 1) {
556 /* NUL terminate string - PEM. */
557 tmp[pemSz] = 0x00;
558 /* Return allocated buffer and size. */
559 *out = tmp;
560 *outSz = pemSz;
561 /* Don't free returning buffer. */
562 tmp = NULL;
563 }
564
565 XFREE(tmp, NULL, DYNAMIC_TYPE_KEY);
566 XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
567 if (der != NULL) {
568 ForceZero(der, (word32)derAllocSz);
569 XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER);
570 }
571
572 return ret;
573}
574#endif
575
576#endif /* !NO_ASN */
577
578#if !defined(NO_CERTS) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
579 !defined(NO_STDIO_FILESYSTEM) && (!defined(NO_RSA) || !defined(NO_DSA) || \
580 defined(HAVE_ECC)) && defined(OPENSSL_EXTRA)
581/* Print the number bn in hex with name field and indentation indent to file fp.
582 *
583 * Used by wolfSSL_DSA_print_fp, wolfSSL_RSA_print_fp and
584 * wolfSSL_EC_KEY_print_fp to print DSA, RSA and ECC keys and parameters.
585 *
586 * @param [in] fp File pointer to write to.
587 * @param [in] indent Number of spaces to prepend to each line.
588 * @param [in] field Name of field.
589 * @param [in] bn Big number to print.
590 * @return 1 on success.
591 * @return 0 on failure.
592 * @return BAD_FUNC_ARG when fp is invalid, indent is less than 0, or field or
593 * bn or NULL.
594 */
595static int pk_bn_field_print_fp(XFILE fp, int indent, const char* field,
596 const WOLFSSL_BIGNUM* bn)
597{
598 static const int HEX_INDENT = 4;
599 static const int MAX_DIGITS_PER_LINE = 30;
600
601 int ret = 1;
602 int i = 0;
603 char* buf = NULL;
604
605 /* Internal function - assume parameters are valid. */
606
607 /* Convert BN to hexadecimal character array (allocates buffer). */
608 buf = wolfSSL_BN_bn2hex(bn);
609 if (buf == NULL) {
610 ret = 0;
611 }
612 if (ret == 1) {
613 /* Print leading spaces, name and spaces before data. */
614 if (indent > 0) {
615 if (XFPRINTF(fp, "%*s", indent, "") < 0)
616 ret = 0;
617 }
618 }
619 if (ret == 1) {
620 if (XFPRINTF(fp, "%s:\n", field) < 0)
621 ret = 0;
622 }
623 if (ret == 1) {
624 if (indent > 0) {
625 if (XFPRINTF(fp, "%*s", indent, "") < 0)
626 ret = 0;
627 }
628 }
629 if (ret == 1) {
630 if (XFPRINTF(fp, "%*s", HEX_INDENT, "") < 0)
631 ret = 0;
632 }
633 if (ret == 1) {
634 /* Print first byte - should always exist. */
635 if ((buf[i] != '\0') && (buf[i+1] != '\0')) {
636 if (XFPRINTF(fp, "%c", buf[i++]) < 0)
637 ret = 0;
638 else if (XFPRINTF(fp, "%c", buf[i++]) < 0)
639 ret = 0;
640 }
641 }
642 if (ret == 1) {
643 /* Print each hexadecimal character with byte separator. */
644 while ((buf[i] != '\0') && (buf[i+1] != '\0')) {
645 /* Byte separator every two nibbles - one byte. */
646 if (XFPRINTF(fp, ":") < 0) {
647 ret = 0;
648 break;
649 }
650 /* New line after every 15 bytes - 30 nibbles. */
651 if (i % MAX_DIGITS_PER_LINE == 0) {
652 if (XFPRINTF(fp, "\n") < 0) {
653 ret = 0;
654 break;
655 }
656 if (indent > 0) {
657 if (XFPRINTF(fp, "%*s", indent, "") < 0) {
658 ret = 0;
659 break;
660 }
661 }
662 if (XFPRINTF(fp, "%*s", HEX_INDENT, "") < 0) {
663 ret = 0;
664 break;
665 }
666 }
667 /* Print two nibbles - one byte. */
668 if (XFPRINTF(fp, "%c", buf[i++]) < 0) {
669 ret = 0;
670 break;
671 }
672 if (XFPRINTF(fp, "%c", buf[i++]) < 0) {
673 ret = 0;
674 break;
675 }
676 }
677 /* Ensure on new line after data. */
678 if (XFPRINTF(fp, "\n") < 0) {
679 ret = 0;
680 }
681 }
682
683 /* Dispose of any allocated character array. */
684 XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
685
686 return ret;
687}
688#endif /* !NO_CERTS && XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM &&
689 * (!NO_DSA || !NO_RSA || HAVE_ECC) */
690
691#if defined(OPENSSL_EXTRA) && defined(XSNPRINTF) && !defined(NO_BIO) && \
692 !defined(NO_RSA)
693/* snprintf() must be available */
694
695/* Maximum number of extra indent spaces on each line. */
696#define PRINT_NUM_MAX_INDENT 48
697/* Maximum size of a line containing a value. */
698#define PRINT_NUM_MAX_VALUE_LINE PRINT_NUM_MAX_INDENT
699/* Number of leading spaces on each line. */
700#define PRINT_NUM_INDENT_CNT 4
701/* Indent spaces for number lines. */
702#define PRINT_NUM_INDENT " "
703/* 4 leading spaces and 15 bytes with colons is a complete line. */
704#define PRINT_NUM_MAX_DIGIT_LINE (PRINT_NUM_INDENT_CNT + 3 * 15)
705
706/* Print indent to BIO.
707 *
708 * @param [in] bio BIO object to write to.
709 * @param [in] line Buffer to put characters to before writing to BIO.
710 * @param [in] lineLen Length of buffer.
711 * @return 1 on success.
712 * @return 0 on failure.
713 */
714static int wolfssl_print_indent(WOLFSSL_BIO* bio, char* line, int lineLen,
715 int indent)
716{
717 int ret = 1;
718
719 if (indent > 0) {
720 int len_wanted;
721 /* Cap indent to buffer size to avoid format truncation warning */
722 if (indent >= lineLen) {
723 indent = lineLen - 1;
724 }
725 /* Print indent spaces. */
726 len_wanted = XSNPRINTF(line, (size_t)lineLen, "%*s", indent, " ");
727 if ((len_wanted < 0) || (len_wanted >= lineLen)) {
728 WOLFSSL_ERROR_MSG("Buffer overflow formatting indentation");
729 ret = 0;
730 }
731 else {
732 /* Write indents string to BIO */
733 if (wolfSSL_BIO_write(bio, line, len_wanted) <= 0) {
734 ret = 0;
735 }
736 }
737 }
738
739 return ret;
740}
741
742/* Print out name, and value in decimal and hex to BIO.
743 *
744 * @param [in] bio BIO object to write to.
745 * @param [in] value MP integer to write.
746 * @param [in] name Name of value.
747 * @param [in] indent Number of leading spaces before line.
748 * @return 1 on success.
749 * @return 0 on failure.
750 */
751static int wolfssl_print_value(WOLFSSL_BIO* bio, mp_int* value,
752 const char* name, int indent)
753{
754 int ret = 1;
755 int len;
756 char line[PRINT_NUM_MAX_VALUE_LINE + 1];
757
758 /* Get the length of hex encoded value. */
759 len = mp_unsigned_bin_size(value);
760 /* Value must no more than 32-bits - 4 bytes. */
761 if ((len < 0) || (len > 4)) {
762 WOLFSSL_ERROR_MSG("Error getting exponent size");
763 ret = 0;
764 }
765 if (ret == 1) {
766 /* Print any indent spaces. */
767 ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
768 }
769 if (ret == 1) {
770 /* Get 32-bits of value. */
771 word32 v = (word32)value->dp[0];
772 /* Print the line to the string. */
773 len = (int)XSNPRINTF(line, sizeof(line), "%s %u (0x%x)\n", name, v,
774 v);
775 if (len >= (int)sizeof(line)) {
776 WOLFSSL_ERROR_MSG("Buffer overflow while formatting value");
777 ret = 0;
778 } else {
779 /* Write string to BIO */
780 if (wolfSSL_BIO_write(bio, line, len) <= 0) {
781 ret = 0;
782 }
783 }
784 }
785
786 return ret;
787}
788
789/* Print out name and multi-precision number to BIO.
790 *
791 * @param [in] bio BIO object to write to.
792 * @param [in] num MP integer to write.
793 * @param [in] name Name of value.
794 * @param [in] indent Number of leading spaces before each line.
795 * @return 1 on success.
796 * @return 0 on failure.
797 */
798static int wolfssl_print_number(WOLFSSL_BIO* bio, mp_int* num, const char* name,
799 int indent)
800{
801 int ret = 1;
802 int rawLen = 0;
803 byte* rawKey = NULL;
804 char line[PRINT_NUM_MAX_DIGIT_LINE + 1];
805 int li = 0; /* Line index. */
806 int i;
807
808 /* Allocate a buffer to hold binary encoded data. */
809 rawLen = mp_unsigned_bin_size(num);
810 if (rawLen == 0) {
811 WOLFSSL_ERROR_MSG("Invalid number");
812 ret = 0;
813 }
814 if (ret == 1) {
815 rawKey = (byte*)XMALLOC((size_t)rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
816 if (rawKey == NULL) {
817 WOLFSSL_ERROR_MSG("Memory allocation error");
818 ret = 0;
819 }
820 }
821 /* Encode number as big-endian byte array. */
822 if ((ret == 1) && (mp_to_unsigned_bin(num, rawKey) < 0)) {
823 ret = 0;
824 }
825
826 if (ret == 1) {
827 /* Print any indent spaces. */
828 ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
829 }
830 if (ret == 1) {
831 /* Print header string line to string. */
832 li = XSNPRINTF(line, sizeof(line), "%s\n", name);
833 if (li >= (int)sizeof(line)) {
834 WOLFSSL_ERROR_MSG("Buffer overflow formatting name");
835 ret = 0;
836 }
837 else {
838 if (wolfSSL_BIO_write(bio, line, li) <= 0) {
839 ret = 0;
840 }
841 }
842 }
843 if (ret == 1) {
844 /* Print any indent spaces. */
845 ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
846 }
847 if (ret == 1) {
848 /* Start first digit line with spaces.
849 * Writing out zeros ensures number is a positive value. */
850 li = XSNPRINTF(line, sizeof(line), PRINT_NUM_INDENT "%s",
851 mp_leading_bit(num) ? "00:" : "");
852 if (li >= (int)sizeof(line)) {
853 WOLFSSL_ERROR_MSG("Buffer overflow formatting spaces");
854 ret = 0;
855 }
856 }
857
858 /* Put out each line of numbers. */
859 for (i = 0; (ret == 1) && (i < rawLen); i++) {
860 /* Encode another byte as 2 hex digits and append colon. */
861 int len_wanted = XSNPRINTF(line + li, sizeof(line) - (size_t)li,
862 "%02x:", rawKey[i]);
863 /* Check if there was room -- if not, print the current line, not
864 * including the newest octet.
865 */
866 if (len_wanted >= (int)sizeof(line) - li) {
867 /* bump current octet to the next line. */
868 --i;
869 /* More bytes coming so add a line break. */
870 line[li++] = '\n';
871 /* Write out the line. */
872 if (wolfSSL_BIO_write(bio, line, li) <= 0) {
873 ret = 0;
874 }
875 if (ret == 1) {
876 /* Print any indent spaces. */
877 ret = wolfssl_print_indent(bio, line, sizeof(line), indent);
878 }
879 /* Put the leading spaces on new line. */
880 XSTRNCPY(line, PRINT_NUM_INDENT, PRINT_NUM_INDENT_CNT + 1);
881 li = PRINT_NUM_INDENT_CNT;
882 }
883 else {
884 li += len_wanted;
885 }
886 }
887
888 if (ret == 1) {
889 /* Put out last line - replace last colon with carriage return. */
890 line[li-1] = '\n';
891 if (wolfSSL_BIO_write(bio, line, li) <= 0) {
892 ret = 0;
893 }
894 }
895
896 /* Dispose of any allocated data. */
897 XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
898 return ret;
899}
900
901#endif /* OPENSSL_EXTRA && XSNPRINTF && !NO_BIO && !NO_RSA */
902
903#endif /* OPENSSL_EXTRA */
904
905#if !defined(NO_CERTS) || (defined(OPENSSL_EXTRA) && (!defined(NO_RSA) || \
906 (!defined(NO_DH) && defined(HAVE_FIPS) && !FIPS_VERSION_GT(2,0)) || \
907 defined(HAVE_ECC)))
908
909/* Uses the DER SEQUENCE to determine size of DER data.
910 *
911 * Outer SEQUENCE encapsulates all the DER encoding.
912 * Add the length of the SEQUENCE data to the length of the SEQUENCE header.
913 *
914 * @param [in] seq Buffer holding DER encoded sequence.
915 * @param [in] len Length of data in buffer (may be larger than SEQ).
916 * @return Size of complete DER encoding on success.
917 * @return 0 on failure.
918 */
919static int wolfssl_der_length(const unsigned char* seq, int len)
920{
921 int ret = 0;
922 word32 i = 0;
923
924 /* Check it is a SEQUENCE and get the length of the underlying data.
925 * i is updated to be after SEQUENCE header bytes.
926 */
927 if (GetSequence_ex(seq, &i, &ret, (word32)len, 0) >= 0) {
928 /* Add SEQUENCE header length to underlying data length. */
929 ret += (int)i;
930 }
931
932 return ret;
933}
934
935#endif
936
937
938#define WOLFSSL_PK_RSA_INCLUDED
939#include "src/pk_rsa.c"
940
941
942/*******************************************************************************
943 * START OF DSA API
944 ******************************************************************************/
945
946#ifndef NO_DSA
947
948#if defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \
949 !defined(NO_STDIO_FILESYSTEM)
950/* return code compliant with OpenSSL :
951 * 1 if success, 0 if error
952 */
953int wolfSSL_DSA_print_fp(XFILE fp, WOLFSSL_DSA* dsa, int indent)
954{
955 int ret = 1;
956
957 WOLFSSL_ENTER("wolfSSL_DSA_print_fp");
958
959 if (fp == XBADFILE || dsa == NULL) {
960 ret = 0;
961 }
962
963 if (ret == 1 && dsa->p != NULL) {
964 int pBits = wolfSSL_BN_num_bits(dsa->p);
965 if (pBits == 0) {
966 ret = 0;
967 }
968 else {
969 if (XFPRINTF(fp, "%*s", indent, "") < 0)
970 ret = 0;
971 else if (XFPRINTF(fp, "Private-Key: (%d bit)\n", pBits) < 0)
972 ret = 0;
973 }
974 }
975 if (ret == 1 && dsa->priv_key != NULL) {
976 ret = pk_bn_field_print_fp(fp, indent, "priv", dsa->priv_key);
977 }
978 if (ret == 1 && dsa->pub_key != NULL) {
979 ret = pk_bn_field_print_fp(fp, indent, "pub", dsa->pub_key);
980 }
981 if (ret == 1 && dsa->p != NULL) {
982 ret = pk_bn_field_print_fp(fp, indent, "P", dsa->p);
983 }
984 if (ret == 1 && dsa->q != NULL) {
985 ret = pk_bn_field_print_fp(fp, indent, "Q", dsa->q);
986 }
987 if (ret == 1 && dsa->g != NULL) {
988 ret = pk_bn_field_print_fp(fp, indent, "G", dsa->g);
989 }
990
991 WOLFSSL_LEAVE("wolfSSL_DSA_print_fp", ret);
992
993 return ret;
994}
995#endif /* OPENSSL_EXTRA && XSNPRINTF && !NO_FILESYSTEM && NO_STDIO_FILESYSTEM */
996
997#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
998static void InitwolfSSL_DSA(WOLFSSL_DSA* dsa)
999{
1000 if (dsa) {
1001 dsa->p = NULL;
1002 dsa->q = NULL;
1003 dsa->g = NULL;
1004 dsa->pub_key = NULL;
1005 dsa->priv_key = NULL;
1006 dsa->internal = NULL;
1007 dsa->inSet = 0;
1008 dsa->exSet = 0;
1009 }
1010}
1011
1012
1013WOLFSSL_DSA* wolfSSL_DSA_new(void)
1014{
1015 WOLFSSL_DSA* external;
1016 DsaKey* key;
1017
1018 WOLFSSL_MSG("wolfSSL_DSA_new");
1019
1020 key = (DsaKey*) XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
1021 if (key == NULL) {
1022 WOLFSSL_MSG("wolfSSL_DSA_new malloc DsaKey failure");
1023 return NULL;
1024 }
1025
1026 external = (WOLFSSL_DSA*) XMALLOC(sizeof(WOLFSSL_DSA), NULL,
1027 DYNAMIC_TYPE_DSA);
1028 if (external == NULL) {
1029 WOLFSSL_MSG("wolfSSL_DSA_new malloc WOLFSSL_DSA failure");
1030 XFREE(key, NULL, DYNAMIC_TYPE_DSA);
1031 return NULL;
1032 }
1033
1034 InitwolfSSL_DSA(external);
1035 if (wc_InitDsaKey(key) != 0) {
1036 WOLFSSL_MSG("wolfSSL_DSA_new InitDsaKey failure");
1037 XFREE(key, NULL, DYNAMIC_TYPE_DSA);
1038 wolfSSL_DSA_free(external);
1039 return NULL;
1040 }
1041 external->internal = key;
1042
1043 return external;
1044}
1045
1046
1047void wolfSSL_DSA_free(WOLFSSL_DSA* dsa)
1048{
1049 WOLFSSL_MSG("wolfSSL_DSA_free");
1050
1051 if (dsa) {
1052 if (dsa->internal) {
1053 FreeDsaKey((DsaKey*)dsa->internal);
1054 XFREE(dsa->internal, NULL, DYNAMIC_TYPE_DSA);
1055 dsa->internal = NULL;
1056 }
1057 wolfSSL_BN_free(dsa->priv_key);
1058 wolfSSL_BN_free(dsa->pub_key);
1059 wolfSSL_BN_free(dsa->g);
1060 wolfSSL_BN_free(dsa->q);
1061 wolfSSL_BN_free(dsa->p);
1062 InitwolfSSL_DSA(dsa); /* set back to NULLs for safety */
1063
1064 XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
1065
1066 /* dsa = NULL, don't try to access or double free it */
1067 }
1068}
1069
1070/* wolfSSL -> OpenSSL */
1071int SetDsaExternal(WOLFSSL_DSA* dsa)
1072{
1073 DsaKey* key;
1074 WOLFSSL_MSG("Entering SetDsaExternal");
1075
1076 if (dsa == NULL || dsa->internal == NULL) {
1077 WOLFSSL_MSG("dsa key NULL error");
1078 return WOLFSSL_FATAL_ERROR;
1079 }
1080
1081 key = (DsaKey*)dsa->internal;
1082
1083 if (wolfssl_bn_set_value(&dsa->p, &key->p) != 1) {
1084 WOLFSSL_MSG("dsa p key error");
1085 return WOLFSSL_FATAL_ERROR;
1086 }
1087
1088 if (wolfssl_bn_set_value(&dsa->q, &key->q) != 1) {
1089 WOLFSSL_MSG("dsa q key error");
1090 return WOLFSSL_FATAL_ERROR;
1091 }
1092
1093 if (wolfssl_bn_set_value(&dsa->g, &key->g) != 1) {
1094 WOLFSSL_MSG("dsa g key error");
1095 return WOLFSSL_FATAL_ERROR;
1096 }
1097
1098 if (wolfssl_bn_set_value(&dsa->pub_key, &key->y) != 1) {
1099 WOLFSSL_MSG("dsa y key error");
1100 return WOLFSSL_FATAL_ERROR;
1101 }
1102
1103 if (wolfssl_bn_set_value(&dsa->priv_key, &key->x) != 1) {
1104 WOLFSSL_MSG("dsa x key error");
1105 return WOLFSSL_FATAL_ERROR;
1106 }
1107
1108 dsa->exSet = 1;
1109
1110 return 1;
1111}
1112#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
1113
1114#ifdef OPENSSL_EXTRA
1115/* Openssl -> WolfSSL */
1116int SetDsaInternal(WOLFSSL_DSA* dsa)
1117{
1118 DsaKey* key;
1119 WOLFSSL_MSG("Entering SetDsaInternal");
1120
1121 if (dsa == NULL || dsa->internal == NULL) {
1122 WOLFSSL_MSG("dsa key NULL error");
1123 return WOLFSSL_FATAL_ERROR;
1124 }
1125
1126 key = (DsaKey*)dsa->internal;
1127
1128 if (dsa->p != NULL &&
1129 wolfssl_bn_get_value(dsa->p, &key->p) != 1) {
1130 WOLFSSL_MSG("rsa p key error");
1131 return WOLFSSL_FATAL_ERROR;
1132 }
1133
1134 if (dsa->q != NULL &&
1135 wolfssl_bn_get_value(dsa->q, &key->q) != 1) {
1136 WOLFSSL_MSG("rsa q key error");
1137 return WOLFSSL_FATAL_ERROR;
1138 }
1139
1140 if (dsa->g != NULL &&
1141 wolfssl_bn_get_value(dsa->g, &key->g) != 1) {
1142 WOLFSSL_MSG("rsa g key error");
1143 return WOLFSSL_FATAL_ERROR;
1144 }
1145
1146 if (dsa->pub_key != NULL) {
1147 if (wolfssl_bn_get_value(dsa->pub_key, &key->y) != 1) {
1148 WOLFSSL_MSG("rsa pub_key error");
1149 return WOLFSSL_FATAL_ERROR;
1150 }
1151
1152 /* public key */
1153 key->type = DSA_PUBLIC;
1154 }
1155
1156 if (dsa->priv_key != NULL) {
1157 if (wolfssl_bn_get_value(dsa->priv_key, &key->x) != 1) {
1158 WOLFSSL_MSG("rsa priv_key error");
1159 return WOLFSSL_FATAL_ERROR;
1160 }
1161
1162 /* private key */
1163 key->type = DSA_PRIVATE;
1164 }
1165
1166 dsa->inSet = 1;
1167
1168 return 1;
1169}
1170
1171/* return code compliant with OpenSSL :
1172 * 1 if success, 0 if error
1173 */
1174int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa)
1175{
1176 int ret = 0;
1177
1178 WOLFSSL_ENTER("wolfSSL_DSA_generate_key");
1179
1180 if (dsa == NULL || dsa->internal == NULL) {
1181 WOLFSSL_MSG("Bad arguments");
1182 return 0;
1183 }
1184
1185 if (dsa->inSet == 0) {
1186 WOLFSSL_MSG("No DSA internal set, do it");
1187
1188 if (SetDsaInternal(dsa) != 1) {
1189 WOLFSSL_MSG("SetDsaInternal failed");
1190 return ret;
1191 }
1192 }
1193
1194#ifdef WOLFSSL_KEY_GEN
1195 {
1196 int initTmpRng = 0;
1197 WC_RNG *rng = NULL;
1198 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
1199
1200 WC_ALLOC_VAR_EX(tmpRng, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG,
1201 return WOLFSSL_FATAL_ERROR);
1202 if (wc_InitRng(tmpRng) == 0) {
1203 rng = tmpRng;
1204 initTmpRng = 1;
1205 }
1206 else {
1207 WOLFSSL_MSG("Bad RNG Init, trying global");
1208 rng = wolfssl_get_global_rng();
1209 }
1210
1211 if (rng) {
1212 /* These were allocated above by SetDsaInternal(). They should
1213 * be cleared before wc_MakeDsaKey() which reinitializes
1214 * x and y. */
1215 mp_clear(&((DsaKey*)dsa->internal)->x);
1216 mp_clear(&((DsaKey*)dsa->internal)->y);
1217
1218 if (wc_MakeDsaKey(rng, (DsaKey*)dsa->internal) != MP_OKAY)
1219 WOLFSSL_MSG("wc_MakeDsaKey failed");
1220 else if (SetDsaExternal(dsa) != 1)
1221 WOLFSSL_MSG("SetDsaExternal failed");
1222 else
1223 ret = 1;
1224 }
1225
1226 if (initTmpRng)
1227 wc_FreeRng(tmpRng);
1228
1229 WC_FREE_VAR_EX(tmpRng, NULL, DYNAMIC_TYPE_RNG);
1230 }
1231#else /* WOLFSSL_KEY_GEN */
1232 WOLFSSL_MSG("No Key Gen built in");
1233#endif
1234 return ret;
1235}
1236
1237
1238/* Returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
1239 */
1240WOLFSSL_DSA* wolfSSL_DSA_generate_parameters(int bits, unsigned char* seed,
1241 int seedLen, int* counterRet, unsigned long* hRet,
1242 WOLFSSL_BN_CB cb, void* CBArg)
1243{
1244 WOLFSSL_DSA* dsa;
1245
1246 WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters");
1247
1248 (void)cb;
1249 (void)CBArg;
1250 dsa = wolfSSL_DSA_new();
1251 if (dsa == NULL) {
1252 return NULL;
1253 }
1254
1255 if (wolfSSL_DSA_generate_parameters_ex(dsa, bits, seed, seedLen,
1256 counterRet, hRet, NULL) != 1) {
1257 wolfSSL_DSA_free(dsa);
1258 return NULL;
1259 }
1260
1261 return dsa;
1262}
1263
1264
1265/* return code compliant with OpenSSL :
1266 * 1 if success, 0 if error
1267 */
1268int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits,
1269 unsigned char* seed, int seedLen,
1270 int* counterRet,
1271 unsigned long* hRet, void* cb)
1272{
1273 int ret = 0;
1274
1275 (void)bits;
1276 (void)seed;
1277 (void)seedLen;
1278 (void)counterRet;
1279 (void)hRet;
1280 (void)cb;
1281
1282 WOLFSSL_ENTER("wolfSSL_DSA_generate_parameters_ex");
1283
1284 if (dsa == NULL || dsa->internal == NULL) {
1285 WOLFSSL_MSG("Bad arguments");
1286 return 0;
1287 }
1288
1289#ifdef WOLFSSL_KEY_GEN
1290 {
1291 int initTmpRng = 0;
1292 WC_RNG *rng = NULL;
1293 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
1294
1295 WC_ALLOC_VAR_EX(tmpRng, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG,
1296 return WOLFSSL_FATAL_ERROR);
1297 if (wc_InitRng(tmpRng) == 0) {
1298 rng = tmpRng;
1299 initTmpRng = 1;
1300 }
1301 else {
1302 WOLFSSL_MSG("Bad RNG Init, trying global");
1303 rng = wolfssl_get_global_rng();
1304 }
1305
1306 if (rng) {
1307 if (wc_MakeDsaParameters(rng, bits,
1308 (DsaKey*)dsa->internal) != MP_OKAY)
1309 WOLFSSL_MSG("wc_MakeDsaParameters failed");
1310 else if (SetDsaExternal(dsa) != 1)
1311 WOLFSSL_MSG("SetDsaExternal failed");
1312 else
1313 ret = 1;
1314 }
1315
1316 if (initTmpRng)
1317 wc_FreeRng(tmpRng);
1318
1319 WC_FREE_VAR_EX(tmpRng, NULL, DYNAMIC_TYPE_RNG);
1320 }
1321#else /* WOLFSSL_KEY_GEN */
1322 WOLFSSL_MSG("No Key Gen built in");
1323#endif
1324
1325 return ret;
1326}
1327
1328void wolfSSL_DSA_get0_pqg(const WOLFSSL_DSA *d, const WOLFSSL_BIGNUM **p,
1329 const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
1330{
1331 WOLFSSL_ENTER("wolfSSL_DSA_get0_pqg");
1332 if (d != NULL) {
1333 if (p != NULL)
1334 *p = d->p;
1335 if (q != NULL)
1336 *q = d->q;
1337 if (g != NULL)
1338 *g = d->g;
1339 }
1340}
1341
1342int wolfSSL_DSA_set0_pqg(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *p,
1343 WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g)
1344{
1345 WOLFSSL_ENTER("wolfSSL_DSA_set0_pqg");
1346 if (d == NULL || p == NULL || q == NULL || g == NULL) {
1347 WOLFSSL_MSG("Bad parameter");
1348 return 0;
1349 }
1350 wolfSSL_BN_free(d->p);
1351 wolfSSL_BN_free(d->q);
1352 wolfSSL_BN_free(d->g);
1353 d->p = p;
1354 d->q = q;
1355 d->g = g;
1356 return 1;
1357}
1358
1359void wolfSSL_DSA_get0_key(const WOLFSSL_DSA *d,
1360 const WOLFSSL_BIGNUM **pub_key, const WOLFSSL_BIGNUM **priv_key)
1361{
1362 WOLFSSL_ENTER("wolfSSL_DSA_get0_key");
1363 if (d != NULL) {
1364 if (pub_key != NULL)
1365 *pub_key = d->pub_key;
1366 if (priv_key != NULL)
1367 *priv_key = d->priv_key;
1368 }
1369}
1370
1371int wolfSSL_DSA_set0_key(WOLFSSL_DSA *d, WOLFSSL_BIGNUM *pub_key,
1372 WOLFSSL_BIGNUM *priv_key)
1373{
1374 WOLFSSL_ENTER("wolfSSL_DSA_set0_key");
1375
1376 /* The private key may be NULL */
1377 if (d->pub_key == NULL && pub_key == NULL) {
1378 WOLFSSL_MSG("Bad parameter");
1379 return 0;
1380 }
1381
1382 if (pub_key != NULL) {
1383 wolfSSL_BN_free(d->pub_key);
1384 d->pub_key = pub_key;
1385 }
1386 if (priv_key != NULL) {
1387 wolfSSL_BN_free(d->priv_key);
1388 d->priv_key = priv_key;
1389 }
1390
1391 return 1;
1392}
1393
1394WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void)
1395{
1396 WOLFSSL_DSA_SIG* sig;
1397 WOLFSSL_ENTER("wolfSSL_DSA_SIG_new");
1398 sig = (WOLFSSL_DSA_SIG*)XMALLOC(sizeof(WOLFSSL_DSA_SIG), NULL,
1399 DYNAMIC_TYPE_OPENSSL);
1400 if (sig)
1401 XMEMSET(sig, 0, sizeof(WOLFSSL_DSA_SIG));
1402 return sig;
1403}
1404
1405void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig)
1406{
1407 WOLFSSL_ENTER("wolfSSL_DSA_SIG_free");
1408 if (sig) {
1409 if (sig->r) {
1410 wolfSSL_BN_free(sig->r);
1411 }
1412 if (sig->s) {
1413 wolfSSL_BN_free(sig->s);
1414 }
1415 XFREE(sig, NULL, DYNAMIC_TYPE_OPENSSL);
1416 }
1417}
1418
1419void wolfSSL_DSA_SIG_get0(const WOLFSSL_DSA_SIG *sig,
1420 const WOLFSSL_BIGNUM **r, const WOLFSSL_BIGNUM **s)
1421{
1422 WOLFSSL_ENTER("wolfSSL_DSA_SIG_get0");
1423 if (sig != NULL) {
1424 *r = sig->r;
1425 *s = sig->s;
1426 }
1427}
1428
1429int wolfSSL_DSA_SIG_set0(WOLFSSL_DSA_SIG *sig, WOLFSSL_BIGNUM *r,
1430 WOLFSSL_BIGNUM *s)
1431{
1432 WOLFSSL_ENTER("wolfSSL_DSA_SIG_set0");
1433 if (r == NULL || s == NULL) {
1434 WOLFSSL_MSG("Bad parameter");
1435 return 0;
1436 }
1437
1438 wolfSSL_BN_clear_free(sig->r);
1439 wolfSSL_BN_clear_free(sig->s);
1440 sig->r = r;
1441 sig->s = s;
1442
1443 return 1;
1444}
1445
1446#ifndef HAVE_SELFTEST
1447/**
1448 *
1449 * @param sig The input signature to encode
1450 * @param out The output buffer. If *out is NULL then a new buffer is
1451 * allocated. Otherwise the output is written to the buffer.
1452 * @return length on success and -1 on error
1453 */
1454int wolfSSL_i2d_DSA_SIG(const WOLFSSL_DSA_SIG *sig, byte **out)
1455{
1456 /* Space for sequence + two asn ints */
1457 byte buf[MAX_SEQ_SZ + 2*(ASN_TAG_SZ + MAX_LENGTH_SZ + DSA_MAX_HALF_SIZE)];
1458 word32 bufLen = sizeof(buf);
1459
1460 WOLFSSL_ENTER("wolfSSL_i2d_DSA_SIG");
1461
1462 if (sig == NULL || sig->r == NULL || sig->s == NULL ||
1463 out == NULL) {
1464 WOLFSSL_MSG("Bad function arguments");
1465 return WOLFSSL_FATAL_ERROR;
1466 }
1467
1468 if (StoreECC_DSA_Sig(buf, &bufLen,
1469 (mp_int*)sig->r->internal, (mp_int*)sig->s->internal) != 0) {
1470 WOLFSSL_MSG("StoreECC_DSA_Sig error");
1471 return WOLFSSL_FATAL_ERROR;
1472 }
1473
1474 if (*out == NULL) {
1475 byte* tmp = (byte*)XMALLOC(bufLen, NULL, DYNAMIC_TYPE_ASN1);
1476 if (tmp == NULL) {
1477 WOLFSSL_MSG("malloc error");
1478 return WOLFSSL_FATAL_ERROR;
1479 }
1480 *out = tmp;
1481 }
1482
1483 XMEMCPY(*out, buf, bufLen);
1484
1485 return (int)bufLen;
1486}
1487
1488/**
1489 * Same as wolfSSL_DSA_SIG_new but also initializes the internal bignums.
1490 * @return New WOLFSSL_DSA_SIG with r and s created as well
1491 */
1492static WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new_bn(void)
1493{
1494 WOLFSSL_DSA_SIG* ret;
1495
1496 if ((ret = wolfSSL_DSA_SIG_new()) == NULL) {
1497 WOLFSSL_MSG("wolfSSL_DSA_SIG_new error");
1498 return NULL;
1499 }
1500
1501 if ((ret->r = wolfSSL_BN_new()) == NULL) {
1502 WOLFSSL_MSG("wolfSSL_BN_new error");
1503 wolfSSL_DSA_SIG_free(ret);
1504 return NULL;
1505 }
1506
1507 if ((ret->s = wolfSSL_BN_new()) == NULL) {
1508 WOLFSSL_MSG("wolfSSL_BN_new error");
1509 wolfSSL_DSA_SIG_free(ret);
1510 return NULL;
1511 }
1512
1513 return ret;
1514}
1515
1516/**
1517 * This parses a DER encoded ASN.1 structure. The ASN.1 encoding is:
1518 * ASN1_SEQUENCE
1519 * ASN1_INTEGER (DSA r)
1520 * ASN1_INTEGER (DSA s)
1521 * Alternatively, if the input is DSA_160_SIG_SIZE or DSA_256_SIG_SIZE in
1522 * length then this API interprets this as two unsigned binary numbers.
1523 * @param sig If non-null then free'd first and then newly created
1524 * WOLFSSL_DSA_SIG is assigned
1525 * @param pp Input buffer that is moved forward on success
1526 * @param length Length of input buffer
1527 * @return Newly created WOLFSSL_DSA_SIG on success or NULL on failure
1528 */
1529WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig,
1530 const unsigned char **pp, long length)
1531{
1532 WOLFSSL_DSA_SIG* ret;
1533 mp_int* r;
1534 mp_int* s;
1535
1536 WOLFSSL_ENTER("wolfSSL_d2i_DSA_SIG");
1537
1538 if (pp == NULL || *pp == NULL || length < 0) {
1539 WOLFSSL_MSG("Bad function arguments");
1540 return NULL;
1541 }
1542
1543 if ((ret = wolfSSL_DSA_SIG_new_bn()) == NULL) {
1544 WOLFSSL_MSG("wolfSSL_DSA_SIG_new_bn error");
1545 return NULL;
1546 }
1547
1548 r = (mp_int*)ret->r->internal;
1549 s = (mp_int*)ret->s->internal;
1550
1551 if (DecodeECC_DSA_Sig(*pp, (word32)length, r, s) != 0) {
1552 if (length == DSA_160_SIG_SIZE || length == DSA_256_SIG_SIZE) {
1553 /* Two raw numbers of length/2 size each */
1554 if (mp_read_unsigned_bin(r, *pp, (word32)length/2) != 0) {
1555 WOLFSSL_MSG("r mp_read_unsigned_bin error");
1556 wolfSSL_DSA_SIG_free(ret);
1557 return NULL;
1558 }
1559
1560 if (mp_read_unsigned_bin(s, *pp + (length/2), (word32)length/2) !=
1561 0) {
1562 WOLFSSL_MSG("s mp_read_unsigned_bin error");
1563 wolfSSL_DSA_SIG_free(ret);
1564 return NULL;
1565 }
1566
1567 *pp += length;
1568 }
1569 else {
1570 WOLFSSL_MSG("DecodeECC_DSA_Sig error");
1571 wolfSSL_DSA_SIG_free(ret);
1572 return NULL;
1573 }
1574 }
1575 else {
1576 /* DecodeECC_DSA_Sig success move pointer forward */
1577#ifndef NO_STRICT_ECDSA_LEN
1578 *pp += length;
1579#else
1580 {
1581 /* We need to figure out how much to move by ourselves */
1582 word32 idx = 0;
1583 int len = 0;
1584 if (GetSequence(*pp, &idx, &len, (word32)length) < 0) {
1585 WOLFSSL_MSG("GetSequence error");
1586 wolfSSL_DSA_SIG_free(ret);
1587 return NULL;
1588 }
1589 *pp += len;
1590 }
1591#endif
1592 }
1593
1594 if (sig != NULL) {
1595 if (*sig != NULL)
1596 wolfSSL_DSA_SIG_free(*sig);
1597 *sig = ret;
1598 }
1599
1600 return ret;
1601}
1602
1603#endif /* !HAVE_SELFTEST */
1604
1605static int dsa_do_sign(const unsigned char* d, int dLen, unsigned char* sigRet,
1606 WOLFSSL_DSA* dsa)
1607{
1608 int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
1609 int initTmpRng = 0;
1610 WC_RNG* rng = NULL;
1611 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
1612
1613 if (d == NULL || sigRet == NULL || dsa == NULL) {
1614 WOLFSSL_MSG("Bad function arguments");
1615 return WOLFSSL_FATAL_ERROR;
1616 }
1617
1618 if (dsa->inSet == 0) {
1619 WOLFSSL_MSG("No DSA internal set, do it");
1620 if (SetDsaInternal(dsa) != 1) {
1621 WOLFSSL_MSG("SetDsaInternal failed");
1622 return WOLFSSL_FATAL_ERROR;
1623 }
1624 }
1625
1626 WC_ALLOC_VAR_EX(tmpRng, WC_RNG, 1, NULL, DYNAMIC_TYPE_RNG,
1627 return WOLFSSL_FATAL_ERROR);
1628
1629 if (wc_InitRng(tmpRng) == 0) {
1630 rng = tmpRng;
1631 initTmpRng = 1;
1632 }
1633 else {
1634 WOLFSSL_MSG("Bad RNG Init, trying global");
1635#ifdef WOLFSSL_SMALL_STACK
1636 XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
1637 tmpRng = NULL;
1638#endif
1639 rng = wolfssl_get_global_rng();
1640 if (! rng)
1641 return WOLFSSL_FATAL_ERROR;
1642 }
1643
1644 if (rng) {
1645#ifdef HAVE_SELFTEST
1646 if (dLen != WC_SHA_DIGEST_SIZE ||
1647 wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
1648 WOLFSSL_MSG("wc_DsaSign failed or dLen wrong length");
1649 ret = WOLFSSL_FATAL_ERROR;
1650 }
1651#else
1652 if (wc_DsaSign_ex(d, dLen, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
1653 WOLFSSL_MSG("wc_DsaSign_ex failed");
1654 ret = WOLFSSL_FATAL_ERROR;
1655 }
1656#endif
1657 else
1658 ret = WOLFSSL_SUCCESS;
1659 }
1660
1661 if (initTmpRng)
1662 wc_FreeRng(tmpRng);
1663 WC_FREE_VAR_EX(tmpRng, NULL, DYNAMIC_TYPE_RNG);
1664
1665 return ret;
1666}
1667
1668/* return 1 on success, < 0 otherwise */
1669int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
1670 WOLFSSL_DSA* dsa)
1671{
1672 WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
1673
1674 return dsa_do_sign(d, WC_SHA_DIGEST_SIZE, sigRet, dsa);
1675}
1676
1677#ifndef HAVE_SELFTEST
1678WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
1679 int inLen, WOLFSSL_DSA* dsa)
1680{
1681 byte sigBin[DSA_MAX_SIG_SIZE];
1682 const byte *tmp = sigBin;
1683 int sigLen;
1684
1685 WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex");
1686
1687 if (!digest || !dsa) {
1688 WOLFSSL_MSG("Bad function arguments");
1689 return NULL;
1690 }
1691
1692 if (dsa_do_sign(digest, inLen, sigBin, dsa) != 1) {
1693 WOLFSSL_MSG("wolfSSL_DSA_do_sign error");
1694 return NULL;
1695 }
1696
1697 if (dsa->internal == NULL) {
1698 WOLFSSL_MSG("dsa->internal is null");
1699 return NULL;
1700 }
1701
1702 sigLen = mp_unsigned_bin_size(&((DsaKey*)dsa->internal)->q);
1703 if (sigLen <= 0) {
1704 WOLFSSL_MSG("mp_unsigned_bin_size error");
1705 return NULL;
1706 }
1707
1708 /* 2 * sigLen for the two points r and s */
1709 return wolfSSL_d2i_DSA_SIG(NULL, &tmp, 2 * sigLen);
1710}
1711#endif
1712
1713static int dsa_do_verify(const unsigned char* d, int dLen, unsigned char* sig,
1714 WOLFSSL_DSA* dsa, int *dsacheck)
1715{
1716 int ret;
1717
1718 if (d == NULL || sig == NULL || dsa == NULL) {
1719 WOLFSSL_MSG("Bad function arguments");
1720 return WOLFSSL_FATAL_ERROR;
1721 }
1722 if (dsa->inSet == 0)
1723 {
1724 WOLFSSL_MSG("No DSA internal set, do it");
1725
1726 if (SetDsaInternal(dsa) != 1) {
1727 WOLFSSL_MSG("SetDsaInternal failed");
1728 return WOLFSSL_FATAL_ERROR;
1729 }
1730 }
1731
1732#ifdef HAVE_SELFTEST
1733 ret = dLen == WC_SHA_DIGEST_SIZE ?
1734 wc_DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck) : BAD_FUNC_ARG;
1735#else
1736 ret = wc_DsaVerify_ex(d, (word32)dLen, sig, (DsaKey*)dsa->internal,
1737 dsacheck);
1738#endif
1739 if (ret != 0) {
1740 WOLFSSL_MSG("DsaVerify failed");
1741 return WOLFSSL_FATAL_ERROR;
1742 }
1743 if (*dsacheck != 1) {
1744 WOLFSSL_MSG("DsaVerify sig failed");
1745 return WOLFSSL_FAILURE;
1746 }
1747
1748 return WOLFSSL_SUCCESS;
1749}
1750
1751int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
1752 WOLFSSL_DSA* dsa, int *dsacheck)
1753{
1754 WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
1755
1756 return dsa_do_verify(d, WC_SHA_DIGEST_SIZE, sig, dsa, dsacheck);
1757}
1758
1759
1760int wolfSSL_DSA_bits(const WOLFSSL_DSA *d)
1761{
1762 if (!d)
1763 return 0;
1764 if (!d->exSet && SetDsaExternal((WOLFSSL_DSA*)d) != 1)
1765 return 0;
1766 return wolfSSL_BN_num_bits(d->p);
1767}
1768
1769#ifndef HAVE_SELFTEST
1770int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len,
1771 WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa)
1772{
1773 int dsacheck, sz;
1774 byte sigBin[DSA_MAX_SIG_SIZE];
1775 byte* sigBinPtr = sigBin;
1776 DsaKey* key;
1777 int qSz;
1778
1779 WOLFSSL_ENTER("wolfSSL_DSA_do_verify_ex");
1780
1781 if (!digest || !sig || !dsa) {
1782 WOLFSSL_MSG("Bad function arguments");
1783 return 0;
1784 }
1785
1786 if (!sig->r || !sig->s) {
1787 WOLFSSL_MSG("No signature found in DSA_SIG");
1788 return 0;
1789 }
1790
1791 if (dsa->inSet == 0) {
1792 WOLFSSL_MSG("No DSA internal set, do it");
1793 if (SetDsaInternal(dsa) != 1) {
1794 WOLFSSL_MSG("SetDsaInternal failed");
1795 return 0;
1796 }
1797 }
1798
1799 key = (DsaKey*)dsa->internal;
1800
1801 if (key == NULL) {
1802 WOLFSSL_MSG("dsa->internal is null");
1803 return 0;
1804 }
1805
1806 qSz = mp_unsigned_bin_size(&key->q);
1807 if (qSz < 0 || qSz > DSA_MAX_HALF_SIZE) {
1808 WOLFSSL_MSG("mp_unsigned_bin_size error");
1809 return 0;
1810 }
1811
1812 /* read r */
1813 /* front pad with zeros */
1814 if ((sz = wolfSSL_BN_num_bytes(sig->r)) < 0 || sz > DSA_MAX_HALF_SIZE)
1815 return 0;
1816 while (sz++ < qSz)
1817 *sigBinPtr++ = 0;
1818 if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == -1)
1819 return 0;
1820
1821 /* Move to s */
1822 sigBinPtr = sigBin + qSz;
1823
1824 /* read s */
1825 /* front pad with zeros */
1826 if ((sz = wolfSSL_BN_num_bytes(sig->s)) < 0 || sz > DSA_MAX_HALF_SIZE)
1827 return 0;
1828 while (sz++ < qSz)
1829 *sigBinPtr++ = 0;
1830 if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == -1)
1831 return 0;
1832
1833 if ((dsa_do_verify(digest, digest_len, sigBin, dsa, &dsacheck)
1834 != 1) || dsacheck != 1) {
1835 return 0;
1836 }
1837
1838 return 1;
1839}
1840#endif
1841
1842int wolfSSL_i2d_DSAparams(const WOLFSSL_DSA* dsa,
1843 unsigned char** out)
1844{
1845 int ret = 0;
1846 word32 derLen = 0;
1847 int preAllocated = 1;
1848 DsaKey* key = NULL;
1849
1850 WOLFSSL_ENTER("wolfSSL_i2d_DSAparams");
1851
1852 if (dsa == NULL || dsa->internal == NULL || out == NULL) {
1853 ret = BAD_FUNC_ARG;
1854 }
1855
1856 if (ret == 0) {
1857 key = (DsaKey*)dsa->internal;
1858 ret = wc_DsaKeyToParamsDer_ex(key, NULL, &derLen);
1859 if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
1860 ret = 0;
1861 }
1862 }
1863 if (ret == 0 && *out == NULL) {
1864 /* If we're allocating out for the caller, we don't increment out just
1865 past the end of the DER buffer. If out is already allocated, we do.
1866 (OpenSSL convention) */
1867 preAllocated = 0;
1868 *out = (unsigned char*)XMALLOC(derLen, key->heap, DYNAMIC_TYPE_OPENSSL);
1869 if (*out == NULL) {
1870 ret = MEMORY_E;
1871 }
1872 }
1873 if (ret == 0) {
1874 ret = wc_DsaKeyToParamsDer_ex(key, *out, &derLen);
1875 }
1876 if (ret >= 0 && preAllocated == 1) {
1877 *out += derLen;
1878 }
1879
1880 if (ret < 0 && preAllocated == 0) {
1881 XFREE(*out, key ? key->heap : NULL, DYNAMIC_TYPE_OPENSSL);
1882 }
1883
1884 WOLFSSL_LEAVE("wolfSSL_i2d_DSAparams", ret);
1885
1886 return ret;
1887}
1888
1889WOLFSSL_DSA* wolfSSL_d2i_DSAparams(WOLFSSL_DSA** dsa, const unsigned char** der,
1890 long derLen)
1891{
1892 WOLFSSL_DSA* ret = NULL;
1893 int err = 0;
1894 word32 idx = 0;
1895 int asnLen;
1896 DsaKey* internalKey = NULL;
1897
1898 WOLFSSL_ENTER("wolfSSL_d2i_DSAparams");
1899
1900 if (der == NULL || *der == NULL || derLen <= 0) {
1901 err = 1;
1902 }
1903 if (err == 0) {
1904 ret = wolfSSL_DSA_new();
1905 err = ret == NULL;
1906 }
1907 if (err == 0) {
1908 err = GetSequence(*der, &idx, &asnLen, (word32)derLen) <= 0;
1909 }
1910 if (err == 0) {
1911 internalKey = (DsaKey*)ret->internal;
1912 err = GetInt(&internalKey->p, *der, &idx, (word32)derLen) != 0;
1913 }
1914 if (err == 0) {
1915 err = GetInt(&internalKey->q, *der, &idx, (word32)derLen) != 0;
1916 }
1917 if (err == 0) {
1918 err = GetInt(&internalKey->g, *der, &idx, (word32)derLen) != 0;
1919 }
1920 if (err == 0) {
1921 err = wolfssl_bn_set_value(&ret->p, &internalKey->p)
1922 != 1;
1923 }
1924 if (err == 0) {
1925 err = wolfssl_bn_set_value(&ret->q, &internalKey->q)
1926 != 1;
1927 }
1928 if (err == 0) {
1929 err = wolfssl_bn_set_value(&ret->g, &internalKey->g)
1930 != 1;
1931 }
1932 if (err == 0 && dsa != NULL) {
1933 *dsa = ret;
1934 }
1935
1936 if (err != 0 && ret != NULL) {
1937 wolfSSL_DSA_free(ret);
1938 ret = NULL;
1939 }
1940
1941 return ret;
1942}
1943
1944#if defined(WOLFSSL_KEY_GEN)
1945#ifndef NO_BIO
1946
1947/* Takes a DSA Privatekey and writes it out to a WOLFSSL_BIO
1948 * Returns 1 or 0
1949 */
1950int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa,
1951 const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz,
1952 wc_pem_password_cb* cb, void* arg)
1953{
1954 int ret = 1;
1955 byte *pem = NULL;
1956 int pLen = 0;
1957
1958 WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSAPrivateKey");
1959
1960 (void)cb;
1961 (void)arg;
1962
1963 /* Validate parameters. */
1964 if ((bio == NULL) || (dsa == NULL)) {
1965 WOLFSSL_MSG("Bad Function Arguments");
1966 ret = 0;
1967 }
1968
1969 if (ret == 1) {
1970 ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, cipher, passwd, passwdSz,
1971 &pem, &pLen);
1972 }
1973
1974 /* Write PEM to BIO. */
1975 if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, pLen) != pLen)) {
1976 WOLFSSL_ERROR_MSG("DSA private key BIO write failed");
1977 ret = 0;
1978 }
1979
1980 XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
1981 return ret;
1982}
1983
1984#ifndef HAVE_SELFTEST
1985/* Encode the DSA public key as DER.
1986 *
1987 * @param [in] key DSA key to encode.
1988 * @param [out] der Pointer through which buffer is returned.
1989 * @param [in] heap Heap hint.
1990 * @return Size of encoding on success.
1991 * @return 0 on error.
1992 */
1993static int wolfssl_dsa_key_to_pubkey_der(WOLFSSL_DSA* key, unsigned char** der,
1994 void* heap)
1995{
1996 int sz;
1997 unsigned char* buf = NULL;
1998
1999 /* Use maximum encoded size to allocate. */
2000 sz = MAX_DSA_PUBKEY_SZ;
2001 /* Allocate memory to hold encoding. */
2002 buf = (byte*)XMALLOC((size_t)sz, heap, DYNAMIC_TYPE_TMP_BUFFER);
2003 if (buf == NULL) {
2004 WOLFSSL_MSG("malloc failed");
2005 sz = 0;
2006 }
2007 if (sz > 0) {
2008 /* Encode public key to DER using wolfSSL. */
2009 sz = wc_DsaKeyToPublicDer((DsaKey*)key->internal, buf, (word32)sz);
2010 if (sz < 0) {
2011 WOLFSSL_MSG("wc_DsaKeyToPublicDer failed");
2012 sz = 0;
2013 }
2014 }
2015
2016 /* Return buffer on success. */
2017 if (sz > 0) {
2018 *der = buf;
2019 }
2020 else {
2021 /* Dispose of any dynamically allocated data not returned. */
2022 XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
2023 }
2024
2025 return sz;
2026}
2027
2028/* Takes a DSA public key and writes it out to a WOLFSSL_BIO
2029 * Returns 1 or 0
2030 */
2031int wolfSSL_PEM_write_bio_DSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa)
2032{
2033 int ret = 1;
2034 unsigned char* derBuf = NULL;
2035 int derSz = 0;
2036
2037 WOLFSSL_ENTER("wolfSSL_PEM_write_bio_DSA_PUBKEY");
2038
2039 /* Validate parameters. */
2040 if ((bio == NULL) || (dsa == NULL)) {
2041 WOLFSSL_MSG("Bad Function Arguments");
2042 return 0;
2043 }
2044
2045 /* Encode public key in EC key as DER. */
2046 derSz = wolfssl_dsa_key_to_pubkey_der(dsa, &derBuf, bio->heap);
2047 if (derSz == 0) {
2048 ret = 0;
2049 }
2050
2051 /* Write out to BIO the PEM encoding of the DSA public key. */
2052 if ((ret == 1) && (der_write_to_bio_as_pem(derBuf, derSz, bio,
2053 PUBLICKEY_TYPE) != 1)) {
2054 ret = 0;
2055 }
2056
2057 /* Dispose of any dynamically allocated data. */
2058 XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
2059
2060 return ret;
2061}
2062#endif /* HAVE_SELFTEST */
2063#endif /* !NO_BIO */
2064
2065/* return code compliant with OpenSSL :
2066 * 1 if success, 0 if error
2067 */
2068int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa,
2069 const WOLFSSL_EVP_CIPHER* cipher,
2070 unsigned char* passwd, int passwdSz,
2071 unsigned char **pem, int *pLen)
2072{
2073#if (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)) && \
2074 !defined(NO_MD5)
2075 byte *derBuf, *tmp, *cipherInfo = NULL;
2076 int der_max_len = 0, derSz = 0;
2077 const int type = DSA_PRIVATEKEY_TYPE;
2078 const char* header = NULL;
2079 const char* footer = NULL;
2080
2081 WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey");
2082
2083 if (pem == NULL || pLen == NULL || dsa == NULL || dsa->internal == NULL) {
2084 WOLFSSL_MSG("Bad function arguments");
2085 return 0;
2086 }
2087
2088 if (wc_PemGetHeaderFooter(type, &header, &footer) != 0)
2089 return 0;
2090
2091 if (dsa->inSet == 0) {
2092 WOLFSSL_MSG("No DSA internal set, do it");
2093
2094 if (SetDsaInternal(dsa) != 1) {
2095 WOLFSSL_MSG("SetDsaInternal failed");
2096 return 0;
2097 }
2098 }
2099
2100 der_max_len = MAX_DSA_PRIVKEY_SZ;
2101
2102 derBuf = (byte*)XMALLOC((size_t)der_max_len, NULL, DYNAMIC_TYPE_DER);
2103 if (derBuf == NULL) {
2104 WOLFSSL_MSG("malloc failed");
2105 return 0;
2106 }
2107
2108 /* Key to DER */
2109 derSz = wc_DsaKeyToDer((DsaKey*)dsa->internal, derBuf, (word32)der_max_len);
2110 if (derSz < 0) {
2111 WOLFSSL_MSG("wc_DsaKeyToDer failed");
2112 ForceZero(derBuf, (word32)der_max_len);
2113 XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2114 return 0;
2115 }
2116
2117 /* encrypt DER buffer if required */
2118 if (passwd != NULL && passwdSz > 0 && cipher != NULL) {
2119 int ret;
2120
2121 ret = EncryptDerKey(derBuf, &derSz, cipher, passwd, passwdSz,
2122 &cipherInfo, der_max_len, WC_MD5);
2123 if (ret != 1) {
2124 WOLFSSL_MSG("EncryptDerKey failed");
2125 ForceZero(derBuf, (word32)der_max_len);
2126 XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2127 return ret;
2128 }
2129 /* tmp buffer with a max size */
2130 *pLen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
2131 (int)XSTRLEN(footer) + 1 + HEADER_ENCRYPTED_KEY_SIZE;
2132 }
2133 else { /* tmp buffer with a max size */
2134 *pLen = (derSz * 2) + (int)XSTRLEN(header) + 1 +
2135 (int)XSTRLEN(footer) + 1;
2136 }
2137
2138 tmp = (byte*)XMALLOC((size_t)*pLen, NULL, DYNAMIC_TYPE_PEM);
2139 if (tmp == NULL) {
2140 WOLFSSL_MSG("malloc failed");
2141 ForceZero(derBuf, (word32)der_max_len);
2142 XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2143 XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
2144 return 0;
2145 }
2146
2147 /* DER to PEM */
2148 *pLen = wc_DerToPemEx(derBuf, (word32)derSz, tmp, (word32)*pLen, cipherInfo,
2149 type);
2150 if (*pLen <= 0) {
2151 WOLFSSL_MSG("wc_DerToPemEx failed");
2152 ForceZero(derBuf, (word32)der_max_len);
2153 XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2154 XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
2155 XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
2156 return 0;
2157 }
2158 ForceZero(derBuf, (word32)der_max_len);
2159 XFREE(derBuf, NULL, DYNAMIC_TYPE_DER);
2160 XFREE(cipherInfo, NULL, DYNAMIC_TYPE_STRING);
2161
2162 *pem = (byte*)XMALLOC((size_t)((*pLen)+1), NULL, DYNAMIC_TYPE_KEY);
2163 if (*pem == NULL) {
2164 WOLFSSL_MSG("malloc failed");
2165 XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
2166 return 0;
2167 }
2168 XMEMSET(*pem, 0, (size_t)((*pLen)+1));
2169
2170 if (XMEMCPY(*pem, tmp, (size_t)*pLen) == NULL) {
2171 WOLFSSL_MSG("XMEMCPY failed");
2172 XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
2173 XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
2174 return 0;
2175 }
2176 XFREE(tmp, NULL, DYNAMIC_TYPE_PEM);
2177
2178 return 1;
2179#else
2180 (void)dsa;
2181 (void)cipher;
2182 (void)passwd;
2183 (void)passwdSz;
2184 (void)pem;
2185 (void)pLen;
2186 return 0;
2187#endif /* (WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM) && !NO_MD5 */
2188}
2189
2190#ifndef NO_FILESYSTEM
2191/* return code compliant with OpenSSL :
2192 * 1 if success, 0 if error
2193 */
2194int wolfSSL_PEM_write_DSAPrivateKey(XFILE fp, WOLFSSL_DSA *dsa,
2195 const WOLFSSL_EVP_CIPHER *enc,
2196 unsigned char *kstr, int klen,
2197 wc_pem_password_cb *cb, void *u)
2198{
2199 byte *pem;
2200 int pLen, ret;
2201
2202 (void)cb;
2203 (void)u;
2204
2205 WOLFSSL_MSG("wolfSSL_PEM_write_DSAPrivateKey");
2206
2207 if (fp == XBADFILE || dsa == NULL || dsa->internal == NULL) {
2208 WOLFSSL_MSG("Bad function arguments");
2209 return 0;
2210 }
2211
2212 ret = wolfSSL_PEM_write_mem_DSAPrivateKey(dsa, enc, kstr, klen, &pem,
2213 &pLen);
2214 if (ret != 1) {
2215 WOLFSSL_MSG("wolfSSL_PEM_write_mem_DSAPrivateKey failed");
2216 return 0;
2217 }
2218
2219 ret = (int)XFWRITE(pem, (size_t)pLen, 1, fp);
2220 if (ret != 1) {
2221 WOLFSSL_MSG("DSA private key file write failed");
2222 return 0;
2223 }
2224
2225 XFREE(pem, NULL, DYNAMIC_TYPE_KEY);
2226 return 1;
2227}
2228
2229#endif /* NO_FILESYSTEM */
2230#endif /* defined(WOLFSSL_KEY_GEN) */
2231
2232#ifndef NO_FILESYSTEM
2233/* return code compliant with OpenSSL :
2234 * 1 if success, 0 if error
2235 */
2236#ifndef NO_WOLFSSL_STUB
2237int wolfSSL_PEM_write_DSA_PUBKEY(XFILE fp, WOLFSSL_DSA *x)
2238{
2239 (void)fp;
2240 (void)x;
2241 WOLFSSL_STUB("PEM_write_DSA_PUBKEY");
2242 WOLFSSL_MSG("wolfSSL_PEM_write_DSA_PUBKEY not implemented");
2243
2244 return 0;
2245}
2246#endif
2247#endif /* NO_FILESYSTEM */
2248
2249#ifndef NO_BIO
2250
2251#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && (!defined(NO_CERTS) && \
2252 !defined(NO_FILESYSTEM) && defined(WOLFSSL_KEY_GEN))
2253/* Uses the same format of input as wolfSSL_PEM_read_bio_PrivateKey but expects
2254 * the results to be an DSA key.
2255 *
2256 * bio structure to read DSA private key from
2257 * dsa if not null is then set to the result
2258 * cb password callback for reading PEM
2259 * pass password string
2260 *
2261 * returns a pointer to a new WOLFSSL_DSA structure on success and NULL on fail
2262 */
2263WOLFSSL_DSA* wolfSSL_PEM_read_bio_DSAPrivateKey(WOLFSSL_BIO* bio,
2264 WOLFSSL_DSA** dsa,
2265 wc_pem_password_cb* cb,
2266 void* pass)
2267{
2268 WOLFSSL_EVP_PKEY* pkey = NULL;
2269 WOLFSSL_DSA* local;
2270 WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAPrivateKey");
2271
2272
2273 pkey = wolfSSL_PEM_read_bio_PrivateKey(bio, NULL, cb, pass);
2274 if (pkey == NULL) {
2275 WOLFSSL_MSG("Error in PEM_read_bio_PrivateKey");
2276 return NULL;
2277 }
2278 /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
2279 * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
2280 * to avoid having it free'd */
2281 pkey->ownDsa = 0;
2282 local = pkey->dsa;
2283 if (dsa != NULL) {
2284 *dsa = local;
2285 }
2286 wolfSSL_EVP_PKEY_free(pkey);
2287 return local;
2288}
2289
2290/* Reads an DSA public key from a WOLFSSL_BIO into a WOLFSSL_DSA.
2291 * Returns 1 or 0
2292 */
2293WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_DSA** dsa,
2294 wc_pem_password_cb* cb, void* pass)
2295{
2296 WOLFSSL_EVP_PKEY* pkey;
2297 WOLFSSL_DSA* local;
2298 WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSA_PUBKEY");
2299
2300 pkey = wolfSSL_PEM_read_bio_PUBKEY(bio, NULL, cb, pass);
2301 if (pkey == NULL) {
2302 WOLFSSL_MSG("wolfSSL_PEM_read_bio_PUBKEY failed");
2303 return NULL;
2304 }
2305
2306 /* Since the WOLFSSL_DSA structure is being taken from WOLFSSL_EVP_PKEY the
2307 * flag indicating that the WOLFSSL_DSA structure is owned should be FALSE
2308 * to avoid having it free'd */
2309 pkey->ownDsa = 0;
2310 local = pkey->dsa;
2311 if (dsa != NULL) {
2312 *dsa = local;
2313 }
2314
2315 wolfSSL_EVP_PKEY_free(pkey);
2316 return local;
2317}
2318#endif /* (OPENSSL_EXTRA || OPENSSL_ALL) && (!NO_CERTS &&
2319 !NO_FILESYSTEM && WOLFSSL_KEY_GEN) */
2320
2321#endif /* NO_BIO */
2322
2323#endif /* OPENSSL_EXTRA */
2324
2325#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
2326/* return 1 if success, -1 if error */
2327int wolfSSL_DSA_LoadDer(WOLFSSL_DSA* dsa, const unsigned char* derBuf,
2328 int derSz)
2329{
2330 word32 idx = 0;
2331 int ret;
2332
2333 WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
2334
2335 if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
2336 WOLFSSL_MSG("Bad function arguments");
2337 return WOLFSSL_FATAL_ERROR;
2338 }
2339
2340 ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal,
2341 (word32)derSz);
2342 if (ret < 0) {
2343 WOLFSSL_MSG("DsaPrivateKeyDecode failed");
2344 return WOLFSSL_FATAL_ERROR;
2345 }
2346
2347 if (SetDsaExternal(dsa) != 1) {
2348 WOLFSSL_MSG("SetDsaExternal failed");
2349 return WOLFSSL_FATAL_ERROR;
2350 }
2351
2352 dsa->inSet = 1;
2353
2354 return 1;
2355}
2356
2357/* Loads DSA key from DER buffer. opt = DSA_LOAD_PRIVATE or DSA_LOAD_PUBLIC.
2358 returns 1 on success, or 0 on failure. */
2359int wolfSSL_DSA_LoadDer_ex(WOLFSSL_DSA* dsa, const unsigned char* derBuf,
2360 int derSz, int opt)
2361{
2362 word32 idx = 0;
2363 int ret;
2364
2365 WOLFSSL_ENTER("wolfSSL_DSA_LoadDer");
2366
2367 if (dsa == NULL || dsa->internal == NULL || derBuf == NULL || derSz <= 0) {
2368 WOLFSSL_MSG("Bad function arguments");
2369 return WOLFSSL_FATAL_ERROR;
2370 }
2371
2372 if (opt == WOLFSSL_DSA_LOAD_PRIVATE) {
2373 ret = DsaPrivateKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal,
2374 (word32)derSz);
2375 }
2376 else {
2377 ret = DsaPublicKeyDecode(derBuf, &idx, (DsaKey*)dsa->internal,
2378 (word32)derSz);
2379 }
2380
2381 if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PRIVATE) {
2382 WOLFSSL_ERROR_VERBOSE(ret);
2383 WOLFSSL_MSG("DsaPrivateKeyDecode failed");
2384 return WOLFSSL_FATAL_ERROR;
2385 }
2386 else if (ret < 0 && opt == WOLFSSL_DSA_LOAD_PUBLIC) {
2387 WOLFSSL_ERROR_VERBOSE(ret);
2388 WOLFSSL_MSG("DsaPublicKeyDecode failed");
2389 return WOLFSSL_FATAL_ERROR;
2390 }
2391
2392 if (SetDsaExternal(dsa) != 1) {
2393 WOLFSSL_MSG("SetDsaExternal failed");
2394 return WOLFSSL_FATAL_ERROR;
2395 }
2396
2397 dsa->inSet = 1;
2398
2399 return 1;
2400}
2401#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
2402
2403#ifdef OPENSSL_EXTRA
2404#ifndef NO_BIO
2405WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp, WOLFSSL_DSA **x,
2406 wc_pem_password_cb *cb, void *u)
2407{
2408 WOLFSSL_DSA* dsa;
2409 DsaKey* key;
2410 int length;
2411 unsigned char* buf;
2412 word32 bufSz;
2413 int ret;
2414 word32 idx = 0;
2415 DerBuffer* pDer;
2416
2417 WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DSAparams");
2418
2419 ret = wolfSSL_BIO_get_mem_data(bp, &buf);
2420 if (ret <= 0) {
2421 WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
2422 return NULL;
2423 }
2424
2425 bufSz = (word32)ret;
2426
2427 if (cb != NULL || u != NULL) {
2428 /*
2429 * cb is for a call back when encountering encrypted PEM files
2430 * if cb == NULL and u != NULL then u = null terminated password string
2431 */
2432 WOLFSSL_MSG("Not supporting callback or password for encrypted PEM");
2433 }
2434
2435 if (PemToDer(buf, (long)bufSz, DSA_PARAM_TYPE, &pDer, NULL, NULL,
2436 NULL) < 0 ) {
2437 WOLFSSL_MSG("Issue converting from PEM to DER");
2438 return NULL;
2439 }
2440
2441 if (GetSequence(pDer->buffer, &idx, &length, pDer->length) < 0) {
2442 WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_DSAparams", ret);
2443 FreeDer(&pDer);
2444 return NULL;
2445 }
2446
2447 dsa = wolfSSL_DSA_new();
2448 if (dsa == NULL) {
2449 FreeDer(&pDer);
2450 WOLFSSL_MSG("Error creating DSA struct");
2451 return NULL;
2452 }
2453
2454 key = (DsaKey*)dsa->internal;
2455 if (key == NULL) {
2456 FreeDer(&pDer);
2457 wolfSSL_DSA_free(dsa);
2458 WOLFSSL_MSG("Error finding DSA key struct");
2459 return NULL;
2460 }
2461
2462 if (GetInt(&key->p, pDer->buffer, &idx, pDer->length) < 0 ||
2463 GetInt(&key->q, pDer->buffer, &idx, pDer->length) < 0 ||
2464 GetInt(&key->g, pDer->buffer, &idx, pDer->length) < 0 ) {
2465 WOLFSSL_MSG("dsa key error");
2466 FreeDer(&pDer);
2467 wolfSSL_DSA_free(dsa);
2468 return NULL;
2469 }
2470
2471 if (wolfssl_bn_set_value(&dsa->p, &key->p) != 1) {
2472 WOLFSSL_MSG("dsa p key error");
2473 FreeDer(&pDer);
2474 wolfSSL_DSA_free(dsa);
2475 return NULL;
2476 }
2477
2478 if (wolfssl_bn_set_value(&dsa->q, &key->q) != 1) {
2479 WOLFSSL_MSG("dsa q key error");
2480 FreeDer(&pDer);
2481 wolfSSL_DSA_free(dsa);
2482 return NULL;
2483 }
2484
2485 if (wolfssl_bn_set_value(&dsa->g, &key->g) != 1) {
2486 WOLFSSL_MSG("dsa g key error");
2487 FreeDer(&pDer);
2488 wolfSSL_DSA_free(dsa);
2489 return NULL;
2490 }
2491
2492 if (x != NULL) {
2493 *x = dsa;
2494 }
2495
2496 FreeDer(&pDer);
2497 return dsa;
2498}
2499#endif /* !NO_BIO */
2500
2501#if !defined(NO_DH)
2502WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *dsa)
2503{
2504 WOLFSSL_DH* dh;
2505 DhKey* key;
2506
2507 WOLFSSL_ENTER("wolfSSL_DSA_dup_DH");
2508
2509 if (dsa == NULL) {
2510 return NULL;
2511 }
2512
2513 dh = wolfSSL_DH_new();
2514 if (dh == NULL) {
2515 return NULL;
2516 }
2517 key = (DhKey*)dh->internal;
2518
2519 if (dsa->p != NULL &&
2520 wolfssl_bn_get_value(((WOLFSSL_DSA*)dsa)->p, &key->p)
2521 != 1) {
2522 WOLFSSL_MSG("rsa p key error");
2523 wolfSSL_DH_free(dh);
2524 return NULL;
2525 }
2526 if (dsa->g != NULL &&
2527 wolfssl_bn_get_value(((WOLFSSL_DSA*)dsa)->g, &key->g)
2528 != 1) {
2529 WOLFSSL_MSG("rsa g key error");
2530 wolfSSL_DH_free(dh);
2531 return NULL;
2532 }
2533
2534 if (wolfssl_bn_set_value(&dh->p, &key->p) != 1) {
2535 WOLFSSL_MSG("dsa p key error");
2536 wolfSSL_DH_free(dh);
2537 return NULL;
2538 }
2539 if (wolfssl_bn_set_value(&dh->g, &key->g) != 1) {
2540 WOLFSSL_MSG("dsa g key error");
2541 wolfSSL_DH_free(dh);
2542 return NULL;
2543 }
2544
2545 return dh;
2546}
2547#endif /* !NO_DH */
2548
2549#endif /* OPENSSL_EXTRA */
2550
2551#endif /* !NO_DSA */
2552
2553/*******************************************************************************
2554 * END OF DSA API
2555 ******************************************************************************/
2556
2557
2558/*******************************************************************************
2559 * START OF DH API
2560 ******************************************************************************/
2561
2562#ifndef NO_DH
2563
2564#ifdef OPENSSL_EXTRA
2565
2566/*
2567 * DH constructor/deconstructor APIs
2568 */
2569
2570/* Allocate and initialize a new DH key.
2571 *
2572 * @return DH key on success.
2573 * @return NULL on failure.
2574 */
2575WOLFSSL_DH* wolfSSL_DH_new(void)
2576{
2577 int err = 0;
2578 WOLFSSL_DH* dh = NULL;
2579 DhKey* key = NULL;
2580
2581 WOLFSSL_ENTER("wolfSSL_DH_new");
2582
2583 /* Allocate OpenSSL DH key. */
2584 dh = (WOLFSSL_DH*)XMALLOC(sizeof(WOLFSSL_DH), NULL, DYNAMIC_TYPE_DH);
2585 if (dh == NULL) {
2586 WOLFSSL_ERROR_MSG("wolfSSL_DH_new malloc WOLFSSL_DH failure");
2587 err = 1;
2588 }
2589
2590 if (!err) {
2591 /* Clear key data. */
2592 XMEMSET(dh, 0, sizeof(WOLFSSL_DH));
2593 /* Initialize reference counting. */
2594 wolfSSL_RefInit(&dh->ref, &err);
2595#ifdef WOLFSSL_REFCNT_ERROR_RETURN
2596 }
2597 if (!err) {
2598#endif
2599 /* Allocate wolfSSL DH key. */
2600 key = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
2601 if (key == NULL) {
2602 WOLFSSL_ERROR_MSG("wolfSSL_DH_new malloc DhKey failure");
2603 err = 1;
2604 }
2605 }
2606 if (!err) {
2607 /* Set and initialize wolfSSL DH key. */
2608 dh->internal = key;
2609 if (wc_InitDhKey(key) != 0) {
2610 WOLFSSL_ERROR_MSG("wolfSSL_DH_new InitDhKey failure");
2611 err = 1;
2612 }
2613 }
2614
2615 if (err && (dh != NULL)) {
2616 /* Dispose of the allocated memory. */
2617 XFREE(key, NULL, DYNAMIC_TYPE_DH);
2618 wolfSSL_RefFree(&dh->ref);
2619 XFREE(dh, NULL, DYNAMIC_TYPE_DH);
2620 dh = NULL;
2621 }
2622 return dh;
2623}
2624
2625#if defined(HAVE_PUBLIC_FFDHE) || (defined(HAVE_FIPS) && FIPS_VERSION_EQ(2,0))
2626/* Set the DH parameters based on the NID.
2627 *
2628 * @param [in, out] dh DH key to set.
2629 * @param [in] nid Numeric ID of predefined DH parameters.
2630 * @return 0 on success.
2631 * @return 1 on failure.
2632 */
2633static int wolfssl_dh_set_nid(WOLFSSL_DH* dh, int nid)
2634{
2635 int err = 0;
2636 const DhParams* params = NULL;
2637
2638 /* HAVE_PUBLIC_FFDHE not required to expose wc_Dh_ffdhe* functions in
2639 * FIPS v2 module */
2640 switch (nid) {
2641#ifdef HAVE_FFDHE_2048
2642 case WC_NID_ffdhe2048:
2643 params = wc_Dh_ffdhe2048_Get();
2644 break;
2645#endif /* HAVE_FFDHE_2048 */
2646#ifdef HAVE_FFDHE_3072
2647 case WC_NID_ffdhe3072:
2648 params = wc_Dh_ffdhe3072_Get();
2649 break;
2650#endif /* HAVE_FFDHE_3072 */
2651#ifdef HAVE_FFDHE_4096
2652 case WC_NID_ffdhe4096:
2653 params = wc_Dh_ffdhe4096_Get();
2654 break;
2655#endif /* HAVE_FFDHE_4096 */
2656 default:
2657 break;
2658 }
2659 if (params == NULL) {
2660 WOLFSSL_ERROR_MSG("Unable to find DH params for nid.");
2661 err = 1;
2662 }
2663
2664 if (!err) {
2665 /* Set prime from data retrieved. */
2666 dh->p = wolfSSL_BN_bin2bn(params->p, (int)params->p_len, NULL);
2667 if (dh->p == NULL) {
2668 WOLFSSL_ERROR_MSG("Error converting p hex to WOLFSSL_BIGNUM.");
2669 err = 1;
2670 }
2671 }
2672 if (!err) {
2673 /* Set generator from data retrieved. */
2674 dh->g = wolfSSL_BN_bin2bn(params->g, (int)params->g_len, NULL);
2675 if (dh->g == NULL) {
2676 WOLFSSL_ERROR_MSG("Error converting g hex to WOLFSSL_BIGNUM.");
2677 err = 1;
2678 }
2679 }
2680#ifdef HAVE_FFDHE_Q
2681 if (!err) {
2682 /* Set order from data retrieved. */
2683 dh->q = wolfSSL_BN_bin2bn(params->q, params->q_len, NULL);
2684 if (dh->q == NULL) {
2685 WOLFSSL_ERROR_MSG("Error converting q hex to WOLFSSL_BIGNUM.");
2686 err = 1;
2687 }
2688 }
2689#endif
2690
2691 /* Synchronize the external into internal DH key's parameters. */
2692 if ((!err) && (SetDhInternal(dh) != 1)) {
2693 WOLFSSL_ERROR_MSG("Failed to set internal DH params.");
2694 err = 1;
2695 }
2696 if (!err) {
2697 /* External DH key parameters were set. */
2698 dh->exSet = 1;
2699 }
2700
2701 if (err == 1) {
2702 /* Dispose of any external parameters. */
2703 #ifdef HAVE_FFDHE_Q
2704 wolfSSL_BN_free(dh->q);
2705 dh->q = NULL;
2706 #endif
2707 wolfSSL_BN_free(dh->p);
2708 dh->p = NULL;
2709 wolfSSL_BN_free(dh->g);
2710 dh->g = NULL;
2711 }
2712
2713 return err;
2714}
2715#elif !defined(HAVE_PUBLIC_FFDHE) && (!defined(HAVE_FIPS) || \
2716 FIPS_VERSION_GT(2,0))
2717/* Set the DH parameters based on the NID.
2718 *
2719 * FIPS v2 and lower doesn't support wc_DhSetNamedKey.
2720 *
2721 * @param [in, out] dh DH key to set.
2722 * @param [in] nid Numeric ID of predefined DH parameters.
2723 * @return 0 on success.
2724 * @return 1 on failure.
2725 */
2726static int wolfssl_dh_set_nid(WOLFSSL_DH* dh, int nid)
2727{
2728 int err = 0;
2729 int name = 0;
2730#ifdef HAVE_FFDHE_Q
2731 int elements = ELEMENT_P | ELEMENT_G | ELEMENT_Q;
2732#else
2733 int elements = ELEMENT_P | ELEMENT_G;
2734#endif /* HAVE_FFDHE_Q */
2735
2736 switch (nid) {
2737#ifdef HAVE_FFDHE_2048
2738 case WC_NID_ffdhe2048:
2739 name = WC_FFDHE_2048;
2740 break;
2741#endif /* HAVE_FFDHE_2048 */
2742#ifdef HAVE_FFDHE_3072
2743 case WC_NID_ffdhe3072:
2744 name = WC_FFDHE_3072;
2745 break;
2746#endif /* HAVE_FFDHE_3072 */
2747#ifdef HAVE_FFDHE_4096
2748 case WC_NID_ffdhe4096:
2749 name = WC_FFDHE_4096;
2750 break;
2751#endif /* HAVE_FFDHE_4096 */
2752 default:
2753 err = 1;
2754 WOLFSSL_ERROR_MSG("Unable to find DH params for nid.");
2755 break;
2756 }
2757 /* Set the internal DH key's parameters based on name. */
2758 if ((!err) && (wc_DhSetNamedKey((DhKey*)dh->internal, name) != 0)) {
2759 WOLFSSL_ERROR_MSG("wc_DhSetNamedKey failed.");
2760 err = 1;
2761 }
2762 /* Synchronize the internal into external DH key's parameters. */
2763 if (!err && (SetDhExternal_ex(dh, elements) != 1)) {
2764 WOLFSSL_ERROR_MSG("Failed to set external DH params.");
2765 err = 1;
2766 }
2767
2768 return err;
2769}
2770#else
2771/* Set the DH parameters based on the NID.
2772 *
2773 * Pre-defined DH parameters not available.
2774 *
2775 * @param [in, out] dh DH key to set.
2776 * @param [in] nid Numeric ID of predefined DH parameters.
2777 * @return 1 for failure.
2778 */
2779static int wolfssl_dh_set_nid(WOLFSSL_DH* dh, int nid)
2780{
2781 return 1;
2782}
2783#endif
2784
2785/* Allocate and initialize a new DH key with the parameters based on the NID.
2786 *
2787 * @param [in] nid Numeric ID of DH parameters.
2788 *
2789 * @return DH key on success.
2790 * @return NULL on failure.
2791 */
2792WOLFSSL_DH* wolfSSL_DH_new_by_nid(int nid)
2793{
2794 WOLFSSL_DH* dh = NULL;
2795 int err = 0;
2796
2797 WOLFSSL_ENTER("wolfSSL_DH_new_by_nid");
2798
2799 /* Allocate a new DH key. */
2800 dh = wolfSSL_DH_new();
2801 if (dh == NULL) {
2802 WOLFSSL_ERROR_MSG("Failed to create WOLFSSL_DH.");
2803 err = 1;
2804 }
2805 if (!err) {
2806 /* Set the parameters based on NID. */
2807 err = wolfssl_dh_set_nid(dh, nid);
2808 }
2809
2810 if (err && (dh != NULL)) {
2811 /* Dispose of the key on failure to set. */
2812 wolfSSL_DH_free(dh);
2813 dh = NULL;
2814 }
2815
2816 WOLFSSL_LEAVE("wolfSSL_DH_new_by_nid", err);
2817
2818 return dh;
2819}
2820
2821/* Dispose of DH key and allocated data.
2822 *
2823 * Cannot use dh after this call.
2824 *
2825 * @param [in] dh DH key to free.
2826 */
2827void wolfSSL_DH_free(WOLFSSL_DH* dh)
2828{
2829 int doFree = 0;
2830
2831 WOLFSSL_ENTER("wolfSSL_DH_free");
2832
2833 if (dh != NULL) {
2834 int err;
2835
2836 /* Only free if all references to it are done */
2837 wolfSSL_RefDec(&dh->ref, &doFree, &err);
2838 /* Ignore errors - doFree will be 0 on error. */
2839 (void)err;
2840 }
2841 if (doFree) {
2842 /* Dispose of allocated reference counting data. */
2843 wolfSSL_RefFree(&dh->ref);
2844
2845 /* Dispose of wolfSSL DH key. */
2846 if (dh->internal) {
2847 wc_FreeDhKey((DhKey*)dh->internal);
2848 XFREE(dh->internal, NULL, DYNAMIC_TYPE_DH);
2849 dh->internal = NULL;
2850 }
2851
2852 /* Dispose of any allocated BNs. */
2853 wolfSSL_BN_free(dh->priv_key);
2854 wolfSSL_BN_free(dh->pub_key);
2855 wolfSSL_BN_free(dh->g);
2856 wolfSSL_BN_free(dh->p);
2857 wolfSSL_BN_free(dh->q);
2858 /* Set back to NULLs for safety. */
2859 XMEMSET(dh, 0, sizeof(WOLFSSL_DH));
2860
2861 XFREE(dh, NULL, DYNAMIC_TYPE_DH);
2862 }
2863}
2864
2865/* Increments ref count of DH key.
2866 *
2867 * @param [in, out] dh DH key.
2868 * @return 1 on success
2869 * @return 0 on error
2870 */
2871int wolfSSL_DH_up_ref(WOLFSSL_DH* dh)
2872{
2873 int err = 1;
2874
2875 WOLFSSL_ENTER("wolfSSL_DH_up_ref");
2876
2877 if (dh != NULL) {
2878 wolfSSL_RefInc(&dh->ref, &err);
2879 }
2880
2881 return !err;
2882}
2883
2884#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) || \
2885 defined(OPENSSL_EXTRA)
2886
2887#ifdef WOLFSSL_DH_EXTRA
2888/* Duplicate the DH key.
2889 *
2890 * Internal DH key in 'dh' is updated if necessary.
2891 *
2892 * @param [in, out] dh DH key to duplicate.
2893 * @return NULL on failure.
2894 * @return DH key on success.
2895 */
2896WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh)
2897{
2898 WOLFSSL_DH* ret = NULL;
2899 int err = 0;
2900
2901 WOLFSSL_ENTER("wolfSSL_DH_dup");
2902
2903 /* Validate parameters. */
2904 if (dh == NULL) {
2905 WOLFSSL_ERROR_MSG("Bad parameter");
2906 err = 1;
2907 }
2908
2909 /* Ensure internal DH key is set. */
2910 if ((!err) && (dh->inSet == 0) && (SetDhInternal(dh) != 1)) {
2911 WOLFSSL_ERROR_MSG("Bad DH set internal");
2912 err = 1;
2913 }
2914
2915 /* Create a new DH key object. */
2916 if ((!err) && (!(ret = wolfSSL_DH_new()))) {
2917 WOLFSSL_ERROR_MSG("wolfSSL_DH_new error");
2918 err = 1;
2919 }
2920 /* Copy internal DH key from original to new. */
2921 if ((!err) && (wc_DhKeyCopy((DhKey*)dh->internal, (DhKey*)ret->internal) !=
2922 MP_OKAY)) {
2923 WOLFSSL_ERROR_MSG("wc_DhKeyCopy error");
2924 err = 1;
2925 }
2926 if (!err) {
2927 ret->inSet = 1;
2928
2929 /* Synchronize the internal into external DH key's parameters. */
2930 if (SetDhExternal(ret) != 1) {
2931 WOLFSSL_ERROR_MSG("SetDhExternal error");
2932 err = 1;
2933 }
2934 }
2935
2936 /* Dispose of any allocated DH key on error. */
2937 if (err && (ret != NULL)) {
2938 wolfSSL_DH_free(ret);
2939 ret = NULL;
2940 }
2941 return ret;
2942}
2943#endif /* WOLFSSL_DH_EXTRA */
2944
2945#endif
2946
2947/* Allocate and initialize a new DH key with 2048-bit parameters.
2948 *
2949 * See RFC 5114 section 2.3, "2048-bit MODP Group with 256-bit Prime Order
2950 * Subgroup."
2951 *
2952 * @return NULL on failure.
2953 * @return DH Key on success.
2954 */
2955WOLFSSL_DH* wolfSSL_DH_get_2048_256(void)
2956{
2957 WOLFSSL_DH* dh;
2958 int err = 0;
2959 static const byte pHex[] = {
2960 0x87, 0xA8, 0xE6, 0x1D, 0xB4, 0xB6, 0x66, 0x3C, 0xFF, 0xBB, 0xD1, 0x9C,
2961 0x65, 0x19, 0x59, 0x99, 0x8C, 0xEE, 0xF6, 0x08, 0x66, 0x0D, 0xD0, 0xF2,
2962 0x5D, 0x2C, 0xEE, 0xD4, 0x43, 0x5E, 0x3B, 0x00, 0xE0, 0x0D, 0xF8, 0xF1,
2963 0xD6, 0x19, 0x57, 0xD4, 0xFA, 0xF7, 0xDF, 0x45, 0x61, 0xB2, 0xAA, 0x30,
2964 0x16, 0xC3, 0xD9, 0x11, 0x34, 0x09, 0x6F, 0xAA, 0x3B, 0xF4, 0x29, 0x6D,
2965 0x83, 0x0E, 0x9A, 0x7C, 0x20, 0x9E, 0x0C, 0x64, 0x97, 0x51, 0x7A, 0xBD,
2966 0x5A, 0x8A, 0x9D, 0x30, 0x6B, 0xCF, 0x67, 0xED, 0x91, 0xF9, 0xE6, 0x72,
2967 0x5B, 0x47, 0x58, 0xC0, 0x22, 0xE0, 0xB1, 0xEF, 0x42, 0x75, 0xBF, 0x7B,
2968 0x6C, 0x5B, 0xFC, 0x11, 0xD4, 0x5F, 0x90, 0x88, 0xB9, 0x41, 0xF5, 0x4E,
2969 0xB1, 0xE5, 0x9B, 0xB8, 0xBC, 0x39, 0xA0, 0xBF, 0x12, 0x30, 0x7F, 0x5C,
2970 0x4F, 0xDB, 0x70, 0xC5, 0x81, 0xB2, 0x3F, 0x76, 0xB6, 0x3A, 0xCA, 0xE1,
2971 0xCA, 0xA6, 0xB7, 0x90, 0x2D, 0x52, 0x52, 0x67, 0x35, 0x48, 0x8A, 0x0E,
2972 0xF1, 0x3C, 0x6D, 0x9A, 0x51, 0xBF, 0xA4, 0xAB, 0x3A, 0xD8, 0x34, 0x77,
2973 0x96, 0x52, 0x4D, 0x8E, 0xF6, 0xA1, 0x67, 0xB5, 0xA4, 0x18, 0x25, 0xD9,
2974 0x67, 0xE1, 0x44, 0xE5, 0x14, 0x05, 0x64, 0x25, 0x1C, 0xCA, 0xCB, 0x83,
2975 0xE6, 0xB4, 0x86, 0xF6, 0xB3, 0xCA, 0x3F, 0x79, 0x71, 0x50, 0x60, 0x26,
2976 0xC0, 0xB8, 0x57, 0xF6, 0x89, 0x96, 0x28, 0x56, 0xDE, 0xD4, 0x01, 0x0A,
2977 0xBD, 0x0B, 0xE6, 0x21, 0xC3, 0xA3, 0x96, 0x0A, 0x54, 0xE7, 0x10, 0xC3,
2978 0x75, 0xF2, 0x63, 0x75, 0xD7, 0x01, 0x41, 0x03, 0xA4, 0xB5, 0x43, 0x30,
2979 0xC1, 0x98, 0xAF, 0x12, 0x61, 0x16, 0xD2, 0x27, 0x6E, 0x11, 0x71, 0x5F,
2980 0x69, 0x38, 0x77, 0xFA, 0xD7, 0xEF, 0x09, 0xCA, 0xDB, 0x09, 0x4A, 0xE9,
2981 0x1E, 0x1A, 0x15, 0x97
2982 };
2983 static const byte gHex[] = {
2984 0x3F, 0xB3, 0x2C, 0x9B, 0x73, 0x13, 0x4D, 0x0B, 0x2E, 0x77, 0x50, 0x66,
2985 0x60, 0xED, 0xBD, 0x48, 0x4C, 0xA7, 0xB1, 0x8F, 0x21, 0xEF, 0x20, 0x54,
2986 0x07, 0xF4, 0x79, 0x3A, 0x1A, 0x0B, 0xA1, 0x25, 0x10, 0xDB, 0xC1, 0x50,
2987 0x77, 0xBE, 0x46, 0x3F, 0xFF, 0x4F, 0xED, 0x4A, 0xAC, 0x0B, 0xB5, 0x55,
2988 0xBE, 0x3A, 0x6C, 0x1B, 0x0C, 0x6B, 0x47, 0xB1, 0xBC, 0x37, 0x73, 0xBF,
2989 0x7E, 0x8C, 0x6F, 0x62, 0x90, 0x12, 0x28, 0xF8, 0xC2, 0x8C, 0xBB, 0x18,
2990 0xA5, 0x5A, 0xE3, 0x13, 0x41, 0x00, 0x0A, 0x65, 0x01, 0x96, 0xF9, 0x31,
2991 0xC7, 0x7A, 0x57, 0xF2, 0xDD, 0xF4, 0x63, 0xE5, 0xE9, 0xEC, 0x14, 0x4B,
2992 0x77, 0x7D, 0xE6, 0x2A, 0xAA, 0xB8, 0xA8, 0x62, 0x8A, 0xC3, 0x76, 0xD2,
2993 0x82, 0xD6, 0xED, 0x38, 0x64, 0xE6, 0x79, 0x82, 0x42, 0x8E, 0xBC, 0x83,
2994 0x1D, 0x14, 0x34, 0x8F, 0x6F, 0x2F, 0x91, 0x93, 0xB5, 0x04, 0x5A, 0xF2,
2995 0x76, 0x71, 0x64, 0xE1, 0xDF, 0xC9, 0x67, 0xC1, 0xFB, 0x3F, 0x2E, 0x55,
2996 0xA4, 0xBD, 0x1B, 0xFF, 0xE8, 0x3B, 0x9C, 0x80, 0xD0, 0x52, 0xB9, 0x85,
2997 0xD1, 0x82, 0xEA, 0x0A, 0xDB, 0x2A, 0x3B, 0x73, 0x13, 0xD3, 0xFE, 0x14,
2998 0xC8, 0x48, 0x4B, 0x1E, 0x05, 0x25, 0x88, 0xB9, 0xB7, 0xD2, 0xBB, 0xD2,
2999 0xDF, 0x01, 0x61, 0x99, 0xEC, 0xD0, 0x6E, 0x15, 0x57, 0xCD, 0x09, 0x15,
3000 0xB3, 0x35, 0x3B, 0xBB, 0x64, 0xE0, 0xEC, 0x37, 0x7F, 0xD0, 0x28, 0x37,
3001 0x0D, 0xF9, 0x2B, 0x52, 0xC7, 0x89, 0x14, 0x28, 0xCD, 0xC6, 0x7E, 0xB6,
3002 0x18, 0x4B, 0x52, 0x3D, 0x1D, 0xB2, 0x46, 0xC3, 0x2F, 0x63, 0x07, 0x84,
3003 0x90, 0xF0, 0x0E, 0xF8, 0xD6, 0x47, 0xD1, 0x48, 0xD4, 0x79, 0x54, 0x51,
3004 0x5E, 0x23, 0x27, 0xCF, 0xEF, 0x98, 0xC5, 0x82, 0x66, 0x4B, 0x4C, 0x0F,
3005 0x6C, 0xC4, 0x16, 0x59
3006 };
3007 static const byte qHex[] = {
3008 0x8C, 0xF8, 0x36, 0x42, 0xA7, 0x09, 0xA0, 0x97, 0xB4, 0x47, 0x99, 0x76,
3009 0x40, 0x12, 0x9D, 0xA2, 0x99, 0xB1, 0xA4, 0x7D, 0x1E, 0xB3, 0x75, 0x0B,
3010 0xA3, 0x08, 0xB0, 0xFE, 0x64, 0xF5, 0xFB, 0xD3
3011 };
3012
3013 /* Create a new DH key to return. */
3014 dh = wolfSSL_DH_new();
3015 if (dh == NULL) {
3016 err = 1;
3017 }
3018 if (!err) {
3019 /* Set prime. */
3020 dh->p = wolfSSL_BN_bin2bn(pHex, (int)sizeof(pHex), NULL);
3021 if (dh->p == NULL) {
3022 WOLFSSL_ERROR_MSG("Error converting p hex to WOLFSSL_BIGNUM.");
3023 err = 1;
3024 }
3025 }
3026 if (!err) {
3027 /* Set generator. */
3028 dh->g = wolfSSL_BN_bin2bn(gHex, (int)sizeof(gHex), NULL);
3029 if (dh->g == NULL) {
3030 WOLFSSL_ERROR_MSG("Error converting g hex to WOLFSSL_BIGNUM.");
3031 err = 1;
3032 }
3033 }
3034 if (!err) {
3035 /* Set order. */
3036 dh->q = wolfSSL_BN_bin2bn(qHex, (int)sizeof(qHex), NULL);
3037 if (dh->q == NULL) {
3038 WOLFSSL_ERROR_MSG("Error converting q hex to WOLFSSL_BIGNUM.");
3039 err = 1;
3040 }
3041 }
3042 /* Set values into wolfSSL DH key. */
3043 if ((!err) && (SetDhInternal(dh) != 1)) {
3044 WOLFSSL_ERROR_MSG("Error setting DH parameters.");
3045 err = 1;
3046 }
3047 if (!err) {
3048 /* External DH key parameters were set. */
3049 dh->exSet = 1;
3050 }
3051
3052 /* Dispose of any allocated DH key on error. */
3053 if (err && (dh != NULL)) {
3054 wolfSSL_DH_free(dh);
3055 dh = NULL;
3056 }
3057
3058 return dh;
3059}
3060
3061/* TODO: consider changing strings to byte arrays. */
3062
3063/* Returns a big number with the 768-bit prime from RFC 2409.
3064 *
3065 * @param [in, out] bn If not NULL then this BN is set and returned.
3066 * If NULL then a new BN is created, set and returned.
3067 *
3068 * @return NULL on failure.
3069 * @return WOLFSSL_BIGNUM with value set to 768-bit prime on success.
3070 */
3071WOLFSSL_BIGNUM* wolfSSL_DH_768_prime(WOLFSSL_BIGNUM* bn)
3072{
3073#if WOLFSSL_MAX_BN_BITS >= 768
3074 static const char prm[] = {
3075 "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3076 "C4C6628B80DC1CD129024E088A67CC74"
3077 "020BBEA63B139B22514A08798E3404DD"
3078 "EF9519B3CD3A431B302B0A6DF25F1437"
3079 "4FE1356D6D51C245E485B576625E7EC6"
3080 "F44C42E9A63A3620FFFFFFFFFFFFFFFF"
3081 };
3082
3083 WOLFSSL_ENTER("wolfSSL_DH_768_prime");
3084
3085 /* Set prime into BN. Creates a new BN when bn is NULL. */
3086 if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3087 WOLFSSL_ERROR_MSG("Error converting DH 768 prime to big number");
3088 bn = NULL;
3089 }
3090
3091 return bn;
3092#else
3093 (void)bn;
3094 return NULL;
3095#endif
3096}
3097
3098/* Returns a big number with the 1024-bit prime from RFC 2409.
3099 *
3100 * @param [in, out] bn If not NULL then this BN is set and returned.
3101 * If NULL then a new BN is created, set and returned.
3102 *
3103 * @return NULL on failure.
3104 * @return WOLFSSL_BIGNUM with value set to 1024-bit prime on success.
3105 */
3106WOLFSSL_BIGNUM* wolfSSL_DH_1024_prime(WOLFSSL_BIGNUM* bn)
3107{
3108#if WOLFSSL_MAX_BN_BITS >= 1024
3109 static const char prm[] = {
3110 "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3111 "C4C6628B80DC1CD129024E088A67CC74"
3112 "020BBEA63B139B22514A08798E3404DD"
3113 "EF9519B3CD3A431B302B0A6DF25F1437"
3114 "4FE1356D6D51C245E485B576625E7EC6"
3115 "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3116 "EE386BFB5A899FA5AE9F24117C4B1FE6"
3117 "49286651ECE65381FFFFFFFFFFFFFFFF"
3118 };
3119
3120 WOLFSSL_ENTER("wolfSSL_DH_1024_prime");
3121
3122 /* Set prime into BN. Creates a new BN when bn is NULL. */
3123 if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3124 WOLFSSL_ERROR_MSG("Error converting DH 1024 prime to big number");
3125 bn = NULL;
3126 }
3127
3128 return bn;
3129#else
3130 (void)bn;
3131 return NULL;
3132#endif
3133}
3134
3135/* Returns a big number with the 1536-bit prime from RFC 3526.
3136 *
3137 * @param [in, out] bn If not NULL then this BN is set and returned.
3138 * If NULL then a new BN is created, set and returned.
3139 *
3140 * @return NULL on failure.
3141 * @return WOLFSSL_BIGNUM with value set to 1536-bit prime on success.
3142 */
3143WOLFSSL_BIGNUM* wolfSSL_DH_1536_prime(WOLFSSL_BIGNUM* bn)
3144{
3145#if WOLFSSL_MAX_BN_BITS >= 1536
3146 static const char prm[] = {
3147 "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3148 "C4C6628B80DC1CD129024E088A67CC74"
3149 "020BBEA63B139B22514A08798E3404DD"
3150 "EF9519B3CD3A431B302B0A6DF25F1437"
3151 "4FE1356D6D51C245E485B576625E7EC6"
3152 "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3153 "EE386BFB5A899FA5AE9F24117C4B1FE6"
3154 "49286651ECE45B3DC2007CB8A163BF05"
3155 "98DA48361C55D39A69163FA8FD24CF5F"
3156 "83655D23DCA3AD961C62F356208552BB"
3157 "9ED529077096966D670C354E4ABC9804"
3158 "F1746C08CA237327FFFFFFFFFFFFFFFF"
3159 };
3160
3161 WOLFSSL_ENTER("wolfSSL_DH_1536_prime");
3162
3163 /* Set prime into BN. Creates a new BN when bn is NULL. */
3164 if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3165 WOLFSSL_ERROR_MSG("Error converting DH 1536 prime to big number");
3166 bn = NULL;
3167 }
3168
3169 return bn;
3170#else
3171 (void)bn;
3172 return NULL;
3173#endif
3174}
3175
3176/* Returns a big number with the 2048-bit prime from RFC 3526.
3177 *
3178 * @param [in, out] bn If not NULL then this BN is set and returned.
3179 * If NULL then a new BN is created, set and returned.
3180 *
3181 * @return NULL on failure.
3182 * @return WOLFSSL_BIGNUM with value set to 2048-bit prime on success.
3183 */
3184WOLFSSL_BIGNUM* wolfSSL_DH_2048_prime(WOLFSSL_BIGNUM* bn)
3185{
3186#if WOLFSSL_MAX_BN_BITS >= 2048
3187 static const char prm[] = {
3188 "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3189 "C4C6628B80DC1CD129024E088A67CC74"
3190 "020BBEA63B139B22514A08798E3404DD"
3191 "EF9519B3CD3A431B302B0A6DF25F1437"
3192 "4FE1356D6D51C245E485B576625E7EC6"
3193 "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3194 "EE386BFB5A899FA5AE9F24117C4B1FE6"
3195 "49286651ECE45B3DC2007CB8A163BF05"
3196 "98DA48361C55D39A69163FA8FD24CF5F"
3197 "83655D23DCA3AD961C62F356208552BB"
3198 "9ED529077096966D670C354E4ABC9804"
3199 "F1746C08CA18217C32905E462E36CE3B"
3200 "E39E772C180E86039B2783A2EC07A28F"
3201 "B5C55DF06F4C52C9DE2BCBF695581718"
3202 "3995497CEA956AE515D2261898FA0510"
3203 "15728E5A8AACAA68FFFFFFFFFFFFFFFF"
3204 };
3205
3206 WOLFSSL_ENTER("wolfSSL_DH_2048_prime");
3207
3208 /* Set prime into BN. Creates a new BN when bn is NULL. */
3209 if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3210 WOLFSSL_ERROR_MSG("Error converting DH 2048 prime to big number");
3211 bn = NULL;
3212 }
3213
3214 return bn;
3215#else
3216 (void)bn;
3217 return NULL;
3218#endif
3219}
3220
3221/* Returns a big number with the 3072-bit prime from RFC 3526.
3222 *
3223 * @param [in, out] bn If not NULL then this BN is set and returned.
3224 * If NULL then a new BN is created, set and returned.
3225 *
3226 * @return NULL on failure.
3227 * @return WOLFSSL_BIGNUM with value set to 3072-bit prime on success.
3228 */
3229WOLFSSL_BIGNUM* wolfSSL_DH_3072_prime(WOLFSSL_BIGNUM* bn)
3230{
3231#if WOLFSSL_MAX_BN_BITS >= 3072
3232 static const char prm[] = {
3233 "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3234 "C4C6628B80DC1CD129024E088A67CC74"
3235 "020BBEA63B139B22514A08798E3404DD"
3236 "EF9519B3CD3A431B302B0A6DF25F1437"
3237 "4FE1356D6D51C245E485B576625E7EC6"
3238 "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3239 "EE386BFB5A899FA5AE9F24117C4B1FE6"
3240 "49286651ECE45B3DC2007CB8A163BF05"
3241 "98DA48361C55D39A69163FA8FD24CF5F"
3242 "83655D23DCA3AD961C62F356208552BB"
3243 "9ED529077096966D670C354E4ABC9804"
3244 "F1746C08CA18217C32905E462E36CE3B"
3245 "E39E772C180E86039B2783A2EC07A28F"
3246 "B5C55DF06F4C52C9DE2BCBF695581718"
3247 "3995497CEA956AE515D2261898FA0510"
3248 "15728E5A8AAAC42DAD33170D04507A33"
3249 "A85521ABDF1CBA64ECFB850458DBEF0A"
3250 "8AEA71575D060C7DB3970F85A6E1E4C7"
3251 "ABF5AE8CDB0933D71E8C94E04A25619D"
3252 "CEE3D2261AD2EE6BF12FFA06D98A0864"
3253 "D87602733EC86A64521F2B18177B200C"
3254 "BBE117577A615D6C770988C0BAD946E2"
3255 "08E24FA074E5AB3143DB5BFCE0FD108E"
3256 "4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
3257 };
3258
3259 WOLFSSL_ENTER("wolfSSL_DH_3072_prime");
3260
3261 /* Set prime into BN. Creates a new BN when bn is NULL. */
3262 if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3263 WOLFSSL_ERROR_MSG("Error converting DH 3072 prime to big number");
3264 bn = NULL;
3265 }
3266
3267 return bn;
3268#else
3269 (void)bn;
3270 return NULL;
3271#endif
3272}
3273
3274/* Returns a big number with the 4096-bit prime from RFC 3526.
3275 *
3276 * @param [in, out] bn If not NULL then this BN is set and returned.
3277 * If NULL then a new BN is created, set and returned.
3278 *
3279 * @return NULL on failure.
3280 * @return WOLFSSL_BIGNUM with value set to 4096-bit prime on success.
3281 */
3282WOLFSSL_BIGNUM* wolfSSL_DH_4096_prime(WOLFSSL_BIGNUM* bn)
3283{
3284#if WOLFSSL_MAX_BN_BITS >= 4096
3285 static const char prm[] = {
3286 "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3287 "C4C6628B80DC1CD129024E088A67CC74"
3288 "020BBEA63B139B22514A08798E3404DD"
3289 "EF9519B3CD3A431B302B0A6DF25F1437"
3290 "4FE1356D6D51C245E485B576625E7EC6"
3291 "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3292 "EE386BFB5A899FA5AE9F24117C4B1FE6"
3293 "49286651ECE45B3DC2007CB8A163BF05"
3294 "98DA48361C55D39A69163FA8FD24CF5F"
3295 "83655D23DCA3AD961C62F356208552BB"
3296 "9ED529077096966D670C354E4ABC9804"
3297 "F1746C08CA18217C32905E462E36CE3B"
3298 "E39E772C180E86039B2783A2EC07A28F"
3299 "B5C55DF06F4C52C9DE2BCBF695581718"
3300 "3995497CEA956AE515D2261898FA0510"
3301 "15728E5A8AAAC42DAD33170D04507A33"
3302 "A85521ABDF1CBA64ECFB850458DBEF0A"
3303 "8AEA71575D060C7DB3970F85A6E1E4C7"
3304 "ABF5AE8CDB0933D71E8C94E04A25619D"
3305 "CEE3D2261AD2EE6BF12FFA06D98A0864"
3306 "D87602733EC86A64521F2B18177B200C"
3307 "BBE117577A615D6C770988C0BAD946E2"
3308 "08E24FA074E5AB3143DB5BFCE0FD108E"
3309 "4B82D120A92108011A723C12A787E6D7"
3310 "88719A10BDBA5B2699C327186AF4E23C"
3311 "1A946834B6150BDA2583E9CA2AD44CE8"
3312 "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
3313 "287C59474E6BC05D99B2964FA090C3A2"
3314 "233BA186515BE7ED1F612970CEE2D7AF"
3315 "B81BDD762170481CD0069127D5B05AA9"
3316 "93B4EA988D8FDDC186FFB7DC90A6C08F"
3317 "4DF435C934063199FFFFFFFFFFFFFFFF"
3318 };
3319
3320 WOLFSSL_ENTER("wolfSSL_DH_4096_prime");
3321
3322 /* Set prime into BN. Creates a new BN when bn is NULL. */
3323 if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3324 WOLFSSL_ERROR_MSG("Error converting DH 4096 prime to big number");
3325 bn = NULL;
3326 }
3327
3328 return bn;
3329#else
3330 (void)bn;
3331 return NULL;
3332#endif
3333}
3334
3335/* Returns a big number with the 6144-bit prime from RFC 3526.
3336 *
3337 * @param [in, out] bn If not NULL then this BN is set and returned.
3338 * If NULL then a new BN is created, set and returned.
3339 *
3340 * @return NULL on failure.
3341 * @return WOLFSSL_BIGNUM with value set to 6144-bit prime on success.
3342 */
3343WOLFSSL_BIGNUM* wolfSSL_DH_6144_prime(WOLFSSL_BIGNUM* bn)
3344{
3345#if WOLFSSL_MAX_BN_BITS >= 6144
3346 static const char prm[] = {
3347 "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3348 "C4C6628B80DC1CD129024E088A67CC74"
3349 "020BBEA63B139B22514A08798E3404DD"
3350 "EF9519B3CD3A431B302B0A6DF25F1437"
3351 "4FE1356D6D51C245E485B576625E7EC6"
3352 "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3353 "EE386BFB5A899FA5AE9F24117C4B1FE6"
3354 "49286651ECE45B3DC2007CB8A163BF05"
3355 "98DA48361C55D39A69163FA8FD24CF5F"
3356 "83655D23DCA3AD961C62F356208552BB"
3357 "9ED529077096966D670C354E4ABC9804"
3358 "F1746C08CA18217C32905E462E36CE3B"
3359 "E39E772C180E86039B2783A2EC07A28F"
3360 "B5C55DF06F4C52C9DE2BCBF695581718"
3361 "3995497CEA956AE515D2261898FA0510"
3362 "15728E5A8AAAC42DAD33170D04507A33"
3363 "A85521ABDF1CBA64ECFB850458DBEF0A"
3364 "8AEA71575D060C7DB3970F85A6E1E4C7"
3365 "ABF5AE8CDB0933D71E8C94E04A25619D"
3366 "CEE3D2261AD2EE6BF12FFA06D98A0864"
3367 "D87602733EC86A64521F2B18177B200C"
3368 "BBE117577A615D6C770988C0BAD946E2"
3369 "08E24FA074E5AB3143DB5BFCE0FD108E"
3370 "4B82D120A92108011A723C12A787E6D7"
3371 "88719A10BDBA5B2699C327186AF4E23C"
3372 "1A946834B6150BDA2583E9CA2AD44CE8"
3373 "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
3374 "287C59474E6BC05D99B2964FA090C3A2"
3375 "233BA186515BE7ED1F612970CEE2D7AF"
3376 "B81BDD762170481CD0069127D5B05AA9"
3377 "93B4EA988D8FDDC186FFB7DC90A6C08F"
3378 "4DF435C93402849236C3FAB4D27C7026"
3379 "C1D4DCB2602646DEC9751E763DBA37BD"
3380 "F8FF9406AD9E530EE5DB382F413001AE"
3381 "B06A53ED9027D831179727B0865A8918"
3382 "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
3383 "DB7F1447E6CC254B332051512BD7AF42"
3384 "6FB8F401378CD2BF5983CA01C64B92EC"
3385 "F032EA15D1721D03F482D7CE6E74FEF6"
3386 "D55E702F46980C82B5A84031900B1C9E"
3387 "59E7C97FBEC7E8F323A97A7E36CC88BE"
3388 "0F1D45B7FF585AC54BD407B22B4154AA"
3389 "CC8F6D7EBF48E1D814CC5ED20F8037E0"
3390 "A79715EEF29BE32806A1D58BB7C5DA76"
3391 "F550AA3D8A1FBFF0EB19CCB1A313D55C"
3392 "DA56C9EC2EF29632387FE8D76E3C0468"
3393 "043E8F663F4860EE12BF2D5B0B7474D6"
3394 "E694F91E6DCC4024FFFFFFFFFFFFFFFF"
3395 };
3396
3397 WOLFSSL_ENTER("wolfSSL_DH_6144_prime");
3398
3399 /* Set prime into BN. Creates a new BN when bn is NULL. */
3400 if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3401 WOLFSSL_ERROR_MSG("Error converting DH 6144 prime to big number");
3402 bn = NULL;
3403 }
3404
3405 return bn;
3406#else
3407 (void)bn;
3408 return NULL;
3409#endif
3410}
3411
3412
3413/* Returns a big number with the 8192-bit prime from RFC 3526.
3414 *
3415 * @param [in, out] bn If not NULL then this BN is set and returned.
3416 * If NULL then a new BN is created, set and returned.
3417 *
3418 * @return NULL on failure.
3419 * @return WOLFSSL_BIGNUM with value set to 8192-bit prime on success.
3420 */
3421WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
3422{
3423#if WOLFSSL_MAX_BN_BITS >= 8192
3424 static const char prm[] = {
3425 "FFFFFFFFFFFFFFFFC90FDAA22168C234"
3426 "C4C6628B80DC1CD129024E088A67CC74"
3427 "020BBEA63B139B22514A08798E3404DD"
3428 "EF9519B3CD3A431B302B0A6DF25F1437"
3429 "4FE1356D6D51C245E485B576625E7EC6"
3430 "F44C42E9A637ED6B0BFF5CB6F406B7ED"
3431 "EE386BFB5A899FA5AE9F24117C4B1FE6"
3432 "49286651ECE45B3DC2007CB8A163BF05"
3433 "98DA48361C55D39A69163FA8FD24CF5F"
3434 "83655D23DCA3AD961C62F356208552BB"
3435 "9ED529077096966D670C354E4ABC9804"
3436 "F1746C08CA18217C32905E462E36CE3B"
3437 "E39E772C180E86039B2783A2EC07A28F"
3438 "B5C55DF06F4C52C9DE2BCBF695581718"
3439 "3995497CEA956AE515D2261898FA0510"
3440 "15728E5A8AAAC42DAD33170D04507A33"
3441 "A85521ABDF1CBA64ECFB850458DBEF0A"
3442 "8AEA71575D060C7DB3970F85A6E1E4C7"
3443 "ABF5AE8CDB0933D71E8C94E04A25619D"
3444 "CEE3D2261AD2EE6BF12FFA06D98A0864"
3445 "D87602733EC86A64521F2B18177B200C"
3446 "BBE117577A615D6C770988C0BAD946E2"
3447 "08E24FA074E5AB3143DB5BFCE0FD108E"
3448 "4B82D120A92108011A723C12A787E6D7"
3449 "88719A10BDBA5B2699C327186AF4E23C"
3450 "1A946834B6150BDA2583E9CA2AD44CE8"
3451 "DBBBC2DB04DE8EF92E8EFC141FBECAA6"
3452 "287C59474E6BC05D99B2964FA090C3A2"
3453 "233BA186515BE7ED1F612970CEE2D7AF"
3454 "B81BDD762170481CD0069127D5B05AA9"
3455 "93B4EA988D8FDDC186FFB7DC90A6C08F"
3456 "4DF435C93402849236C3FAB4D27C7026"
3457 "C1D4DCB2602646DEC9751E763DBA37BD"
3458 "F8FF9406AD9E530EE5DB382F413001AE"
3459 "B06A53ED9027D831179727B0865A8918"
3460 "DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
3461 "DB7F1447E6CC254B332051512BD7AF42"
3462 "6FB8F401378CD2BF5983CA01C64B92EC"
3463 "F032EA15D1721D03F482D7CE6E74FEF6"
3464 "D55E702F46980C82B5A84031900B1C9E"
3465 "59E7C97FBEC7E8F323A97A7E36CC88BE"
3466 "0F1D45B7FF585AC54BD407B22B4154AA"
3467 "CC8F6D7EBF48E1D814CC5ED20F8037E0"
3468 "A79715EEF29BE32806A1D58BB7C5DA76"
3469 "F550AA3D8A1FBFF0EB19CCB1A313D55C"
3470 "DA56C9EC2EF29632387FE8D76E3C0468"
3471 "043E8F663F4860EE12BF2D5B0B7474D6"
3472 "E694F91E6DBE115974A3926F12FEE5E4"
3473 "38777CB6A932DF8CD8BEC4D073B931BA"
3474 "3BC832B68D9DD300741FA7BF8AFC47ED"
3475 "2576F6936BA424663AAB639C5AE4F568"
3476 "3423B4742BF1C978238F16CBE39D652D"
3477 "E3FDB8BEFC848AD922222E04A4037C07"
3478 "13EB57A81A23F0C73473FC646CEA306B"
3479 "4BCBC8862F8385DDFA9D4B7FA2C087E8"
3480 "79683303ED5BDD3A062B3CF5B3A278A6"
3481 "6D2A13F83F44F82DDF310EE074AB6A36"
3482 "4597E899A0255DC164F31CC50846851D"
3483 "F9AB48195DED7EA1B1D510BD7EE74D73"
3484 "FAF36BC31ECFA268359046F4EB879F92"
3485 "4009438B481C6CD7889A002ED5EE382B"
3486 "C9190DA6FC026E479558E4475677E9AA"
3487 "9E3050E2765694DFC81F56E880B96E71"
3488 "60C980DD98EDD3DFFFFFFFFFFFFFFFFF"
3489 };
3490
3491 WOLFSSL_ENTER("wolfSSL_DH_8192_prime");
3492
3493 /* Set prime into BN. Creates a new BN when bn is NULL. */
3494 if (wolfSSL_BN_hex2bn(&bn, prm) != 1) {
3495 WOLFSSL_ERROR_MSG("Error converting DH 8192 prime to big number");
3496 bn = NULL;
3497 }
3498
3499 return bn;
3500#else
3501 (void)bn;
3502 return NULL;
3503#endif
3504}
3505
3506/*
3507 * DH to/from bin APIs
3508 */
3509
3510#ifndef NO_CERTS
3511
3512/* Load the DER encoded DH parameters into DH key.
3513 *
3514 * @param [in, out] dh DH key to load parameters into.
3515 * @param [in] der Buffer holding DER encoded parameters data.
3516 * @param [in, out] idx On in, index at which DH key DER data starts.
3517 * On out, index after DH key DER data.
3518 * @param [in] derSz Size of DER buffer in bytes.
3519 *
3520 * @return 0 on success.
3521 * @return 1 when decoding DER or setting the external key fails.
3522 */
3523static int wolfssl_dh_load_params(WOLFSSL_DH* dh, const unsigned char* der,
3524 word32* idx, word32 derSz)
3525{
3526 int err = 0;
3527
3528#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
3529 int ret;
3530
3531 /* Decode DH parameters/key from DER. */
3532 ret = wc_DhKeyDecode(der, idx, (DhKey*)dh->internal, derSz);
3533 if (ret != 0) {
3534 WOLFSSL_ERROR_MSG("DhKeyDecode() failed");
3535 err = 1;
3536 }
3537 if (!err) {
3538 /* wolfSSL DH key set. */
3539 dh->inSet = 1;
3540
3541 /* Set the external DH key based on wolfSSL DH key. */
3542 if (SetDhExternal(dh) != 1) {
3543 WOLFSSL_ERROR_MSG("SetDhExternal failed");
3544 err = 1;
3545 }
3546 }
3547#else
3548 byte* p;
3549 byte* g;
3550 word32 pSz = MAX_DH_SIZE;
3551 word32 gSz = MAX_DH_SIZE;
3552
3553 /* Only DH parameters supported. */
3554 /* Load external and set internal. */
3555 p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
3556 g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
3557 if ((p == NULL) || (g == NULL)) {
3558 err = 1;
3559 }
3560 /* Extract the p and g as data from the DER encoded DH parameters. */
3561 if ((!err) && (wc_DhParamsLoad(der + *idx, derSz - *idx, p, &pSz, g,
3562 &gSz) < 0)) {
3563 err = 1;
3564 }
3565 if (!err) {
3566 /* Put p and g in as big numbers - free existing BNs. */
3567 if (dh->p != NULL) {
3568 wolfSSL_BN_free(dh->p);
3569 dh->p = NULL;
3570 }
3571 if (dh->g != NULL) {
3572 wolfSSL_BN_free(dh->g);
3573 dh->g = NULL;
3574 }
3575 dh->p = wolfSSL_BN_bin2bn(p, (int)pSz, NULL);
3576 dh->g = wolfSSL_BN_bin2bn(g, (int)gSz, NULL);
3577 if (dh->p == NULL || dh->g == NULL) {
3578 err = 1;
3579 }
3580 else {
3581 /* External DH key parameters were set. */
3582 dh->exSet = 1;
3583 }
3584 }
3585
3586 /* Set internal as the outside has been updated. */
3587 if ((!err) && (SetDhInternal(dh) != 1)) {
3588 WOLFSSL_ERROR_MSG("Unable to set internal DH structure");
3589 err = 1;
3590 }
3591
3592 if (!err) {
3593 *idx += wolfssl_der_length(der + *idx, derSz - *idx);
3594 }
3595
3596 XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
3597 XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
3598#endif
3599
3600 return err;
3601}
3602
3603#ifdef OPENSSL_ALL
3604
3605#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
3606/* Convert DER encoded DH parameters to a WOLFSSL_DH structure.
3607 *
3608 * @param [out] dh DH key to put parameters into. May be NULL.
3609 * @param [in, out] pp Pointer to DER encoded DH parameters.
3610 * Value updated to end of data when dh is not NULL.
3611 * @param [in] length Length of data available in bytes.
3612 *
3613 * @return DH key on success.
3614 * @return NULL on failure.
3615 */
3616WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH** dh, const unsigned char** pp,
3617 long length)
3618{
3619 WOLFSSL_DH *newDh = NULL;
3620 word32 idx = 0;
3621 int err = 0;
3622
3623 WOLFSSL_ENTER("wolfSSL_d2i_DHparams");
3624
3625 /* Validate parameters. */
3626 if ((pp == NULL) || (length <= 0)) {
3627 WOLFSSL_ERROR_MSG("bad argument");
3628 err = 1;
3629 }
3630
3631 /* Create new DH key to return. */
3632 if ((!err) && ((newDh = wolfSSL_DH_new()) == NULL)) {
3633 WOLFSSL_ERROR_MSG("wolfSSL_DH_new() failed");
3634 err = 1;
3635 }
3636 if ((!err) && (wolfssl_dh_load_params(newDh, *pp, &idx,
3637 (word32)length) != 0)) {
3638 WOLFSSL_ERROR_MSG("Loading DH parameters failed");
3639 err = 1;
3640 }
3641
3642 if ((!err) && (dh != NULL)) {
3643 /* Return through parameter too. */
3644 *dh = newDh;
3645 /* Move buffer on by the used amount. */
3646 *pp += idx;
3647 }
3648
3649 if (err && (newDh != NULL)) {
3650 /* Dispose of any created DH key. */
3651 wolfSSL_DH_free(newDh);
3652 newDh = NULL;
3653 }
3654 return newDh;
3655}
3656#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
3657
3658/* Converts internal WOLFSSL_DH structure to DER encoded DH parameters.
3659 *
3660 * @params [in] dh DH key with parameters to encode.
3661 * @params [in, out] out Pointer to buffer to encode into.
3662 * When NULL or pointer to NULL, only length returned.
3663 * @return 0 on error.
3664 * @return Size of DER encoding in bytes on success.
3665 */
3666int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out)
3667{
3668#if (!defined(HAVE_FIPS) || FIPS_VERSION_GT(5,0)) && defined(WOLFSSL_DH_EXTRA)
3669 /* Set length to an arbitrarily large value for wc_DhParamsToDer(). */
3670 word32 len = (word32)-1;
3671 int err = 0;
3672
3673 /* Validate parameters. */
3674 if (dh == NULL) {
3675 WOLFSSL_ERROR_MSG("Bad parameters");
3676 err = 1;
3677 }
3678
3679 /* Push external DH data into internal DH key if not set. */
3680 if ((!err) && (!dh->inSet) && (SetDhInternal((WOLFSSL_DH*)dh) != 1)) {
3681 WOLFSSL_ERROR_MSG("Bad DH set internal");
3682 err = 1;
3683 }
3684 if (!err) {
3685 int ret;
3686 unsigned char* der = NULL;
3687
3688 /* Use *out when available otherwise NULL. */
3689 if (out != NULL) {
3690 der = *out;
3691 }
3692 /* Get length and/or encode. */
3693 ret = wc_DhParamsToDer((DhKey*)dh->internal, der, &len);
3694 /* Length of encoded data is returned on success. */
3695 if (ret > 0) {
3696 *out += len;
3697 }
3698 /* An error occurred unless only length returned. */
3699 else if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
3700 err = 1;
3701 }
3702 }
3703
3704 /* Set return to 0 on error. */
3705 if (err) {
3706 len = 0;
3707 }
3708 return (int)len;
3709#else
3710 word32 len;
3711 int ret = 0;
3712 int pSz;
3713 int gSz;
3714
3715 WOLFSSL_ENTER("wolfSSL_i2d_DHparams");
3716
3717 /* Validate parameters. */
3718 if (dh == NULL) {
3719 WOLFSSL_ERROR_MSG("Bad parameters");
3720 len = 0;
3721 }
3722 else {
3723 /* SEQ <len>
3724 * INT <len> [0x00] <prime>
3725 * INT <len> [0x00] <generator>
3726 * Integers have 0x00 prepended if the top bit of positive number is
3727 * set.
3728 */
3729 /* Get total length of prime including any prepended zeros. */
3730 pSz = mp_unsigned_bin_size((mp_int*)dh->p->internal) +
3731 mp_leading_bit((mp_int*)dh->p->internal);
3732 /* Get total length of generator including any prepended zeros. */
3733 gSz = mp_unsigned_bin_size((mp_int*)dh->g->internal) +
3734 mp_leading_bit((mp_int*)dh->g->internal);
3735 /* Calculate length of data in sequence. */
3736 len = 1 + ASN_LEN_SIZE(pSz) + pSz +
3737 1 + ASN_LEN_SIZE(gSz) + gSz;
3738 /* Add in the length of the SEQUENCE. */
3739 len += 1 + ASN_LEN_SIZE(len);
3740
3741 if ((out != NULL) && (*out != NULL)) {
3742 /* Encode parameters. */
3743 ret = StoreDHparams(*out, &len, (mp_int*)dh->p->internal,
3744 (mp_int*)dh->g->internal);
3745 if (ret != MP_OKAY) {
3746 WOLFSSL_ERROR_MSG("StoreDHparams error");
3747 len = 0;
3748 }
3749 else {
3750 /* Move pointer on if encoded. */
3751 *out += len;
3752 }
3753 }
3754 }
3755
3756 return (int)len;
3757#endif
3758}
3759
3760#endif /* OPENSSL_ALL */
3761
3762#endif /* !NO_CERTS */
3763
3764#endif /* OPENSSL_EXTRA */
3765
3766#if defined(OPENSSL_EXTRA) || \
3767 ((!defined(NO_BIO) || !defined(NO_FILESYSTEM)) && \
3768 defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) || \
3769 defined(WOLFSSL_MYSQL_COMPATIBLE))
3770
3771/* Load the DER encoded DH parameters into DH key.
3772 *
3773 * @param [in, out] dh DH key to load parameters into.
3774 * @param [in] derBuf Buffer holding DER encoded parameters data.
3775 * @param [in] derSz Size of DER data in buffer in bytes.
3776 *
3777 * @return 1 on success.
3778 * @return -1 when DH or derBuf is NULL,
3779 * internal DH key in DH is NULL,
3780 * derSz is 0 or less,
3781 * error decoding DER data or
3782 * setting external parameter values fails.
3783 */
3784int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz)
3785{
3786 int ret = 1;
3787 word32 idx = 0;
3788
3789 /* Validate parameters. */
3790 if ((dh == NULL) || (dh->internal == NULL) || (derBuf == NULL) ||
3791 (derSz <= 0)) {
3792 WOLFSSL_ERROR_MSG("Bad function arguments");
3793 ret = WOLFSSL_FATAL_ERROR;
3794 }
3795
3796 if ((ret == 1) && (wolfssl_dh_load_params(dh, derBuf, &idx,
3797 (word32)derSz) != 0)) {
3798 WOLFSSL_ERROR_MSG("DH key decode failed");
3799 ret = WOLFSSL_FATAL_ERROR;
3800 }
3801
3802 return ret;
3803}
3804
3805#endif
3806
3807/*
3808 * DH PEM APIs
3809 */
3810
3811#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
3812 || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
3813
3814#if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
3815/* Create a DH key by reading the PEM encoded data from the BIO.
3816 *
3817 * @param [in] bio BIO object to read from.
3818 * @param [in, out] dh DH key to use. May be NULL.
3819 * @param [in] pem PEM data to decode.
3820 * @param [in] pemSz Size of PEM data in bytes.
3821 * @param [in] memAlloced Indicates that pem was allocated and is to be
3822 * freed after use.
3823 * @return DH key on success.
3824 * @return NULL on failure.
3825 */
3826static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **dh,
3827 unsigned char* pem, int pemSz, int memAlloced)
3828{
3829 WOLFSSL_DH* localDh = NULL;
3830 DerBuffer *der = NULL;
3831 int err = 0;
3832
3833 /* Convert PEM to DER assuming DH Parameter format. */
3834 if ((!err) && (PemToDer(pem, pemSz, DH_PARAM_TYPE, &der, NULL, NULL,
3835 NULL) < 0)) {
3836 /* Convert PEM to DER assuming X9.42 DH Parameter format. */
3837 if (PemToDer(pem, pemSz, X942_PARAM_TYPE, &der, NULL, NULL, NULL)
3838 != 0) {
3839 err = 1;
3840 }
3841 /* If Success on X9.42 DH format, clear error from failed DH format */
3842 else {
3843 unsigned long error;
3844 CLEAR_ASN_NO_PEM_HEADER_ERROR(error);
3845 }
3846 }
3847 if (memAlloced) {
3848 /* PEM data no longer needed. */
3849 XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3850 }
3851
3852 if (!err) {
3853 /* Use the DH key passed in or allocate a new one. */
3854 if (dh != NULL) {
3855 localDh = *dh;
3856 }
3857 if (localDh == NULL) {
3858 localDh = wolfSSL_DH_new();
3859 if (localDh == NULL) {
3860 err = 1;
3861 }
3862 }
3863 }
3864 /* Load the DER encoded DH parameters from buffer into a DH key. */
3865 if ((!err) && (wolfSSL_DH_LoadDer(localDh, der->buffer, (int)der->length)
3866 != 1)) {
3867 /* Free an allocated DH key. */
3868 if ((dh == NULL) || (localDh != *dh)) {
3869 wolfSSL_DH_free(localDh);
3870 }
3871 localDh = NULL;
3872 err = 1;
3873 }
3874 /* Return the DH key on success. */
3875 if ((!err) && (dh != NULL)) {
3876 *dh = localDh;
3877 }
3878
3879 /* Dispose of DER data. */
3880 if (der != NULL) {
3881 FreeDer(&der);
3882 }
3883 return localDh;
3884}
3885#endif /* !NO_BIO || !NO_FILESYSTEM */
3886
3887#ifndef NO_BIO
3888/* Create a DH key by reading the PEM encoded data from the BIO.
3889 *
3890 * DH parameters are public data and are not expected to be encrypted.
3891 *
3892 * @param [in] bio BIO object to read from.
3893 * @param [in, out] dh DH key to When pointer to
3894 * NULL, a new DH key is created.
3895 * @param [in] cb Password callback when PEM encrypted. Not used.
3896 * @param [in] pass NUL terminated string for passphrase when PEM
3897 * encrypted. Not used.
3898 * @return DH key on success.
3899 * @return NULL on failure.
3900 */
3901WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **dh,
3902 wc_pem_password_cb *cb, void *pass)
3903{
3904 WOLFSSL_DH* localDh = NULL;
3905 int err = 0;
3906 unsigned char* mem = NULL;
3907 int size = 0;
3908 int memAlloced = 0;
3909
3910 WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
3911
3912 (void)cb;
3913 (void)pass;
3914
3915 /* Validate parameters. */
3916 if (bio == NULL) {
3917 WOLFSSL_ERROR_MSG("Bad Function Argument bio is NULL");
3918 err = 1;
3919 }
3920
3921 /* Get buffer of data from BIO or read data from the BIO into a new buffer.
3922 */
3923 if ((!err) && (wolfssl_read_bio(bio, (char**)&mem, &size, &memAlloced)
3924 != 0)) {
3925 err = 1;
3926 }
3927 if (!err) {
3928 /* Create a DH key from the PEM - try two different headers. */
3929 localDh = wolfssl_dhparams_read_pem(dh, mem, size, memAlloced);
3930 }
3931
3932 return localDh;
3933}
3934
3935#endif /* !NO_BIO */
3936
3937#ifndef NO_FILESYSTEM
3938/* Read DH parameters from a file pointer into DH key.
3939 *
3940 * DH parameters are public data and are not expected to be encrypted.
3941 *
3942 * @param [in] fp File pointer to read DH parameter file from.
3943 * @param [in, out] dh DH key with parameters if not NULL. When pointer to
3944 * NULL, a new DH key is created.
3945 * @param [in] cb Password callback when PEM encrypted. Not used.
3946 * @param [in] pass NUL terminated string for passphrase when PEM
3947 * encrypted. Not used.
3948 *
3949 * @return NULL on failure.
3950 * @return DH key with parameters set on success.
3951 */
3952WOLFSSL_DH* wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH** dh,
3953 wc_pem_password_cb* cb, void* pass)
3954{
3955 WOLFSSL_DH* localDh = NULL;
3956 int err = 0;
3957 unsigned char* mem = NULL;
3958 int size = 0;
3959
3960 (void)cb;
3961 (void)pass;
3962
3963 /* Read data from file pointer. */
3964 if (wolfssl_read_file(fp, (char**)&mem, &size) != 0) {
3965 err = 1;
3966 }
3967 if (!err) {
3968 localDh = wolfssl_dhparams_read_pem(dh, mem, size, 1);
3969 }
3970
3971 return localDh;
3972}
3973#endif /* !NO_FILESYSTEM */
3974
3975#if defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
3976/* Encoded parameter data in DH key as DER.
3977 *
3978 * @param [in, out] dh DH key object to encode.
3979 * @param [out] out Buffer containing DER encoding.
3980 * @param [in] heap Heap hint.
3981 * @return <0 on error.
3982 * @return Length of DER encoded DH parameters in bytes.
3983 */
3984static int wolfssl_dhparams_to_der(WOLFSSL_DH* dh, unsigned char** out,
3985 void* heap)
3986{
3987 int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
3988 int err = 0;
3989 byte* der = NULL;
3990 word32 derSz = 0;
3991 DhKey* key = NULL;
3992
3993 (void)heap;
3994
3995 /* Set internal parameters based on external parameters. */
3996 if ((dh->inSet == 0) && (SetDhInternal(dh) != 1)) {
3997 WOLFSSL_ERROR_MSG("Unable to set internal DH structure");
3998 err = 1;
3999 }
4000 if (!err) {
4001 /* Use wolfSSL API to get length of DER encode DH parameters. */
4002 key = (DhKey*)dh->internal;
4003 ret = wc_DhParamsToDer(key, NULL, &derSz);
4004 if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
4005 WOLFSSL_ERROR_MSG("Failed to get size of DH params");
4006 err = 1;
4007 }
4008 }
4009
4010 if (!err) {
4011 /* Allocate memory for DER encoding. */
4012 der = (byte*)XMALLOC(derSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
4013 if (der == NULL) {
4014 WOLFSSL_LEAVE("wolfssl_dhparams_to_der", MEMORY_E);
4015 err = 1;
4016 }
4017 }
4018 if (!err) {
4019 /* Encode DH parameters into DER buffer. */
4020 ret = wc_DhParamsToDer(key, der, &derSz);
4021 if (ret < 0) {
4022 WOLFSSL_ERROR_MSG("Failed to export DH params");
4023 err = 1;
4024 }
4025 }
4026
4027 if (!err) {
4028 *out = der;
4029 der = NULL;
4030 }
4031 XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER);
4032
4033 return ret;
4034}
4035
4036/* Writes the DH parameters in PEM format from "dh" out to the file pointer
4037 * passed in.
4038 *
4039 * @param [in] fp File pointer to write to.
4040 * @param [in] dh DH key to write.
4041 * @return 1 on success.
4042 * @return 0 on failure.
4043 */
4044int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh)
4045{
4046 int ret = 1;
4047 int derSz = 0;
4048 byte* derBuf = NULL;
4049 void* heap = NULL;
4050
4051 WOLFSSL_ENTER("wolfSSL_PEM_write_DHparams");
4052
4053 /* Validate parameters. */
4054 if ((fp == XBADFILE) || (dh == NULL)) {
4055 WOLFSSL_ERROR_MSG("Bad Function Arguments");
4056 ret = 0;
4057 }
4058
4059 if (ret == 1) {
4060 DhKey* key = (DhKey*)dh->internal;
4061 if (key)
4062 heap = key->heap;
4063 if ((derSz = wolfssl_dhparams_to_der(dh, &derBuf, heap)) < 0) {
4064 WOLFSSL_ERROR_MSG("DER encoding failed");
4065 ret = 0;
4066 }
4067 if (derBuf == NULL) {
4068 WOLFSSL_ERROR_MSG("DER encoding failed to get buffer");
4069 ret = 0;
4070 }
4071 }
4072 if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp,
4073 DH_PARAM_TYPE, NULL) != 1)) {
4074 ret = 0;
4075 }
4076
4077 /* Dispose of DER buffer. */
4078 XFREE(derBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
4079
4080 WOLFSSL_LEAVE("wolfSSL_PEM_write_DHparams", ret);
4081
4082 return ret;
4083}
4084#endif /* WOLFSSL_DH_EXTRA && !NO_FILESYSTEM */
4085
4086#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE ||
4087 * OPENSSL_EXTRA */
4088
4089/*
4090 * DH get/set APIs
4091 */
4092
4093#ifdef OPENSSL_EXTRA
4094
4095#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) \
4096 || defined(WOLFSSL_OPENSSH) || defined(OPENSSL_EXTRA)
4097
4098/* Set the members of DhKey into WOLFSSL_DH
4099 * Specify elements to set via the 2nd parameter
4100 *
4101 * @param [in, out] dh DH key to synchronize.
4102 * @param [in] elm Elements to synchronize.
4103 * @return 1 on success.
4104 * @return -1 on failure.
4105 */
4106int SetDhExternal_ex(WOLFSSL_DH *dh, int elm)
4107{
4108 int ret = 1;
4109 DhKey *key = NULL;
4110
4111 WOLFSSL_ENTER("SetDhExternal_ex");
4112
4113 /* Validate parameters. */
4114 if ((dh == NULL) || (dh->internal == NULL)) {
4115 WOLFSSL_ERROR_MSG("dh key NULL error");
4116 ret = WOLFSSL_FATAL_ERROR;
4117 }
4118
4119 if (ret == 1) {
4120 /* Get the wolfSSL DH key. */
4121 key = (DhKey*)dh->internal;
4122 }
4123
4124 if ((ret == 1) && (elm & ELEMENT_P)) {
4125 /* Set the prime. */
4126 if (wolfssl_bn_set_value(&dh->p, &key->p) != 1) {
4127 WOLFSSL_ERROR_MSG("dh param p error");
4128 ret = WOLFSSL_FATAL_ERROR;
4129 }
4130 }
4131 if ((ret == 1) && (elm & ELEMENT_G)) {
4132 /* Set the generator. */
4133 if (wolfssl_bn_set_value(&dh->g, &key->g) != 1) {
4134 WOLFSSL_ERROR_MSG("dh param g error");
4135 ret = WOLFSSL_FATAL_ERROR;
4136 }
4137 }
4138 if ((ret == 1) && (elm & ELEMENT_Q)) {
4139 /* Set the order. */
4140 if (wolfssl_bn_set_value(&dh->q, &key->q) != 1) {
4141 WOLFSSL_ERROR_MSG("dh param q error");
4142 ret = WOLFSSL_FATAL_ERROR;
4143 }
4144 }
4145#ifdef WOLFSSL_DH_EXTRA
4146 if ((ret == 1) && (elm & ELEMENT_PRV)) {
4147 /* Set the private key. */
4148 if (wolfssl_bn_set_value(&dh->priv_key, &key->priv) != 1) {
4149 WOLFSSL_ERROR_MSG("No DH Private Key");
4150 ret = WOLFSSL_FATAL_ERROR;
4151 }
4152 }
4153 if ((ret == 1) && (elm & ELEMENT_PUB)) {
4154 /* Set the public key. */
4155 if (wolfssl_bn_set_value(&dh->pub_key, &key->pub) != 1) {
4156 WOLFSSL_ERROR_MSG("No DH Public Key");
4157 ret = WOLFSSL_FATAL_ERROR;
4158 }
4159 }
4160#endif /* WOLFSSL_DH_EXTRA */
4161
4162 if (ret == 1) {
4163 /* On success record that the external values have been set. */
4164 dh->exSet = 1;
4165 }
4166
4167 return ret;
4168}
4169/* Set the members of DhKey into WOLFSSL_DH
4170 * DhKey was populated from wc_DhKeyDecode
4171 * p, g, pub_key and priv_key are set.
4172 *
4173 * @param [in, out] dh DH key to synchronize.
4174 * @return 1 on success.
4175 * @return -1 on failure.
4176 */
4177int SetDhExternal(WOLFSSL_DH *dh)
4178{
4179 /* Assuming Q not required when using this API. */
4180 int elements = ELEMENT_P | ELEMENT_G | ELEMENT_PUB | ELEMENT_PRV;
4181 WOLFSSL_ENTER("SetDhExternal");
4182 return SetDhExternal_ex(dh, elements);
4183}
4184#endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH || OPENSSL_EXTRA */
4185
4186/* Set the internal/wolfSSL DH key with data from the external parts.
4187 *
4188 * @param [in, out] dh DH key to synchronize.
4189 * @return 1 on success.
4190 * @return -1 on failure.
4191 */
4192int SetDhInternal(WOLFSSL_DH* dh)
4193{
4194 int ret = 1;
4195 DhKey *key = NULL;
4196
4197 WOLFSSL_ENTER("SetDhInternal");
4198
4199 /* Validate parameters. */
4200 if ((dh == NULL) || (dh->p == NULL) || (dh->g == NULL)) {
4201 WOLFSSL_ERROR_MSG("Bad function arguments");
4202 ret = WOLFSSL_FATAL_ERROR;
4203 }
4204 if (ret == 1) {
4205 /* Get the wolfSSL DH key. */
4206 key = (DhKey*)dh->internal;
4207
4208 /* Clear out key and initialize. */
4209 wc_FreeDhKey(key);
4210 if (wc_InitDhKey(key) != 0) {
4211 ret = WOLFSSL_FATAL_ERROR;
4212 }
4213 }
4214 if (ret == 1) {
4215 /* Transfer prime. */
4216 if (wolfssl_bn_get_value(dh->p, &key->p) != 1) {
4217 ret = WOLFSSL_FATAL_ERROR;
4218 }
4219 }
4220 if (ret == 1) {
4221 /* Transfer generator. */
4222 if (wolfssl_bn_get_value(dh->g, &key->g) != 1) {
4223 ret = WOLFSSL_FATAL_ERROR;
4224 }
4225 }
4226#ifdef HAVE_FFDHE_Q
4227 /* Transfer order if available. */
4228 if ((ret == 1) && (dh->q != NULL)) {
4229 if (wolfssl_bn_get_value(dh->q, &key->q) != 1) {
4230 ret = WOLFSSL_FATAL_ERROR;
4231 }
4232 }
4233#endif
4234#ifdef WOLFSSL_DH_EXTRA
4235 /* Transfer private key if available. */
4236 if ((ret == 1) && (dh->priv_key != NULL) &&
4237 (!wolfSSL_BN_is_zero(dh->priv_key))) {
4238 if (wolfssl_bn_get_value(dh->priv_key, &key->priv) != 1) {
4239 ret = WOLFSSL_FATAL_ERROR;
4240 }
4241 }
4242 /* Transfer public key if available. */
4243 if ((ret == 1) && (dh->pub_key != NULL) &&
4244 (!wolfSSL_BN_is_zero(dh->pub_key))) {
4245 if (wolfssl_bn_get_value(dh->pub_key, &key->pub) != 1) {
4246 ret = WOLFSSL_FATAL_ERROR;
4247 }
4248 }
4249#endif /* WOLFSSL_DH_EXTRA */
4250
4251 if (ret == 1) {
4252 /* On success record that the internal values have been set. */
4253 dh->inSet = 1;
4254 }
4255
4256 return ret;
4257}
4258
4259/* Get the size, in bytes, of the DH key.
4260 *
4261 * Return code compliant with OpenSSL.
4262 *
4263 * @param [in] dh DH key.
4264 * @return -1 on error.
4265 * @return Size of DH key in bytes on success.
4266 */
4267int wolfSSL_DH_size(WOLFSSL_DH* dh)
4268{
4269 WOLFSSL_ENTER("wolfSSL_DH_size");
4270
4271 if (dh == NULL)
4272 return WOLFSSL_FATAL_ERROR;
4273
4274 /* Validate parameter. */
4275 /* Size of key is size of prime in bytes. */
4276 return wolfSSL_BN_num_bytes(dh->p);
4277}
4278
4279/**
4280 * Return parameters p, q and/or g of the DH key.
4281 *
4282 * @param [in] dh DH key to retrieve parameters from.
4283 * @param [out] p Pointer to return prime in. May be NULL.
4284 * @param [out] q Pointer to return order in. May be NULL.
4285 * @param [out] g Pointer to return generator in. May be NULL.
4286 */
4287void wolfSSL_DH_get0_pqg(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **p,
4288 const WOLFSSL_BIGNUM **q, const WOLFSSL_BIGNUM **g)
4289{
4290 WOLFSSL_ENTER("wolfSSL_DH_get0_pqg");
4291
4292 if (dh != NULL) {
4293 /* Return prime if required. */
4294 if (p != NULL) {
4295 *p = dh->p;
4296 }
4297 /* Return order if required. */
4298 if (q != NULL) {
4299 *q = dh->q;
4300 }
4301 /* Return generator if required. */
4302 if (g != NULL) {
4303 *g = dh->g;
4304 }
4305 }
4306}
4307
4308#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && !defined(WOLFSSL_DH_EXTRA)) \
4309 || (defined(HAVE_FIPS_VERSION) && FIPS_VERSION_GT(2,0))
4310#if defined(OPENSSL_ALL) || \
4311 defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
4312/* Sets the parameters p, g and optionally q into the DH key.
4313 *
4314 * Ownership of p, q and g get taken over by "dh" on success and should be
4315 * free'd with a call to wolfSSL_DH_free -- not individually.
4316 *
4317 * @param [in, out] dh DH key to set.
4318 * @param [in] p Prime value to set. May be NULL when value already
4319 * present.
4320 * @param [in] q Order value to set. May be NULL.
4321 * @param [in] g Generator value to set. May be NULL when value already
4322 * present.
4323 * @return 1 on success.
4324 * @return 0 on failure.
4325 */
4326int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p,
4327 WOLFSSL_BIGNUM *q, WOLFSSL_BIGNUM *g)
4328{
4329 int ret = 1;
4330
4331 WOLFSSL_ENTER("wolfSSL_DH_set0_pqg");
4332
4333 /* Validate parameters - q is optional. */
4334 if (dh == NULL) {
4335 WOLFSSL_ERROR_MSG("Bad function arguments");
4336 ret = 0;
4337 }
4338 /* p can be NULL if we already have one set. */
4339 if ((ret == 1) && (p == NULL) && (dh->p == NULL)) {
4340 WOLFSSL_ERROR_MSG("Bad function arguments");
4341 ret = 0;
4342 }
4343 /* g can be NULL if we already have one set. */
4344 if ((ret == 1) && (g == NULL) && (dh->g == NULL)) {
4345 WOLFSSL_ERROR_MSG("Bad function arguments");
4346 ret = 0;
4347 }
4348
4349 if (ret == 1) {
4350 /* Invalidate internal key. */
4351 dh->inSet = 0;
4352
4353 /* Free external representation of parameters and set with those passed
4354 * in. */
4355 if (p != NULL) {
4356 wolfSSL_BN_free(dh->p);
4357 dh->p = p;
4358 }
4359 if (q != NULL) {
4360 wolfSSL_BN_free(dh->q);
4361 dh->q = q;
4362 }
4363 if (g != NULL) {
4364 wolfSSL_BN_free(dh->g);
4365 dh->g = g;
4366 }
4367 /* External DH key parameters were set. */
4368 dh->exSet = 1;
4369
4370 /* Set internal/wolfSSL DH key as well. */
4371 if (SetDhInternal(dh) != 1) {
4372 WOLFSSL_ERROR_MSG("Unable to set internal DH key");
4373 /* Don't keep parameters on failure. */
4374 dh->p = NULL;
4375 dh->q = NULL;
4376 dh->g = NULL;
4377 /* Internal and external DH key not set. */
4378 dh->inSet = 0;
4379 dh->exSet = 0;
4380 ret = 0;
4381 }
4382 }
4383
4384 return ret;
4385}
4386
4387/* Set the length of the DH private key in bits.
4388 *
4389 * Length field is checked at generation.
4390 *
4391 * @param [in, out] dh DH key to set.
4392 * @param [in] len Length of DH private key in bytes.
4393 * @return 0 on failure.
4394 * @return 1 on success.
4395 */
4396int wolfSSL_DH_set_length(WOLFSSL_DH *dh, long len)
4397{
4398 int ret = 1;
4399
4400 WOLFSSL_ENTER("wolfSSL_DH_set_length");
4401
4402 /* Validate parameter. */
4403 if (dh == NULL) {
4404 WOLFSSL_ERROR_MSG("Bad function arguments");
4405 ret = 0;
4406 }
4407 else {
4408 /* Store length. */
4409 dh->length = (int)len;
4410 }
4411
4412 return ret;
4413}
4414#endif /* OPENSSL_ALL || (v1.1.0 or later) */
4415#endif
4416
4417/* Get the public and private keys requested.
4418 *
4419 * @param [in] dh DH key to get keys from.
4420 * @param [out] pub_key Pointer to return public key in. May be NULL.
4421 * @param [out] priv_key Pointer to return private key in. May be NULL.
4422 */
4423void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **pub_key,
4424 const WOLFSSL_BIGNUM **priv_key)
4425{
4426 WOLFSSL_ENTER("wolfSSL_DH_get0_key");
4427
4428 /* Get only when valid DH passed in. */
4429 if (dh != NULL) {
4430 /* Return public key if required and available. */
4431 if ((pub_key != NULL) && (dh->pub_key != NULL)) {
4432 *pub_key = dh->pub_key;
4433 }
4434 /* Return private key if required and available. */
4435 if ((priv_key != NULL) && (dh->priv_key != NULL)) {
4436 *priv_key = dh->priv_key;
4437 }
4438 }
4439}
4440
4441/* Set the public and/or private key.
4442 *
4443 * @param [in, out] dh DH key to have keys set into.
4444 * @param [in] pub_key Public key to set. May be NULL.
4445 * @param [in] priv_key Private key to set. May be NULL.
4446 * @return 0 on failure.
4447 * @return 1 on success.
4448 */
4449int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key,
4450 WOLFSSL_BIGNUM *priv_key)
4451{
4452 int ret = 1;
4453#ifdef WOLFSSL_DH_EXTRA
4454 DhKey *key = NULL;
4455#endif
4456
4457 WOLFSSL_ENTER("wolfSSL_DH_set0_key");
4458
4459 /* Validate parameters. */
4460 if (dh == NULL) {
4461 ret = 0;
4462 }
4463#ifdef WOLFSSL_DH_EXTRA
4464 else {
4465 key = (DhKey*)dh->internal;
4466 }
4467#endif
4468
4469 /* Replace public key when one passed in. */
4470 if ((ret == 1) && (pub_key != NULL)) {
4471 wolfSSL_BN_free(dh->pub_key);
4472 dh->pub_key = pub_key;
4473 #ifdef WOLFSSL_DH_EXTRA
4474 if (wolfssl_bn_get_value(dh->pub_key, &key->pub) != 1) {
4475 ret = 0;
4476 }
4477 #endif
4478 }
4479
4480 /* Replace private key when one passed in. */
4481 if ((ret == 1) && (priv_key != NULL)) {
4482 wolfSSL_BN_clear_free(dh->priv_key);
4483 dh->priv_key = priv_key;
4484 #ifdef WOLFSSL_DH_EXTRA
4485 if (wolfssl_bn_get_value(dh->priv_key, &key->priv) != 1) {
4486 ret = 0;
4487 }
4488 #endif
4489 }
4490
4491 return ret;
4492}
4493
4494#endif /* OPENSSL_EXTRA */
4495
4496/*
4497 * DH check APIs
4498 */
4499
4500#ifdef OPENSSL_EXTRA
4501
4502#ifndef NO_CERTS
4503
4504#ifdef OPENSSL_ALL
4505/* Check whether BN number is a prime.
4506 *
4507 * @param [in] n Number to check.
4508 * @param [out] isPrime MP_YES when prime and MP_NO when not.
4509 * @return 1 on success.
4510 * @return 0 on error.
4511 */
4512static int wolfssl_dh_check_prime(WOLFSSL_BIGNUM* n, int* isPrime)
4513{
4514 int ret = 1;
4515 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
4516 WC_RNG* rng;
4517 int localRng;
4518
4519 /* Make an RNG with tmpRng or get global. */
4520 rng = wolfssl_make_rng(tmpRng, &localRng);
4521 if (rng == NULL) {
4522 ret = 0;
4523 }
4524 if (ret == 1) {
4525 mp_int* prime = (mp_int*)n->internal;
4526
4527 if (mp_prime_is_prime_ex(prime, 8, isPrime, rng) != 0) {
4528 ret = 0;
4529 }
4530 /* Free local random number generator if created. */
4531 if (localRng) {
4532 wc_FreeRng(rng);
4533 WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4534 }
4535 }
4536
4537 return ret;
4538}
4539
4540/* Checks the Diffie-Hellman parameters.
4541 *
4542 * Checks that the generator and prime are available.
4543 * Checks that the prime is prime.
4544 * OpenSSL expects codes to be non-NULL.
4545 *
4546 * @param [in] dh DH key to check.
4547 * @param [out] codes Codes of checks that failed.
4548 * @return 1 on success.
4549 * @return 0 when DH is NULL, there were errors or failed to create a random
4550 * number generator.
4551 */
4552int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes)
4553{
4554 int ret = 1;
4555 int errors = 0;
4556
4557 WOLFSSL_ENTER("wolfSSL_DH_check");
4558
4559 /* Validate parameters. */
4560 if (dh == NULL) {
4561 ret = 0;
4562 }
4563
4564 /* Check generator available. */
4565 if ((ret == 1) && ((dh->g == NULL) || (dh->g->internal == NULL))) {
4566 errors |= DH_NOT_SUITABLE_GENERATOR;
4567 }
4568
4569 if (ret == 1) {
4570 /* Check prime available. */
4571 if ((dh->p == NULL) || (dh->p->internal == NULL)) {
4572 errors |= DH_CHECK_P_NOT_PRIME;
4573 }
4574 else {
4575 /* Test if dh->p is prime. */
4576 int isPrime = MP_NO;
4577 ret = wolfssl_dh_check_prime(dh->p, &isPrime);
4578 /* Set error code if parameter p is not prime. */
4579 if ((ret == 1) && (isPrime != MP_YES)) {
4580 errors |= DH_CHECK_P_NOT_PRIME;
4581 }
4582 }
4583 }
4584
4585 /* Return errors when user wants exact issues. */
4586 if (codes != NULL) {
4587 *codes = errors;
4588 }
4589 else if (errors) {
4590 ret = 0;
4591 }
4592
4593 return ret;
4594}
4595
4596#endif /* OPENSSL_ALL */
4597
4598#endif /* !NO_CERTS */
4599
4600#endif /* OPENSSL_EXTRA */
4601
4602/*
4603 * DH generate APIs
4604 */
4605
4606#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
4607 (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
4608 defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
4609 defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
4610
4611#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_SELFTEST)
4612/* Generate DH parameters.
4613 *
4614 * @param [in] prime_len Length of prime in bits.
4615 * @param [in] generator Generator value to use.
4616 * @param [in] callback Called with progress information. Unused.
4617 * @param [in] cb_arg User callback argument. Unused.
4618 * @return NULL on failure.
4619 * @return DH key on success.
4620 */
4621WOLFSSL_DH *wolfSSL_DH_generate_parameters(int prime_len, int generator,
4622 void (*callback) (int, int, void *), void *cb_arg)
4623{
4624 WOLFSSL_DH* dh = NULL;
4625
4626 WOLFSSL_ENTER("wolfSSL_DH_generate_parameters");
4627 /* Not supported by wolfSSl APIs. */
4628 (void)callback;
4629 (void)cb_arg;
4630
4631 /* Create an empty DH key. */
4632 if ((dh = wolfSSL_DH_new()) == NULL) {
4633 WOLFSSL_ERROR_MSG("wolfSSL_DH_new error");
4634 }
4635 /* Generate parameters into DH key. */
4636 else if (wolfSSL_DH_generate_parameters_ex(dh, prime_len, generator, NULL)
4637 != 1) {
4638 WOLFSSL_ERROR_MSG("wolfSSL_DH_generate_parameters_ex error");
4639 wolfSSL_DH_free(dh);
4640 dh = NULL;
4641 }
4642
4643 return dh;
4644}
4645
4646/* Generate DH parameters.
4647 *
4648 * @param [in] dh DH key to generate parameters into.
4649 * @param [in] prime_len Length of prime in bits.
4650 * @param [in] generator Generator value to use.
4651 * @param [in] callback Called with progress information. Unused.
4652 * @param [in] cb_arg User callback argument. Unused.
4653 * @return 0 on failure.
4654 * @return 1 on success.
4655 */
4656int wolfSSL_DH_generate_parameters_ex(WOLFSSL_DH* dh, int prime_len,
4657 int generator, void (*callback) (int, int, void *))
4658{
4659 int ret = 1;
4660 DhKey* key = NULL;
4661 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
4662 WC_RNG* rng = NULL;
4663 int localRng = 0;
4664
4665 WOLFSSL_ENTER("wolfSSL_DH_generate_parameters_ex");
4666 /* Not supported by wolfSSL APIs. */
4667 (void)callback;
4668 (void)generator;
4669
4670 /* Validate parameters. */
4671 if (dh == NULL) {
4672 WOLFSSL_ERROR_MSG("Bad parameter");
4673 ret = 0;
4674 }
4675
4676 if (ret == 1) {
4677 /* Make an RNG with tmpRng or get global. */
4678 rng = wolfssl_make_rng(tmpRng, &localRng);
4679 if (rng == NULL) {
4680 WOLFSSL_ERROR_MSG("No RNG to use");
4681 ret = 0;
4682 }
4683 }
4684
4685 if (ret == 1) {
4686 /* Get internal/wolfSSL DH key. */
4687 key = (DhKey*)dh->internal;
4688
4689 /* Clear out data from internal DH key. */
4690 wc_FreeDhKey(key);
4691 /* Re-initialize internal DH key. */
4692 if (wc_InitDhKey(key) != 0) {
4693 ret = 0;
4694 }
4695 }
4696 if (ret == 1) {
4697 /* Generate parameters into internal DH key. */
4698 if (wc_DhGenerateParams(rng, prime_len, key) != 0) {
4699 WOLFSSL_ERROR_MSG("wc_DhGenerateParams error");
4700 ret = 0;
4701 }
4702 }
4703
4704 /* Free local random number generator if created. */
4705 if (localRng) {
4706 wc_FreeRng(rng);
4707 WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER);
4708 }
4709
4710 if (ret == 1) {
4711 /* Internal parameters set by generation. */
4712 dh->inSet = 1;
4713
4714 WOLFSSL_MSG("wolfSSL does not support using a custom generator.");
4715
4716 /* Synchronize the external to the internal parameters. */
4717 if (SetDhExternal(dh) != 1) {
4718 WOLFSSL_ERROR_MSG("SetDhExternal error");
4719 ret = 0;
4720 }
4721 }
4722
4723 return ret;
4724}
4725#endif /* WOLFSSL_KEY_GEN && !HAVE_SELFTEST */
4726
4727#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
4728 * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
4729 * HAVE_SBLIM_SFCB)) */
4730
4731#ifdef OPENSSL_EXTRA
4732
4733#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS) && !defined(WOLFSSL_DH_EXTRA)) \
4734 || (defined(HAVE_FIPS_VERSION) && FIPS_VERSION_GT(2,0))
4735/* Generate a public/private key pair base on parameters.
4736 *
4737 * @param [in, out] dh DH key to generate keys into.
4738 * @return 1 on success.
4739 * @return 0 on error.
4740 */
4741int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
4742{
4743 int ret = 1;
4744 word32 pubSz = 0;
4745 word32 privSz = 0;
4746 word32 privAllocSz = 0;
4747 int localRng = 0;
4748 WC_RNG* rng = NULL;
4749 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
4750 unsigned char* pub = NULL;
4751 unsigned char* priv = NULL;
4752
4753 WOLFSSL_ENTER("wolfSSL_DH_generate_key");
4754
4755 /* Validate parameters. */
4756 if ((dh == NULL) || (dh->p == NULL) || (dh->g == NULL)) {
4757 WOLFSSL_ERROR_MSG("Bad function arguments");
4758 ret = 0;
4759 }
4760
4761 /* Synchronize the external and internal parameters. */
4762 if ((ret == 1) && (dh->inSet == 0) && (SetDhInternal(dh) != 1)) {
4763 WOLFSSL_ERROR_MSG("Bad DH set internal");
4764 ret = 0;
4765 }
4766
4767 if (ret == 1) {
4768 /* Make a new RNG or use global. */
4769 rng = wolfssl_make_rng(tmpRng, &localRng);
4770 /* Check we have a random number generator. */
4771 if (rng == NULL) {
4772 ret = 0;
4773 }
4774 }
4775
4776 if (ret == 1) {
4777 /* Get the size of the prime in bytes. */
4778 pubSz = (word32)wolfSSL_BN_num_bytes(dh->p);
4779 if (pubSz == 0) {
4780 WOLFSSL_ERROR_MSG("Prime parameter invalid");
4781 ret = 0;
4782 }
4783 }
4784 if (ret == 1) {
4785 /* Private key size can be as much as the size of the prime. */
4786 if (dh->length) {
4787 privSz = (word32)(dh->length / 8); /* to bytes */
4788 /* Special case where priv key is larger than dh->length / 8
4789 * See GeneratePrivateDh */
4790 if (dh->length == 128)
4791 privSz = 21;
4792 }
4793 else {
4794 privSz = pubSz;
4795 }
4796 /* Allocate public and private key arrays. Preserve the allocation
4797 * size because wc_DhGenerateKeyPair updates privSz in-place. */
4798 privAllocSz = privSz;
4799 pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
4800 priv = (unsigned char*)XMALLOC(privAllocSz, NULL,
4801 DYNAMIC_TYPE_PRIVATE_KEY);
4802 if (pub == NULL || priv == NULL) {
4803 WOLFSSL_ERROR_MSG("Unable to malloc memory");
4804 ret = 0;
4805 }
4806 }
4807 if (ret == 1) {
4808 /* Dispose of old public and private keys. */
4809 wolfSSL_BN_free(dh->pub_key);
4810 wolfSSL_BN_free(dh->priv_key);
4811
4812 /* Allocate new public and private keys. */
4813 dh->pub_key = wolfSSL_BN_new();
4814 dh->priv_key = wolfSSL_BN_new();
4815 if (dh->pub_key == NULL) {
4816 WOLFSSL_ERROR_MSG("Bad DH new pub");
4817 ret = 0;
4818 }
4819 if (dh->priv_key == NULL) {
4820 WOLFSSL_ERROR_MSG("Bad DH new priv");
4821 ret = 0;
4822 }
4823 }
4824
4825 PRIVATE_KEY_UNLOCK();
4826 /* Generate public and private keys into arrays. */
4827 if ((ret == 1) && (wc_DhGenerateKeyPair((DhKey*)dh->internal, rng, priv,
4828 &privSz, pub, &pubSz) < 0)) {
4829 WOLFSSL_ERROR_MSG("Bad wc_DhGenerateKeyPair");
4830 ret = 0;
4831 }
4832 /* Set public key from array. */
4833 if ((ret == 1) && (wolfSSL_BN_bin2bn(pub, (int)pubSz, dh->pub_key) ==
4834 NULL)) {
4835 WOLFSSL_ERROR_MSG("Bad DH bn2bin error pub");
4836 ret = 0;
4837 }
4838 /* Set private key from array. */
4839 if ((ret == 1) && (wolfSSL_BN_bin2bn(priv, (int)privSz, dh->priv_key) ==
4840 NULL)) {
4841 WOLFSSL_ERROR_MSG("Bad DH bn2bin error priv");
4842 ret = 0;
4843 }
4844 PRIVATE_KEY_LOCK();
4845
4846 if (localRng) {
4847 /* Free an initialized local random number generator. */
4848 wc_FreeRng(rng);
4849 WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
4850 }
4851 /* Dispose of allocated data. */
4852 XFREE(pub, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
4853 if (priv != NULL) {
4854 ForceZero(priv, privAllocSz);
4855 XFREE(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
4856 }
4857
4858 return ret;
4859}
4860
4861
4862static int _DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
4863 WOLFSSL_DH* dh, int ct)
4864{
4865 int ret = 0;
4866 word32 keySz = 0;
4867 int pubSz = MAX_DHKEY_SZ;
4868 int privSz = MAX_DHKEY_SZ;
4869 int sz = 0;
4870#ifdef WOLFSSL_SMALL_STACK
4871 unsigned char* pub = NULL;
4872 unsigned char* priv = NULL;
4873#else
4874 unsigned char pub [MAX_DHKEY_SZ];
4875 unsigned char priv[MAX_DHKEY_SZ];
4876#endif
4877
4878 WOLFSSL_ENTER("wolfSSL_DH_compute_key");
4879
4880 /* Validate parameters. */
4881 if ((dh == NULL) || (dh->priv_key == NULL) || (otherPub == NULL)) {
4882 WOLFSSL_ERROR_MSG("Bad function arguments");
4883 ret = WOLFSSL_FATAL_ERROR;
4884 }
4885 /* Get the maximum size of computed DH key. */
4886 if ((ret == 0) && ((keySz = (word32)wolfSSL_DH_size(dh)) == 0)) {
4887 WOLFSSL_ERROR_MSG("Bad DH_size");
4888 ret = WOLFSSL_FATAL_ERROR;
4889 }
4890 if (ret == 0) {
4891 /* Validate the size of the private key. */
4892 sz = wolfSSL_BN_num_bytes(dh->priv_key);
4893 if (sz > privSz) {
4894 WOLFSSL_ERROR_MSG("Bad priv internal size");
4895 ret = WOLFSSL_FATAL_ERROR;
4896 }
4897 }
4898 if (ret == 0) {
4899 #ifdef WOLFSSL_SMALL_STACK
4900 /* Keep real private key size to minimize amount allocated. */
4901 privSz = sz;
4902 #endif
4903
4904 /* Validate the size of the public key. */
4905 sz = wolfSSL_BN_num_bytes(otherPub);
4906 if (sz > pubSz) {
4907 WOLFSSL_ERROR_MSG("Bad otherPub size");
4908 ret = WOLFSSL_FATAL_ERROR;
4909 }
4910 }
4911
4912 if (ret == 0) {
4913 #ifdef WOLFSSL_SMALL_STACK
4914 /* Allocate memory for the public key array. */
4915 pub = (unsigned char*)XMALLOC((size_t)sz, NULL,
4916 DYNAMIC_TYPE_PUBLIC_KEY);
4917 if (pub == NULL)
4918 ret = WOLFSSL_FATAL_ERROR;
4919 }
4920 if (ret == 0) {
4921 /* Allocate memory for the private key array. */
4922 priv = (unsigned char*)XMALLOC((size_t)privSz, NULL,
4923 DYNAMIC_TYPE_PRIVATE_KEY);
4924 if (priv == NULL) {
4925 ret = WOLFSSL_FATAL_ERROR;
4926 }
4927 }
4928 if (ret == 0) {
4929 #endif
4930 /* Get the private key into the array. */
4931 privSz = wolfSSL_BN_bn2bin(dh->priv_key, priv);
4932 if (privSz <= 0) {
4933 ret = WOLFSSL_FATAL_ERROR;
4934 }
4935 }
4936 if (ret == 0) {
4937 /* Get the public key into the array. */
4938 pubSz = wolfSSL_BN_bn2bin(otherPub, pub);
4939 if (pubSz <= 0) {
4940 ret = WOLFSSL_FATAL_ERROR;
4941 }
4942 }
4943 /* Synchronize the external into the internal parameters. */
4944 if ((ret == 0) && ((dh->inSet == 0) && (SetDhInternal(dh) != 1))) {
4945 WOLFSSL_ERROR_MSG("Bad DH set internal");
4946 ret = WOLFSSL_FATAL_ERROR;
4947 }
4948
4949 PRIVATE_KEY_UNLOCK();
4950 /* Calculate shared secret from private and public keys. */
4951 if (ret == 0) {
4952 word32 padded_keySz = keySz;
4953#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0)) && !defined(HAVE_SELFTEST)
4954 if (ct) {
4955 if (wc_DhAgree_ct((DhKey*)dh->internal, key, &keySz, priv,
4956 (word32)privSz, pub, (word32)pubSz) < 0) {
4957 WOLFSSL_ERROR_MSG("wc_DhAgree_ct failed");
4958 ret = WOLFSSL_FATAL_ERROR;
4959 }
4960 }
4961 else
4962#endif /* (!HAVE_FIPS || FIPS_VERSION_GE(7,0)) && !HAVE_SELFTEST */
4963 {
4964 if (wc_DhAgree((DhKey*)dh->internal, key, &keySz, priv,
4965 (word32)privSz, pub, (word32)pubSz) < 0) {
4966 WOLFSSL_ERROR_MSG("wc_DhAgree failed");
4967 ret = WOLFSSL_FATAL_ERROR;
4968 }
4969 }
4970
4971 if ((ret == 0) && ct) {
4972 /* Arrange for correct fixed-length, right-justified key, even if
4973 * the crypto back end doesn't support it. With some crypto back
4974 * ends this forgoes formal constant-timeness on the key agreement,
4975 * but assured that wolfSSL_DH_compute_key_padded() functions
4976 * correctly.
4977 */
4978 if (keySz < padded_keySz) {
4979 XMEMMOVE(key, key + (padded_keySz - keySz),
4980 padded_keySz - keySz);
4981 XMEMSET(key, 0, padded_keySz - keySz);
4982 keySz = padded_keySz;
4983 }
4984 }
4985 }
4986 if (ret == 0) {
4987 /* Return actual length. */
4988 ret = (int)keySz;
4989 }
4990 PRIVATE_KEY_LOCK();
4991
4992 if (privSz > 0) {
4993#ifdef WOLFSSL_SMALL_STACK
4994 if (priv != NULL)
4995#endif
4996 {
4997 /* Zeroize sensitive data. */
4998 ForceZero(priv, (word32)privSz);
4999 }
5000 }
5001 WC_FREE_VAR_EX(pub, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
5002 WC_FREE_VAR_EX(priv, NULL, DYNAMIC_TYPE_PRIVATE_KEY);
5003
5004 WOLFSSL_LEAVE("wolfSSL_DH_compute_key", ret);
5005
5006 return ret;
5007}
5008
5009/* Compute the shared key from the private key and peer's public key.
5010 *
5011 * Return code compliant with OpenSSL.
5012 * OpenSSL returns 0 when number of bits in p are smaller than minimum
5013 * supported.
5014 *
5015 * @param [out] key Buffer to place shared key.
5016 * @param [in] otherPub Peer's public key.
5017 * @param [in] dh DH key containing private key.
5018 * @return -1 on error.
5019 * @return Size of shared secret in bytes on success.
5020 */
5021int wolfSSL_DH_compute_key(unsigned char* key, const WOLFSSL_BIGNUM* otherPub,
5022 WOLFSSL_DH* dh)
5023{
5024 return _DH_compute_key(key, otherPub, dh, 0);
5025}
5026
5027/* Compute the shared key from the private key and peer's public key as in
5028 * wolfSSL_DH_compute_key, but using constant time processing, with an output
5029 * key length fixed at the nominal DH key size. Leading zeros are retained.
5030 *
5031 * Return code compliant with OpenSSL.
5032 * OpenSSL returns 0 when number of bits in p are smaller than minimum
5033 * supported.
5034 *
5035 * @param [out] key Buffer to place shared key.
5036 * @param [in] otherPub Peer's public key.
5037 * @param [in] dh DH key containing private key.
5038 * @return -1 on error.
5039 * @return Size of shared secret in bytes on success.
5040 */
5041int wolfSSL_DH_compute_key_padded(unsigned char* key,
5042 const WOLFSSL_BIGNUM* otherPub, WOLFSSL_DH* dh)
5043{
5044 return _DH_compute_key(key, otherPub, dh, 1);
5045}
5046
5047#endif /* !HAVE_FIPS || (HAVE_FIPS && !WOLFSSL_DH_EXTRA) ||
5048 * HAVE_FIPS_VERSION > 2 */
5049
5050#endif /* OPENSSL_EXTRA */
5051
5052#endif /* NO_DH */
5053
5054/*******************************************************************************
5055 * END OF DH API
5056 ******************************************************************************/
5057
5058
5059#define WOLFSSL_PK_EC_INCLUDED
5060#include "src/pk_ec.c"
5061
5062
5063/*******************************************************************************
5064 * START OF EC25519 API
5065 ******************************************************************************/
5066
5067#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
5068
5069/* Generate an EC25519 key pair.
5070 *
5071 * Output keys are in little endian format.
5072 *
5073 * @param [out] priv EC25519 private key data.
5074 * @param [in, out] privSz On in, the size of priv in bytes.
5075 * On out, the length of the private key data in bytes.
5076 * @param [out] pub EC25519 public key data.
5077 * @param [in, out] pubSz On in, the size of pub in bytes.
5078 * On out, the length of the public key data in bytes.
5079 * @return 1 on success
5080 * @return 0 on failure.
5081 */
5082int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
5083 unsigned char *pub, unsigned int *pubSz)
5084{
5085#ifdef WOLFSSL_KEY_GEN
5086 int res = 1;
5087 int initTmpRng = 0;
5088 WC_RNG *rng = NULL;
5089 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5090 curve25519_key key;
5091
5092 WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
5093
5094 /* Validate parameters. */
5095 if ((priv == NULL) || (privSz == NULL) || (*privSz < CURVE25519_KEYSIZE) ||
5096 (pub == NULL) || (pubSz == NULL) || (*pubSz < CURVE25519_KEYSIZE)) {
5097 WOLFSSL_MSG("Bad arguments");
5098 res = 0;
5099 }
5100
5101 if (res) {
5102 /* Create a random number generator. */
5103 rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5104 if (rng == NULL) {
5105 WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5106 res = 0;
5107 }
5108 }
5109
5110 /* Initialize a Curve25519 key. */
5111 if (res && (wc_curve25519_init(&key) != 0)) {
5112 WOLFSSL_MSG("wc_curve25519_init failed");
5113 res = 0;
5114 }
5115 if (res) {
5116 /* Make a Curve25519 key pair. */
5117 int ret = wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key);
5118 if (ret != MP_OKAY) {
5119 WOLFSSL_MSG("wc_curve25519_make_key failed");
5120 res = 0;
5121 }
5122 if (res) {
5123 /* Export Curve25519 key pair to buffers. */
5124 ret = wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
5125 pubSz, EC25519_LITTLE_ENDIAN);
5126 if (ret != MP_OKAY) {
5127 WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
5128 res = 0;
5129 }
5130 }
5131
5132 /* Dispose of key. */
5133 wc_curve25519_free(&key);
5134 }
5135
5136 if (initTmpRng) {
5137 wc_FreeRng(rng);
5138 WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5139 }
5140
5141 return res;
5142#else
5143 WOLFSSL_MSG("No Key Gen built in");
5144
5145 (void)priv;
5146 (void)privSz;
5147 (void)pub;
5148 (void)pubSz;
5149
5150 return 0;
5151#endif /* WOLFSSL_KEY_GEN */
5152}
5153
5154/* Compute a shared secret from private and public EC25519 keys.
5155 *
5156 * Input and output keys are in little endian format
5157 *
5158 * @param [out] shared Shared secret buffer.
5159 * @param [in, out] sharedSz On in, the size of shared in bytes.
5160 * On out, the length of the secret in bytes.
5161 * @param [in] priv EC25519 private key data.
5162 * @param [in] privSz Length of the private key data in bytes.
5163 * @param [in] pub EC25519 public key data.
5164 * @param [in] pubSz Length of the public key data in bytes.
5165 * @return 1 on success
5166 * @return 0 on failure.
5167 */
5168int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
5169 const unsigned char *priv, unsigned int privSz, const unsigned char *pub,
5170 unsigned int pubSz)
5171{
5172#ifdef WOLFSSL_KEY_GEN
5173 int res = 1;
5174 curve25519_key privkey;
5175 curve25519_key pubkey;
5176
5177 WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
5178
5179 /* Validate parameters. */
5180 if ((shared == NULL) || (sharedSz == NULL) ||
5181 (*sharedSz < CURVE25519_KEYSIZE) || (priv == NULL) ||
5182 (privSz < CURVE25519_KEYSIZE) || (pub == NULL) ||
5183 (pubSz < CURVE25519_KEYSIZE)) {
5184 WOLFSSL_MSG("Bad arguments");
5185 res = 0;
5186 }
5187
5188 /* Initialize private key object. */
5189 if (res && (wc_curve25519_init(&privkey) != 0)) {
5190 WOLFSSL_MSG("wc_curve25519_init privkey failed");
5191 res = 0;
5192 }
5193 if (res) {
5194 #ifdef WOLFSSL_CURVE25519_BLINDING
5195 /* An RNG is needed. */
5196 if (wc_curve25519_set_rng(&privkey, wolfssl_make_global_rng()) != 0) {
5197 res = 0;
5198 }
5199 else
5200 #endif
5201 /* Initialize public key object. */
5202 if (wc_curve25519_init(&pubkey) != MP_OKAY) {
5203 WOLFSSL_MSG("wc_curve25519_init pubkey failed");
5204 res = 0;
5205 }
5206 if (res) {
5207 /* Import our private key. */
5208 int ret = wc_curve25519_import_private_ex(priv, privSz, &privkey,
5209 EC25519_LITTLE_ENDIAN);
5210 if (ret != 0) {
5211 WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
5212 res = 0;
5213 }
5214
5215 if (res) {
5216 /* Import peer's public key. */
5217 ret = wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
5218 EC25519_LITTLE_ENDIAN);
5219 if (ret != 0) {
5220 WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
5221 res = 0;
5222 }
5223 }
5224 if (res) {
5225 /* Compute shared secret. */
5226 ret = wc_curve25519_shared_secret_ex(&privkey, &pubkey, shared,
5227 sharedSz, EC25519_LITTLE_ENDIAN);
5228 if (ret != 0) {
5229 WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
5230 res = 0;
5231 }
5232 }
5233
5234 wc_curve25519_free(&pubkey);
5235 }
5236 wc_curve25519_free(&privkey);
5237 }
5238
5239 return res;
5240#else
5241 WOLFSSL_MSG("No Key Gen built in");
5242
5243 (void)shared;
5244 (void)sharedSz;
5245 (void)priv;
5246 (void)privSz;
5247 (void)pub;
5248 (void)pubSz;
5249
5250 return 0;
5251#endif /* WOLFSSL_KEY_GEN */
5252}
5253#endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
5254
5255/*******************************************************************************
5256 * END OF EC25519 API
5257 ******************************************************************************/
5258
5259/*******************************************************************************
5260 * START OF ED25519 API
5261 ******************************************************************************/
5262
5263#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
5264/* Generate an ED25519 key pair.
5265 *
5266 * Output keys are in little endian format.
5267 *
5268 * @param [out] priv ED25519 private key data.
5269 * @param [in, out] privSz On in, the size of priv in bytes.
5270 * On out, the length of the private key data in bytes.
5271 * @param [out] pub ED25519 public key data.
5272 * @param [in, out] pubSz On in, the size of pub in bytes.
5273 * On out, the length of the public key data in bytes.
5274 * @return 1 on success
5275 * @return 0 on failure.
5276 */
5277int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
5278 unsigned char *pub, unsigned int *pubSz)
5279{
5280#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED25519_KEY_EXPORT)
5281 int res = 1;
5282 int initTmpRng = 0;
5283 WC_RNG *rng = NULL;
5284 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5285 ed25519_key key;
5286
5287 WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
5288
5289 /* Validate parameters. */
5290 if ((priv == NULL) || (privSz == NULL) ||
5291 (*privSz < ED25519_PRV_KEY_SIZE) || (pub == NULL) ||
5292 (pubSz == NULL) || (*pubSz < ED25519_PUB_KEY_SIZE)) {
5293 WOLFSSL_MSG("Bad arguments");
5294 res = 0;
5295 }
5296
5297 if (res) {
5298 /* Create a random number generator. */
5299 rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5300 if (rng == NULL) {
5301 WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5302 res = 0;
5303 }
5304 }
5305
5306 /* Initialize an Ed25519 key. */
5307 if (res && (wc_ed25519_init(&key) != 0)) {
5308 WOLFSSL_MSG("wc_ed25519_init failed");
5309 res = 0;
5310 }
5311 if (res) {
5312 /* Make an Ed25519 key pair. */
5313 int ret = wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key);
5314 if (ret != 0) {
5315 WOLFSSL_MSG("wc_ed25519_make_key failed");
5316 res = 0;
5317 }
5318 if (res) {
5319 /* Export Curve25519 key pair to buffers. */
5320 ret = wc_ed25519_export_key(&key, priv, privSz, pub, pubSz);
5321 if (ret != 0) {
5322 WOLFSSL_MSG("wc_ed25519_export_key failed");
5323 res = 0;
5324 }
5325 }
5326
5327 wc_ed25519_free(&key);
5328 }
5329
5330 if (initTmpRng) {
5331 wc_FreeRng(rng);
5332 WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5333 }
5334
5335 return res;
5336#else
5337#ifndef WOLFSSL_KEY_GEN
5338 WOLFSSL_MSG("No Key Gen built in");
5339#else
5340 WOLFSSL_MSG("No ED25519 key export built in");
5341#endif
5342
5343 (void)priv;
5344 (void)privSz;
5345 (void)pub;
5346 (void)pubSz;
5347
5348 return 0;
5349#endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
5350}
5351
5352/* Sign a message with Ed25519 using the private key.
5353 *
5354 * Input and output keys are in little endian format.
5355 * Priv is a buffer containing private and public part of key.
5356 *
5357 * @param [in] msg Message to be signed.
5358 * @param [in] msgSz Length of message in bytes.
5359 * @param [in] priv ED25519 private key data.
5360 * @param [in] privSz Length in bytes of private key data.
5361 * @param [out] sig Signature buffer.
5362 * @param [in, out] sigSz On in, the length of the signature buffer in bytes.
5363 * On out, the length of the signature in bytes.
5364 * @return 1 on success
5365 * @return 0 on failure.
5366 */
5367int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
5368 const unsigned char *priv, unsigned int privSz, unsigned char *sig,
5369 unsigned int *sigSz)
5370{
5371#if defined(HAVE_ED25519_SIGN) && defined(WOLFSSL_KEY_GEN) && \
5372 defined(HAVE_ED25519_KEY_IMPORT)
5373 ed25519_key key;
5374 int res = 1;
5375
5376 WOLFSSL_ENTER("wolfSSL_ED25519_sign");
5377
5378 /* Validate parameters. */
5379 if ((priv == NULL) || (privSz != ED25519_PRV_KEY_SIZE) ||
5380 (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
5381 (*sigSz < ED25519_SIG_SIZE)) {
5382 WOLFSSL_MSG("Bad arguments");
5383 res = 0;
5384 }
5385
5386 /* Initialize Ed25519 key. */
5387 if (res && (wc_ed25519_init(&key) != 0)) {
5388 WOLFSSL_MSG("wc_curve25519_init failed");
5389 res = 0;
5390 }
5391 if (res) {
5392 /* Import private and public key. */
5393 int ret = wc_ed25519_import_private_key(priv, privSz / 2,
5394 priv + (privSz / 2), ED25519_PUB_KEY_SIZE, &key);
5395 if (ret != 0) {
5396 WOLFSSL_MSG("wc_ed25519_import_private failed");
5397 res = 0;
5398 }
5399
5400 if (res) {
5401 /* Sign message with Ed25519. */
5402 ret = wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key);
5403 if (ret != 0) {
5404 WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
5405 res = 0;
5406 }
5407 }
5408
5409 wc_ed25519_free(&key);
5410 }
5411
5412 return res;
5413#else
5414#if !defined(HAVE_ED25519_SIGN)
5415 WOLFSSL_MSG("No ED25519 sign built in");
5416#elif !defined(WOLFSSL_KEY_GEN)
5417 WOLFSSL_MSG("No Key Gen built in");
5418#elif !defined(HAVE_ED25519_KEY_IMPORT)
5419 WOLFSSL_MSG("No ED25519 Key import built in");
5420#endif
5421
5422 (void)msg;
5423 (void)msgSz;
5424 (void)priv;
5425 (void)privSz;
5426 (void)sig;
5427 (void)sigSz;
5428
5429 return 0;
5430#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
5431}
5432
5433/* Verify a message with Ed25519 using the public key.
5434 *
5435 * Input keys are in little endian format.
5436 *
5437 * @param [in] msg Message to be verified.
5438 * @param [in] msgSz Length of message in bytes.
5439 * @param [in] pub ED25519 public key data.
5440 * @param [in] privSz Length in bytes of public key data.
5441 * @param [in] sig Signature buffer.
5442 * @param [in] sigSz Length of the signature in bytes.
5443 * @return 1 on success
5444 * @return 0 on failure.
5445 */
5446int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
5447 const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
5448 unsigned int sigSz)
5449{
5450#if defined(HAVE_ED25519_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
5451 defined(HAVE_ED25519_KEY_IMPORT)
5452 ed25519_key key;
5453 int res = 1;
5454
5455 WOLFSSL_ENTER("wolfSSL_ED25519_verify");
5456
5457 /* Validate parameters. */
5458 if ((pub == NULL) || (pubSz != ED25519_PUB_KEY_SIZE) || (msg == NULL) ||
5459 (sig == NULL) || (sigSz != ED25519_SIG_SIZE)) {
5460 WOLFSSL_MSG("Bad arguments");
5461 res = 0;
5462 }
5463
5464 /* Initialize Ed25519 key. */
5465 if (res && (wc_ed25519_init(&key) != 0)) {
5466 WOLFSSL_MSG("wc_curve25519_init failed");
5467 res = 0;
5468 }
5469 if (res) {
5470 /* Import public key. */
5471 int ret = wc_ed25519_import_public(pub, pubSz, &key);
5472 if (ret != 0) {
5473 WOLFSSL_MSG("wc_ed25519_import_public failed");
5474 res = 0;
5475 }
5476
5477 if (res) {
5478 int check = 0;
5479
5480 /* Verify signature with message and public key. */
5481 ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
5482 &key);
5483 /* Check for errors in verification process. */
5484 if (ret != 0) {
5485 WOLFSSL_MSG("wc_ed25519_verify_msg failed");
5486 res = 0;
5487 }
5488 /* Check signature is valid. */
5489 else if (!check) {
5490 WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
5491 res = 0;
5492 }
5493 }
5494
5495 wc_ed25519_free(&key);
5496 }
5497
5498 return res;
5499#else
5500#if !defined(HAVE_ED25519_VERIFY)
5501 WOLFSSL_MSG("No ED25519 verify built in");
5502#elif !defined(WOLFSSL_KEY_GEN)
5503 WOLFSSL_MSG("No Key Gen built in");
5504#elif !defined(HAVE_ED25519_KEY_IMPORT)
5505 WOLFSSL_MSG("No ED25519 Key import built in");
5506#endif
5507
5508 (void)msg;
5509 (void)msgSz;
5510 (void)pub;
5511 (void)pubSz;
5512 (void)sig;
5513 (void)sigSz;
5514
5515 return 0;
5516#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
5517}
5518
5519#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
5520
5521#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
5522 defined(HAVE_ED25519)
5523/* Allocate and initialize a new ed25519_key.
5524 *
5525 * @param [in] heap Heap hint for memory allocation.
5526 * @param [in] devId Device identifier for crypto callbacks.
5527 * @return Allocated and initialized ed25519_key on success.
5528 * @return NULL on failure.
5529 */
5530ed25519_key* wolfSSL_ED25519_new(void* heap, int devId)
5531{
5532 ed25519_key* key;
5533
5534 WOLFSSL_ENTER("wolfSSL_ED25519_new");
5535
5536#ifndef WC_NO_CONSTRUCTORS
5537 key = wc_ed25519_new(heap, devId, NULL);
5538#else
5539 key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
5540 DYNAMIC_TYPE_ED25519);
5541 if (key == NULL) {
5542 WOLFSSL_ERROR_MSG("wolfSSL_ED25519_new malloc failure");
5543 }
5544 else if (wc_ed25519_init_ex(key, heap, devId) != 0) {
5545 WOLFSSL_ERROR_MSG("wolfSSL_ED25519_new init failure");
5546 XFREE(key, heap, DYNAMIC_TYPE_ED25519);
5547 key = NULL;
5548 }
5549#endif
5550
5551 return key;
5552}
5553
5554/* Free an ed25519_key allocated with wolfSSL_ED25519_new.
5555 *
5556 * @param [in] key ed25519_key to free. May be NULL.
5557 */
5558void wolfSSL_ED25519_free(ed25519_key* key)
5559{
5560 if (key != NULL) {
5561 WOLFSSL_ENTER("wolfSSL_ED25519_free");
5562 #ifndef WC_NO_CONSTRUCTORS
5563 wc_ed25519_delete(key, NULL);
5564 #else
5565 {
5566 void* heap = key->heap;
5567 wc_ed25519_free(key);
5568 XFREE(key, heap, DYNAMIC_TYPE_ED25519);
5569 }
5570 #endif
5571 }
5572}
5573#endif /* (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) && HAVE_ED25519 */
5574
5575/*******************************************************************************
5576 * END OF ED25519 API
5577 ******************************************************************************/
5578
5579/*******************************************************************************
5580 * START OF EC448 API
5581 ******************************************************************************/
5582
5583#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
5584/* Generate an EC448 key pair.
5585 *
5586 * Output keys are in little endian format.
5587 *
5588 * @param [out] priv EC448 private key data.
5589 * @param [in, out] privSz On in, the size of priv in bytes.
5590 * On out, the length of the private key data in bytes.
5591 * @param [out] pub EC448 public key data.
5592 * @param [in, out] pubSz On in, the size of pub in bytes.
5593 * On out, the length of the public key data in bytes.
5594 * @return 1 on success
5595 * @return 0 on failure.
5596 */
5597int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
5598 unsigned char *pub, unsigned int *pubSz)
5599{
5600#ifdef WOLFSSL_KEY_GEN
5601 int res = 1;
5602 int initTmpRng = 0;
5603 WC_RNG *rng = NULL;
5604 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5605 curve448_key key;
5606
5607 WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
5608
5609 /* Validate parameters. */
5610 if ((priv == NULL) || (privSz == NULL) || (*privSz < CURVE448_KEY_SIZE) ||
5611 (pub == NULL) || (pubSz == NULL) || (*pubSz < CURVE448_KEY_SIZE)) {
5612 WOLFSSL_MSG("Bad arguments");
5613 res = 0;
5614 }
5615
5616 if (res) {
5617 /* Create a random number generator. */
5618 rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5619 if (rng == NULL) {
5620 WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5621 res = 0;
5622 }
5623 }
5624
5625 /* Initialize a Curve448 key. */
5626 if (res && (wc_curve448_init(&key) != 0)) {
5627 WOLFSSL_MSG("wc_curve448_init failed");
5628 res = 0;
5629 }
5630 if (res) {
5631 /* Make a Curve448 key pair. */
5632 int ret = wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key);
5633 if (ret != 0) {
5634 WOLFSSL_MSG("wc_curve448_make_key failed");
5635 res = 0;
5636 }
5637 if (res) {
5638 /* Export Curve448 key pair to buffers. */
5639 ret = wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
5640 EC448_LITTLE_ENDIAN);
5641 if (ret != 0) {
5642 WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
5643 res = 0;
5644 }
5645 }
5646
5647 /* Dispose of key. */
5648 wc_curve448_free(&key);
5649 }
5650
5651 if (initTmpRng) {
5652 wc_FreeRng(rng);
5653 WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5654 }
5655
5656 return res;
5657#else
5658 WOLFSSL_MSG("No Key Gen built in");
5659
5660 (void)priv;
5661 (void)privSz;
5662 (void)pub;
5663 (void)pubSz;
5664
5665 return 0;
5666#endif /* WOLFSSL_KEY_GEN */
5667}
5668
5669/* Compute a shared secret from private and public EC448 keys.
5670 *
5671 * Input and output keys are in little endian format
5672 *
5673 * @param [out] shared Shared secret buffer.
5674 * @param [in, out] sharedSz On in, the size of shared in bytes.
5675 * On out, the length of the secret in bytes.
5676 * @param [in] priv EC448 private key data.
5677 * @param [in] privSz Length of the private key data in bytes.
5678 * @param [in] pub EC448 public key data.
5679 * @param [in] pubSz Length of the public key data in bytes.
5680 * @return 1 on success
5681 * @return 0 on failure.
5682 */
5683int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
5684 const unsigned char *priv, unsigned int privSz,
5685 const unsigned char *pub, unsigned int pubSz)
5686{
5687#ifdef WOLFSSL_KEY_GEN
5688 int res = 1;
5689 curve448_key privkey;
5690 curve448_key pubkey;
5691
5692 WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
5693
5694 /* Validate parameters. */
5695 if ((shared == NULL) || (sharedSz == NULL) ||
5696 (*sharedSz < CURVE448_KEY_SIZE) || (priv == NULL) ||
5697 (privSz < CURVE448_KEY_SIZE) || (pub == NULL) ||
5698 (pubSz < CURVE448_KEY_SIZE)) {
5699 WOLFSSL_MSG("Bad arguments");
5700 res = 0;
5701 }
5702
5703 /* Initialize private key object. */
5704 if (res && (wc_curve448_init(&privkey) != 0)) {
5705 WOLFSSL_MSG("wc_curve448_init privkey failed");
5706 res = 0;
5707 }
5708 if (res) {
5709 /* Initialize public key object. */
5710 if (wc_curve448_init(&pubkey) != MP_OKAY) {
5711 WOLFSSL_MSG("wc_curve448_init pubkey failed");
5712 res = 0;
5713 }
5714 if (res) {
5715 /* Import our private key. */
5716 int ret = wc_curve448_import_private_ex(priv, privSz, &privkey,
5717 EC448_LITTLE_ENDIAN);
5718 if (ret != 0) {
5719 WOLFSSL_MSG("wc_curve448_import_private_ex failed");
5720 res = 0;
5721 }
5722
5723 if (res) {
5724 /* Import peer's public key. */
5725 ret = wc_curve448_import_public_ex(pub, pubSz, &pubkey,
5726 EC448_LITTLE_ENDIAN);
5727 if (ret != 0) {
5728 WOLFSSL_MSG("wc_curve448_import_public_ex failed");
5729 res = 0;
5730 }
5731 }
5732 if (res) {
5733 /* Compute shared secret. */
5734 ret = wc_curve448_shared_secret_ex(&privkey, &pubkey, shared,
5735 sharedSz, EC448_LITTLE_ENDIAN);
5736 if (ret != 0) {
5737 WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
5738 res = 0;
5739 }
5740 }
5741
5742 wc_curve448_free(&pubkey);
5743 }
5744 wc_curve448_free(&privkey);
5745 }
5746
5747 return res;
5748#else
5749 WOLFSSL_MSG("No Key Gen built in");
5750
5751 (void)shared;
5752 (void)sharedSz;
5753 (void)priv;
5754 (void)privSz;
5755 (void)pub;
5756 (void)pubSz;
5757
5758 return 0;
5759#endif /* WOLFSSL_KEY_GEN */
5760}
5761#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
5762
5763/*******************************************************************************
5764 * END OF EC448 API
5765 ******************************************************************************/
5766
5767/*******************************************************************************
5768 * START OF ED448 API
5769 ******************************************************************************/
5770
5771#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
5772/* Generate an ED448 key pair.
5773 *
5774 * Output keys are in little endian format.
5775 *
5776 * @param [out] priv ED448 private key data.
5777 * @param [in, out] privSz On in, the size of priv in bytes.
5778 * On out, the length of the private key data in bytes.
5779 * @param [out] pub ED448 public key data.
5780 * @param [in, out] pubSz On in, the size of pub in bytes.
5781 * On out, the length of the public key data in bytes.
5782 * @return 1 on success
5783 * @return 0 on failure.
5784 */
5785int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
5786 unsigned char *pub, unsigned int *pubSz)
5787{
5788#if defined(WOLFSSL_KEY_GEN) && defined(HAVE_ED448_KEY_EXPORT)
5789 int res = 1;
5790 int initTmpRng = 0;
5791 WC_RNG *rng = NULL;
5792 WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
5793 ed448_key key;
5794
5795 WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
5796
5797 /* Validate parameters. */
5798 if ((priv == NULL) || (privSz == NULL) ||
5799 (*privSz < ED448_PRV_KEY_SIZE) || (pub == NULL) ||
5800 (pubSz == NULL) || (*pubSz < ED448_PUB_KEY_SIZE)) {
5801 WOLFSSL_MSG("Bad arguments");
5802 res = 0;
5803 }
5804
5805 if (res) {
5806 /* Create a random number generator. */
5807 rng = wolfssl_make_rng(tmpRng, &initTmpRng);
5808 if (rng == NULL) {
5809 WOLFSSL_MSG("wolfSSL_EC_KEY_generate_key failed to make RNG");
5810 res = 0;
5811 }
5812 }
5813
5814 /* Initialize an Ed448 key. */
5815 if (res && (wc_ed448_init(&key) != 0)) {
5816 WOLFSSL_MSG("wc_ed448_init failed");
5817 res = 0;
5818 }
5819 if (res) {
5820 /* Make an Ed448 key pair. */
5821 int ret = wc_ed448_make_key(rng, ED448_KEY_SIZE, &key);
5822 if (ret != 0) {
5823 WOLFSSL_MSG("wc_ed448_make_key failed");
5824 res = 0;
5825 }
5826 if (res) {
5827 /* Export Curve448 key pair to buffers. */
5828 ret = wc_ed448_export_key(&key, priv, privSz, pub, pubSz);
5829 if (ret != 0) {
5830 WOLFSSL_MSG("wc_ed448_export_key failed");
5831 res = 0;
5832 }
5833 }
5834
5835 wc_ed448_free(&key);
5836 }
5837
5838 if (initTmpRng) {
5839 wc_FreeRng(rng);
5840 WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
5841 }
5842
5843 return res;
5844#else
5845#ifndef WOLFSSL_KEY_GEN
5846 WOLFSSL_MSG("No Key Gen built in");
5847#else
5848 WOLFSSL_MSG("No ED448 key export built in");
5849#endif
5850
5851 (void)priv;
5852 (void)privSz;
5853 (void)pub;
5854 (void)pubSz;
5855
5856 return 0;
5857#endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
5858}
5859
5860/* Sign a message with Ed448 using the private key.
5861 *
5862 * Input and output keys are in little endian format.
5863 * Priv is a buffer containing private and public part of key.
5864 *
5865 * @param [in] msg Message to be signed.
5866 * @param [in] msgSz Length of message in bytes.
5867 * @param [in] priv ED448 private key data.
5868 * @param [in] privSz Length in bytes of private key data.
5869 * @param [out] sig Signature buffer.
5870 * @param [in, out] sigSz On in, the length of the signature buffer in bytes.
5871 * On out, the length of the signature in bytes.
5872 * @return 1 on success
5873 * @return 0 on failure.
5874 */
5875int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
5876 const unsigned char *priv, unsigned int privSz, unsigned char *sig,
5877 unsigned int *sigSz)
5878{
5879#if defined(HAVE_ED448_SIGN) && defined(WOLFSSL_KEY_GEN) && \
5880 defined(HAVE_ED448_KEY_IMPORT)
5881 ed448_key key;
5882 int res = 1;
5883
5884 WOLFSSL_ENTER("wolfSSL_ED448_sign");
5885
5886 /* Validate parameters. */
5887 if ((priv == NULL) || (privSz != ED448_PRV_KEY_SIZE) ||
5888 (msg == NULL) || (sig == NULL) || (sigSz == NULL) ||
5889 (*sigSz < ED448_SIG_SIZE)) {
5890 WOLFSSL_MSG("Bad arguments");
5891 res = 0;
5892 }
5893
5894 /* Initialize Ed448 key. */
5895 if (res && (wc_ed448_init(&key) != 0)) {
5896 WOLFSSL_MSG("wc_curve448_init failed");
5897 res = 0;
5898 }
5899 if (res) {
5900 /* Import private and public key. */
5901 int ret = wc_ed448_import_private_key(priv, privSz / 2,
5902 priv + (privSz / 2), ED448_PUB_KEY_SIZE, &key);
5903 if (ret != 0) {
5904 WOLFSSL_MSG("wc_ed448_import_private failed");
5905 res = 0;
5906 }
5907
5908 if (res) {
5909 /* Sign message with Ed448 - no context. */
5910 ret = wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key, NULL, 0);
5911 if (ret != 0) {
5912 WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
5913 res = 0;
5914 }
5915 }
5916
5917 wc_ed448_free(&key);
5918 }
5919
5920 return res;
5921#else
5922#if !defined(HAVE_ED448_SIGN)
5923 WOLFSSL_MSG("No ED448 sign built in");
5924#elif !defined(WOLFSSL_KEY_GEN)
5925 WOLFSSL_MSG("No Key Gen built in");
5926#elif !defined(HAVE_ED448_KEY_IMPORT)
5927 WOLFSSL_MSG("No ED448 Key import built in");
5928#endif
5929
5930 (void)msg;
5931 (void)msgSz;
5932 (void)priv;
5933 (void)privSz;
5934 (void)sig;
5935 (void)sigSz;
5936
5937 return 0;
5938#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
5939}
5940
5941/* Verify a message with Ed448 using the public key.
5942 *
5943 * Input keys are in little endian format.
5944 *
5945 * @param [in] msg Message to be verified.
5946 * @param [in] msgSz Length of message in bytes.
5947 * @param [in] pub ED448 public key data.
5948 * @param [in] privSz Length in bytes of public key data.
5949 * @param [in] sig Signature buffer.
5950 * @param [in] sigSz Length of the signature in bytes.
5951 * @return 1 on success
5952 * @return 0 on failure.
5953 */
5954int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
5955 const unsigned char *pub, unsigned int pubSz, const unsigned char *sig,
5956 unsigned int sigSz)
5957{
5958#if defined(HAVE_ED448_VERIFY) && defined(WOLFSSL_KEY_GEN) && \
5959 defined(HAVE_ED448_KEY_IMPORT)
5960 ed448_key key;
5961 int res = 1;
5962
5963 WOLFSSL_ENTER("wolfSSL_ED448_verify");
5964
5965 /* Validate parameters. */
5966 if ((pub == NULL) || (pubSz != ED448_PUB_KEY_SIZE) || (msg == NULL) ||
5967 (sig == NULL) || (sigSz != ED448_SIG_SIZE)) {
5968 WOLFSSL_MSG("Bad arguments");
5969 res = 0;
5970 }
5971
5972 /* Initialize Ed448 key. */
5973 if (res && (wc_ed448_init(&key) != 0)) {
5974 WOLFSSL_MSG("wc_curve448_init failed");
5975 res = 0;
5976 }
5977 if (res) {
5978 /* Import public key. */
5979 int ret = wc_ed448_import_public(pub, pubSz, &key);
5980 if (ret != 0) {
5981 WOLFSSL_MSG("wc_ed448_import_public failed");
5982 res = 0;
5983 }
5984
5985 if (res) {
5986 int check = 0;
5987
5988 /* Verify signature with message and public key - no context. */
5989 ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
5990 &key, NULL, 0);
5991 /* Check for errors in verification process. */
5992 if (ret != 0) {
5993 WOLFSSL_MSG("wc_ed448_verify_msg failed");
5994 res = 0;
5995 }
5996 /* Check signature is valid. */
5997 else if (!check) {
5998 WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
5999 res = 0;
6000 }
6001 }
6002
6003 wc_ed448_free(&key);
6004 }
6005
6006 return res;
6007#else
6008#if !defined(HAVE_ED448_VERIFY)
6009 WOLFSSL_MSG("No ED448 verify built in");
6010#elif !defined(WOLFSSL_KEY_GEN)
6011 WOLFSSL_MSG("No Key Gen built in");
6012#elif !defined(HAVE_ED448_KEY_IMPORT)
6013 WOLFSSL_MSG("No ED448 Key import built in");
6014#endif
6015
6016 (void)msg;
6017 (void)msgSz;
6018 (void)pub;
6019 (void)pubSz;
6020 (void)sig;
6021 (void)sigSz;
6022
6023 return 0;
6024#endif /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
6025}
6026#endif /* OPENSSL_EXTRA && HAVE_ED448 */
6027
6028#if (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)) && \
6029 defined(HAVE_ED448)
6030/* Allocate and initialize a new ed448_key.
6031 *
6032 * @param [in] heap Heap hint for memory allocation.
6033 * @param [in] devId Device identifier for crypto callbacks.
6034 * @return Allocated and initialized ed448_key on success.
6035 * @return NULL on failure.
6036 */
6037ed448_key* wolfSSL_ED448_new(void* heap, int devId)
6038{
6039 ed448_key* key;
6040
6041 WOLFSSL_ENTER("wolfSSL_ED448_new");
6042
6043#if !defined(WC_NO_CONSTRUCTORS) && \
6044 (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7, 0))
6045 key = wc_ed448_new(heap, devId, NULL);
6046#else
6047 key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
6048 if (key == NULL) {
6049 WOLFSSL_ERROR_MSG("wolfSSL_ED448_new malloc failure");
6050 }
6051 else if (wc_ed448_init_ex(key, heap, devId) != 0) {
6052 WOLFSSL_ERROR_MSG("wolfSSL_ED448_new init failure");
6053 XFREE(key, heap, DYNAMIC_TYPE_ED448);
6054 key = NULL;
6055 }
6056#endif
6057
6058 return key;
6059}
6060
6061/* Free an ed448_key allocated with wolfSSL_ED448_new.
6062 *
6063 * @param [in] key ed448_key to free. May be NULL.
6064 */
6065void wolfSSL_ED448_free(ed448_key* key)
6066{
6067 if (key != NULL) {
6068 WOLFSSL_ENTER("wolfSSL_ED448_free");
6069 #if !defined(WC_NO_CONSTRUCTORS) && \
6070 (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7, 0))
6071 wc_ed448_delete(key, NULL);
6072 #else
6073 {
6074 void* heap = key->heap;
6075 wc_ed448_free(key);
6076 XFREE(key, heap, DYNAMIC_TYPE_ED448);
6077 }
6078 #endif
6079 }
6080}
6081#endif /* (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) && HAVE_ED448 */
6082
6083/*******************************************************************************
6084 * END OF ED448 API
6085 ******************************************************************************/
6086
6087/*******************************************************************************
6088 * START OF GENERIC PUBLIC KEY PEM APIs
6089 ******************************************************************************/
6090
6091#ifdef OPENSSL_EXTRA
6092/* Sets default callback password for PEM.
6093 *
6094 * @param [out] buf Buffer to hold password.
6095 * @param [in] num Number of characters in buffer.
6096 * @param [in] rwFlag Read/write flag. Ignored.
6097 * @param [in] userData User data - assumed to be default password.
6098 * @return Password size on success.
6099 * @return 0 on failure.
6100 */
6101int wolfSSL_PEM_def_callback(char* buf, int num, int rwFlag, void* userData)
6102{
6103 int sz = 0;
6104
6105 WOLFSSL_ENTER("wolfSSL_PEM_def_callback");
6106
6107 (void)rwFlag;
6108
6109 /* We assume that the user passes a default password as userdata */
6110 if ((buf != NULL) && (userData != NULL)) {
6111 sz = (int)XSTRLEN((const char*)userData);
6112 sz = (int)min((word32)sz, (word32)num);
6113 XMEMCPY(buf, userData, (size_t)sz);
6114 }
6115 else {
6116 WOLFSSL_MSG("Error, default password cannot be created.");
6117 }
6118
6119 return sz;
6120}
6121
6122#ifndef NO_BIO
6123/* Writes a public key to a WOLFSSL_BIO encoded in PEM format.
6124 *
6125 * @param [in] bio BIO to write to.
6126 * @param [in] key Public key to write in PEM format.
6127 * @return 1 on success.
6128 * @return 0 on failure.
6129 */
6130int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
6131{
6132 int ret = 0;
6133
6134 WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
6135
6136 if ((bio != NULL) && (key != NULL)) {
6137 switch (key->type) {
6138#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
6139 case WC_EVP_PKEY_RSA:
6140 ret = wolfSSL_PEM_write_bio_RSA_PUBKEY(bio, key->rsa);
6141 break;
6142#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
6143#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && \
6144 defined(WOLFSSL_KEY_GEN)
6145 case WC_EVP_PKEY_DSA:
6146 ret = wolfSSL_PEM_write_bio_DSA_PUBKEY(bio, key->dsa);
6147 break;
6148#endif /* !NO_DSA && !HAVE_SELFTEST && defined(WOLFSSL_KEY_GEN) */
6149#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
6150 defined(WOLFSSL_KEY_GEN)
6151 case WC_EVP_PKEY_EC:
6152 ret = wolfSSL_PEM_write_bio_EC_PUBKEY(bio, key->ecc);
6153 break;
6154#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
6155#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
6156 case WC_EVP_PKEY_DH:
6157 /* DH public key not supported. */
6158 WOLFSSL_MSG("Writing DH PUBKEY not supported!");
6159 break;
6160#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
6161 default:
6162 /* Key type not supported. */
6163 WOLFSSL_MSG("Unknown Key type!");
6164 break;
6165 }
6166 }
6167
6168 return ret;
6169}
6170
6171/* Writes a private key to a WOLFSSL_BIO encoded in PEM format.
6172 *
6173 * @param [in] bio BIO to write to.
6174 * @param [in] key Public key to write in PEM format.
6175 * @param [in] cipher Encryption cipher to use.
6176 * @param [in] passwd Password to use when encrypting.
6177 * @param [in] len Length of password.
6178 * @param [in] cb Password callback.
6179 * @param [in] arg Password callback argument.
6180 * @return 1 on success.
6181 * @return 0 on failure.
6182 */
6183int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
6184 const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len,
6185 wc_pem_password_cb* cb, void* arg)
6186{
6187 int ret = 1;
6188
6189 WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
6190
6191 (void)cipher;
6192 (void)passwd;
6193 (void)len;
6194 (void)cb;
6195 (void)arg;
6196
6197 /* Validate parameters. */
6198 if ((bio == NULL) || (key == NULL)) {
6199 WOLFSSL_MSG("Bad Function Arguments");
6200 ret = 0;
6201 }
6202
6203 if (ret == 1) {
6204 #ifdef WOLFSSL_KEY_GEN
6205 switch (key->type) {
6206 #ifndef NO_RSA
6207 case WC_EVP_PKEY_RSA:
6208 /* Write using RSA specific API. */
6209 ret = wolfSSL_PEM_write_bio_RSAPrivateKey(bio, key->rsa,
6210 cipher, passwd, len, cb, arg);
6211 break;
6212 #endif
6213 #ifndef NO_DSA
6214 case WC_EVP_PKEY_DSA:
6215 /* Write using DSA specific API. */
6216 ret = wolfSSL_PEM_write_bio_DSAPrivateKey(bio, key->dsa,
6217 cipher, passwd, len, cb, arg);
6218 break;
6219 #endif
6220 #ifdef HAVE_ECC
6221 case WC_EVP_PKEY_EC:
6222 #if defined(HAVE_ECC_KEY_EXPORT)
6223 /* Write using EC specific API. */
6224 ret = wolfSSL_PEM_write_bio_ECPrivateKey(bio, key->ecc,
6225 cipher, passwd, len, cb, arg);
6226 #else
6227 ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
6228 key->pkey_sz, bio, EC_PRIVATEKEY_TYPE);
6229 #endif
6230 break;
6231 #endif
6232 #ifndef NO_DH
6233 case WC_EVP_PKEY_DH:
6234 /* Write using generic API with DH type. */
6235 ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr,
6236 key->pkey_sz, bio, DH_PRIVATEKEY_TYPE);
6237 break;
6238 #endif
6239 default:
6240 WOLFSSL_MSG("Unknown Key type!");
6241 ret = 0;
6242 break;
6243 }
6244 #else
6245 int type = 0;
6246
6247 switch (key->type) {
6248 #ifndef NO_DSA
6249 case WC_EVP_PKEY_DSA:
6250 type = DSA_PRIVATEKEY_TYPE;
6251 break;
6252 #endif
6253 #ifdef HAVE_ECC
6254 case WC_EVP_PKEY_EC:
6255 type = ECC_PRIVATEKEY_TYPE;
6256 break;
6257 #endif
6258 #ifndef NO_DH
6259 case WC_EVP_PKEY_DH:
6260 type = DH_PRIVATEKEY_TYPE;
6261 break;
6262 #endif
6263 #ifndef NO_RSA
6264 case WC_EVP_PKEY_RSA:
6265 type = PRIVATEKEY_TYPE;
6266 break;
6267 #endif
6268 default:
6269 ret = 0;
6270 break;
6271 }
6272 if (ret == 1) {
6273 /* Write using generic API with generic type. */
6274 ret = der_write_to_bio_as_pem((byte*)key->pkey.ptr, key->pkey_sz,
6275 bio, type);
6276 }
6277 #endif
6278 }
6279
6280 return ret;
6281}
6282#endif /* !NO_BIO */
6283
6284#ifndef NO_BIO
6285/* Create a private key object from the data in the BIO.
6286 *
6287 * @param [in] bio BIO to read from.
6288 * @param [in, out] key Public key object. Object used if passed in.
6289 * @param [in] cb Password callback.
6290 * @param [in] arg Password callback argument.
6291 * @return A WOLFSSL_EVP_PKEY object on success.
6292 * @return NULL on failure.
6293 */
6294WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
6295 WOLFSSL_EVP_PKEY **key, wc_pem_password_cb *cb, void *arg)
6296{
6297 int err = 0;
6298 WOLFSSL_EVP_PKEY* pkey = NULL;
6299 DerBuffer* der = NULL;
6300
6301 WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
6302
6303 if (bio == NULL) {
6304 err = 1;
6305 }
6306
6307 /* Read the PEM public key from the BIO and convert to DER. */
6308 if ((!err) && (pem_read_bio_key(bio, cb, arg, PUBLICKEY_TYPE, NULL,
6309 &der) < 0)) {
6310 err = 1;
6311 }
6312
6313 if (!err) {
6314 const unsigned char* ptr = der->buffer;
6315
6316 /* Use key passed in if set. */
6317 if ((key != NULL) && (*key != NULL)) {
6318 pkey = *key;
6319 }
6320
6321 /* Convert DER data to a public key object. */
6322 if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
6323 WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6324 pkey = NULL;
6325 err = 1;
6326 }
6327 }
6328
6329 /* Return the key if possible. */
6330 if ((!err) && (key != NULL) && (pkey != NULL)) {
6331 *key = pkey;
6332 }
6333 /* Dispose of the DER encoding. */
6334 FreeDer(&der);
6335
6336 WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
6337
6338 return pkey;
6339}
6340
6341/* Create a private key object from the data in the BIO.
6342 *
6343 * @param [in] bio BIO to read from.
6344 * @param [in, out] key Private key object. Object used if passed in.
6345 * @param [in] cb Password callback.
6346 * @param [in] arg Password callback argument.
6347 * @return A WOLFSSL_EVP_PKEY object on success.
6348 * @return NULL on failure.
6349 */
6350WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
6351 WOLFSSL_EVP_PKEY** key, wc_pem_password_cb* cb, void* arg)
6352{
6353 int err = 0;
6354 WOLFSSL_EVP_PKEY* pkey = NULL;
6355 DerBuffer* der = NULL;
6356 int keyFormat = 0;
6357
6358 WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
6359
6360 /* Validate parameters. */
6361 if (bio == NULL) {
6362 err = 1;
6363 }
6364
6365 /* Read the PEM private key from the BIO and convert to DER. */
6366 if ((!err) && (pem_read_bio_key(bio, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
6367 &der) < 0)) {
6368 err = 1;
6369 }
6370
6371 if (!err) {
6372 const unsigned char* ptr = der->buffer;
6373 int type;
6374
6375 /* Set key type based on format returned. */
6376 switch (keyFormat) {
6377 /* No key format set - default to RSA. */
6378 case 0:
6379 case RSAk:
6380 type = WC_EVP_PKEY_RSA;
6381 break;
6382 case DSAk:
6383 type = WC_EVP_PKEY_DSA;
6384 break;
6385 case ECDSAk:
6386 type = WC_EVP_PKEY_EC;
6387 break;
6388 case DHk:
6389 type = WC_EVP_PKEY_DH;
6390 break;
6391 #ifdef HAVE_ED25519
6392 case ED25519k:
6393 type = WC_EVP_PKEY_ED25519;
6394 break;
6395 #endif
6396 #ifdef HAVE_ED448
6397 case ED448k:
6398 type = WC_EVP_PKEY_ED448;
6399 break;
6400 #endif
6401 default:
6402 type = WOLFSSL_FATAL_ERROR;
6403 break;
6404 }
6405
6406 /* Use key passed in if set. */
6407 if ((key != NULL) && (*key != NULL)) {
6408 pkey = *key;
6409 }
6410
6411 /* Convert DER data to a private key object. */
6412 if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
6413 WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6414 pkey = NULL;
6415 err = 1;
6416 }
6417 }
6418
6419 /* Return the key if possible. */
6420 if ((!err) && (key != NULL) && (pkey != NULL)) {
6421 *key = pkey;
6422 }
6423 /* Dispose of the DER encoding. */
6424 FreeDer(&der);
6425
6426 WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", err);
6427
6428 return pkey;
6429}
6430
6431
6432WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_PEM_read_bio_PKCS8_PRIV_KEY_INFO(
6433 WOLFSSL_BIO* bio, WOLFSSL_PKCS8_PRIV_KEY_INFO** key, wc_pem_password_cb* cb,
6434 void* arg)
6435{
6436 return wolfSSL_PEM_read_bio_PrivateKey(bio, key, cb, arg);
6437}
6438#endif /* !NO_BIO */
6439
6440#if !defined(NO_FILESYSTEM)
6441/* Create a private key object from the data in a file.
6442 *
6443 * @param [in] fp File pointer.
6444 * @param [in, out] key Public key object. Object used if passed in.
6445 * @param [in] cb Password callback.
6446 * @param [in] arg Password callback argument.
6447 * @return A WOLFSSL_EVP_PKEY object on success.
6448 * @return NULL on failure.
6449 */
6450WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **key,
6451 wc_pem_password_cb *cb, void *arg)
6452{
6453 int err = 0;
6454 WOLFSSL_EVP_PKEY* pkey = NULL;
6455 DerBuffer* der = NULL;
6456
6457 WOLFSSL_ENTER("wolfSSL_PEM_read_PUBKEY");
6458
6459 /* Validate parameters. */
6460 if (fp == XBADFILE) {
6461 err = 1;
6462 }
6463
6464 /* Read the PEM public key from the file and convert to DER. */
6465 if ((!err) && ((pem_read_file_key(fp, cb, arg, PUBLICKEY_TYPE, NULL,
6466 &der) < 0) || (der == NULL))) {
6467 err = 1;
6468 }
6469 if (!err) {
6470 const unsigned char* ptr = der->buffer;
6471
6472 /* Use key passed in if set. */
6473 if ((key != NULL) && (*key != NULL)) {
6474 pkey = *key;
6475 }
6476
6477 /* Convert DER data to a public key object. */
6478 if (wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length) == NULL) {
6479 WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6480 pkey = NULL;
6481 err = 1;
6482 }
6483 }
6484
6485 /* Return the key if possible. */
6486 if ((!err) && (key != NULL) && (pkey != NULL)) {
6487 *key = pkey;
6488 }
6489 /* Dispose of the DER encoding. */
6490 FreeDer(&der);
6491
6492 WOLFSSL_LEAVE("wolfSSL_PEM_read_PUBKEY", 0);
6493
6494 return pkey;
6495}
6496
6497#ifndef NO_CERTS
6498/* Create a private key object from the data in a file.
6499 *
6500 * @param [in] fp File pointer.
6501 * @param [in, out] key Private key object. Object used if passed in.
6502 * @param [in] cb Password callback.
6503 * @param [in] arg Password callback argument.
6504 * @return A WOLFSSL_EVP_PKEY object on success.
6505 * @return NULL on failure.
6506 */
6507WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp, WOLFSSL_EVP_PKEY **key,
6508 wc_pem_password_cb *cb, void *arg)
6509{
6510 int err = 0;
6511 WOLFSSL_EVP_PKEY* pkey = NULL;
6512 DerBuffer* der = NULL;
6513 int keyFormat = 0;
6514
6515 WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey");
6516
6517 /* Validate parameters. */
6518 if (fp == XBADFILE) {
6519 err = 1;
6520 }
6521
6522 /* Read the PEM private key from the file and convert to DER. */
6523 if ((!err) && (pem_read_file_key(fp, cb, arg, PRIVATEKEY_TYPE, &keyFormat,
6524 &der)) < 0) {
6525 err = 1;
6526 }
6527
6528 if (!err) {
6529 const unsigned char* ptr = der->buffer;
6530 int type;
6531
6532 /* Set key type based on format returned. */
6533 switch (keyFormat) {
6534 /* No key format set - default to RSA. */
6535 case 0:
6536 case RSAk:
6537 type = WC_EVP_PKEY_RSA;
6538 break;
6539 case DSAk:
6540 type = WC_EVP_PKEY_DSA;
6541 break;
6542 case ECDSAk:
6543 type = WC_EVP_PKEY_EC;
6544 break;
6545 case DHk:
6546 type = WC_EVP_PKEY_DH;
6547 break;
6548 #ifdef HAVE_ED25519
6549 case ED25519k:
6550 type = WC_EVP_PKEY_ED25519;
6551 break;
6552 #endif
6553 #ifdef HAVE_ED448
6554 case ED448k:
6555 type = WC_EVP_PKEY_ED448;
6556 break;
6557 #endif
6558 default:
6559 type = WOLFSSL_FATAL_ERROR;
6560 break;
6561 }
6562
6563 /* Use key passed in if set. */
6564 if ((key != NULL) && (*key != NULL)) {
6565 pkey = *key;
6566 }
6567
6568 /* Convert DER data to a private key object. */
6569 if (wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length) == NULL) {
6570 WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
6571 pkey = NULL;
6572 err = 1;
6573 }
6574 }
6575
6576 /* Return the key if possible. */
6577 if ((!err) && (key != NULL) && (pkey != NULL)) {
6578 *key = pkey;
6579 }
6580 /* Dispose of the DER encoding. */
6581 FreeDer(&der);
6582
6583 WOLFSSL_LEAVE("wolfSSL_PEM_read_PrivateKey", 0);
6584
6585 return pkey;
6586}
6587#endif /* !NO_CERTS */
6588#endif /* !NO_FILESYSTEM */
6589
6590#ifndef NO_CERTS
6591
6592#if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
6593#define PEM_BEGIN "-----BEGIN "
6594#define PEM_BEGIN_SZ 11
6595#define PEM_END "-----END "
6596#define PEM_END_SZ 9
6597#define PEM_HDR_FIN "-----"
6598#define PEM_HDR_FIN_SZ 5
6599#define PEM_HDR_FIN_EOL_NEWLINE "-----\n"
6600#define PEM_HDR_FIN_EOL_NULL_TERM "-----\0"
6601#define PEM_HDR_FIN_EOL_SZ 6
6602
6603/* Find strings and return middle offsets.
6604 *
6605 * Find first string in pem as a prefix and then locate second string as a
6606 * postfix.
6607 * len returning with 0 indicates not found.
6608 *
6609 * @param [in] pem PEM data.
6610 * @param [in] pemLen Length of PEM data.
6611 * @param [in] idx Current index.
6612 * @param [in] prefix First string to find.
6613 * @param [in] postfix Second string to find after first.
6614 * @param [out] start Start index of data between strings.
6615 * @param [out] len Length of data between strings.
6616 */
6617static void pem_find_pattern(char* pem, int pemLen, int idx, const char* prefix,
6618 const char* postfix, int* start, int* len)
6619{
6620 int prefixLen = (int)XSTRLEN(prefix);
6621 int postfixLen = (int)XSTRLEN(postfix);
6622
6623 *start = *len = 0;
6624 /* Find prefix part. */
6625 for (; idx < pemLen - prefixLen; idx++) {
6626 if ((pem[idx] == prefix[0]) &&
6627 (XMEMCMP(pem + idx, prefix, (size_t)prefixLen) == 0)) {
6628 idx += prefixLen;
6629 *start = idx;
6630 break;
6631 }
6632 }
6633 /* Find postfix part. */
6634 for (; idx < pemLen - postfixLen; idx++) {
6635 if ((pem[idx] == postfix[0]) &&
6636 (XMEMCMP(pem + idx, postfix, (size_t)postfixLen) == 0)) {
6637 *len = idx - *start;
6638 break;
6639 }
6640 }
6641}
6642
6643/* Parse out content type name, any encryption headers and DER encoding.
6644 *
6645 * @param [in] pem PEM data.
6646 * @param [in] pemLen Length of PEM data.
6647 * @param [out] name Name of content type.
6648 * @param [out] header Encryption headers.
6649 * @param [out] data DER encoding from PEM.
6650 * @param [out] len Length of DER data.
6651 * @return 0 on success.
6652 * @return MEMORY_E when dynamic memory allocation fails.
6653 * @return ASN_NO_PEM_HEADER when no header found or different names found.
6654 */
6655static int pem_read_data(char* pem, int pemLen, char **name, char **header,
6656 unsigned char **data, long *len)
6657{
6658 int ret = 0;
6659 int start;
6660 int nameLen;
6661 int startHdr = 0;
6662 int hdrLen = 0;
6663 int startEnd = 0;
6664 int endLen;
6665
6666 *name = NULL;
6667 *header = NULL;
6668
6669 /* Find header. */
6670 pem_find_pattern(pem, pemLen, 0, PEM_BEGIN, PEM_HDR_FIN, &start, &nameLen);
6671 /* Allocate memory for header name. */
6672 *name = (char*)XMALLOC((size_t)nameLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6673 if (*name == NULL) {
6674 ret = MEMORY_E;
6675 }
6676 if (ret == 0) {
6677 /* Put in header name. */
6678 (*name)[nameLen] = '\0';
6679 if (nameLen == 0) {
6680 ret = ASN_NO_PEM_HEADER;
6681 }
6682 else {
6683 XMEMCPY(*name, pem + start, (size_t)nameLen);
6684 }
6685 }
6686 if (ret == 0) {
6687 /* Find encryption headers after header. */
6688 start += nameLen + PEM_HDR_FIN_SZ;
6689 pem_find_pattern(pem, pemLen, start, "\n", "\n\n", &startHdr, &hdrLen);
6690 if (hdrLen > 0) {
6691 /* Include first of two '\n' characters. */
6692 hdrLen++;
6693 }
6694 /* Allocate memory for encryption header string. */
6695 *header = (char*)XMALLOC((size_t)hdrLen + 1, NULL,
6696 DYNAMIC_TYPE_TMP_BUFFER);
6697 if (*header == NULL) {
6698 ret = MEMORY_E;
6699 }
6700 }
6701 if (ret == 0) {
6702 /* Put in encryption header string. */
6703 (*header)[hdrLen] = '\0';
6704 if (hdrLen > 0) {
6705 XMEMCPY(*header, pem + startHdr, (size_t)hdrLen);
6706 start = startHdr + hdrLen + 1;
6707 }
6708
6709 /* Find footer. */
6710 pem_find_pattern(pem, pemLen, start, PEM_END, PEM_HDR_FIN, &startEnd,
6711 &endLen);
6712 /* Validate header name and footer name are the same. */
6713 if ((endLen != nameLen) ||
6714 (XMEMCMP(*name, pem + startEnd, (size_t)nameLen) != 0)) {
6715 ret = ASN_NO_PEM_HEADER;
6716 }
6717 }
6718 if (ret == 0) {
6719 unsigned char* der = (unsigned char*)pem;
6720 word32 derLen;
6721
6722 /* Convert PEM body to DER. */
6723 derLen = (word32)(startEnd - PEM_END_SZ - start);
6724 ret = Base64_Decode(der + start, derLen, der, &derLen);
6725 if (ret == 0) {
6726 /* Return the DER data. */
6727 *data = der;
6728 *len = derLen;
6729 }
6730 }
6731
6732 return ret;
6733}
6734
6735/* Encode the DER data in PEM format into a newly allocated buffer.
6736 *
6737 * @param [in] name Header/footer name.
6738 * @param [in] header Encryption header.
6739 * @param [in] data DER data.
6740 * @param [in] len Length of DER data.
6741 * @param [out] pemOut PEM encoded data.
6742 * @param [out] pemOutLen Length of PEM encoded data.
6743 * @return 0 on success.
6744 * @return MEMORY_E when dynamic memory allocation fails.
6745 */
6746static int pem_write_data(const char *name, const char *header,
6747 const unsigned char *data, long len, char** pemOut, word32* pemOutLen)
6748{
6749 int ret = 0;
6750 int nameLen;
6751 int headerLen;
6752 char* pem = NULL;
6753 word32 pemLen;
6754 word32 derLen = (word32)len;
6755 byte* p;
6756
6757 nameLen = (int)XSTRLEN(name);
6758 headerLen = (int)XSTRLEN(header);
6759
6760 /* DER encode for PEM. */
6761 pemLen = (derLen + 2) / 3 * 4;
6762 pemLen += (pemLen + 63) / 64;
6763 /* Header */
6764 pemLen += (word32)(PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
6765 if (headerLen > 0) {
6766 /* Encryption lines plus extra carriage return. */
6767 pemLen += (word32)headerLen + 1;
6768 }
6769 /* Trailer */
6770 pemLen += (word32)(PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ);
6771
6772 pem = (char*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6773 if (pem == NULL) {
6774 ret = MEMORY_E;
6775 }
6776 p = (byte*)pem;
6777
6778 if (ret == 0) {
6779 /* Add header. */
6780 XMEMCPY(p, PEM_BEGIN, PEM_BEGIN_SZ);
6781 p += PEM_BEGIN_SZ;
6782 XMEMCPY(p, name, (size_t)nameLen);
6783 p += nameLen;
6784 XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
6785 p += PEM_HDR_FIN_EOL_SZ;
6786
6787 if (headerLen > 0) {
6788 /* Add encryption header. */
6789 XMEMCPY(p, header, (size_t)headerLen);
6790 p += headerLen;
6791 /* Blank line after a header and before body. */
6792 *(p++) = '\n';
6793 }
6794
6795 /* Add DER data as PEM. */
6796 pemLen -= (word32)((size_t)p - (size_t)pem);
6797 ret = Base64_Encode(data, derLen, p, &pemLen);
6798 }
6799 if (ret == 0) {
6800 p += pemLen;
6801
6802 /* Add trailer. */
6803 XMEMCPY(p, PEM_END, PEM_END_SZ);
6804 p += PEM_END_SZ;
6805 XMEMCPY(p, name, (size_t)nameLen);
6806 p += nameLen;
6807 XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ);
6808 p += PEM_HDR_FIN_EOL_SZ;
6809
6810 /* Return buffer and length of data. */
6811 *pemOut = pem;
6812 *pemOutLen = (word32)((size_t)p - (size_t)pem);
6813 }
6814 else {
6815 /* Dispose of any allocated memory. */
6816 XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6817 pem = NULL;
6818 }
6819
6820 return ret;
6821}
6822#endif /* !NO_BIO || !NO_FILESYSTEM */
6823
6824#ifndef NO_BIO
6825/* Read PEM encoded data from a BIO.
6826 *
6827 * Reads the entire contents in.
6828 *
6829 * @param [in] bio BIO to read from.
6830 * @param [out] name Name of content type.
6831 * @param [out] header Encryption headers.
6832 * @param [out] data DER encoding from PEM.
6833 * @param [out] len Length of DER data.
6834 * @return 1 on success.
6835 * @return 0 on failure.
6836 */
6837int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
6838 unsigned char **data, long *len)
6839{
6840 int res = 1;
6841 char* pem = NULL;
6842 int pemLen = 0;
6843 int memAlloced = 1;
6844
6845 /* Validate parameters. */
6846 if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL) ||
6847 (len == NULL)) {
6848 res = 0;
6849 }
6850
6851 /* Load all the data from the BIO. */
6852 if ((res == 1) && (wolfssl_read_bio(bio, &pem, &pemLen, &memAlloced) !=
6853 0)) {
6854 res = 0;
6855 }
6856 if ((res == 1) && (!memAlloced)) {
6857 /* Need to return allocated memory - make sure it is allocated. */
6858 char* p = (char*)XMALLOC((size_t)pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6859 if (p == NULL) {
6860 res = 0;
6861 }
6862 else {
6863 /* Copy the data into new buffer. */
6864 XMEMCPY(p, pem, (size_t)pemLen);
6865 pem = p;
6866 }
6867 }
6868
6869 /* Read the PEM data. */
6870 if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
6871 0)) {
6872 /* Dispose of any allocated memory. */
6873 XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6874 XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6875 XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6876 *name = NULL;
6877 *header = NULL;
6878 res = 0;
6879 }
6880
6881 return res;
6882}
6883
6884/* Encode the DER data in PEM format into a BIO.
6885 *
6886 * @param [in] bio BIO to write to.
6887 * @param [in] name Header/footer name.
6888 * @param [in] header Encryption header.
6889 * @param [in] data DER data.
6890 * @param [in] len Length of DER data.
6891 * @return 0 on failure.
6892 */
6893int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name,
6894 const char *header, const unsigned char *data, long len)
6895{
6896 int err = 0;
6897 char* pem = NULL;
6898 word32 pemLen = 0;
6899
6900 /* Validate parameters. */
6901 if ((bio == NULL) || (name == NULL) || (header == NULL) || (data == NULL)) {
6902 err = BAD_FUNC_ARG;
6903 }
6904
6905 /* Encode into a buffer. */
6906 if (!err) {
6907 err = pem_write_data(name, header, data, len, &pem, &pemLen);
6908 }
6909
6910 /* Write PEM into BIO. */
6911 if ((!err) && (wolfSSL_BIO_write(bio, pem, (int)pemLen) != (int)pemLen)) {
6912 err = IO_FAILED_E;
6913 }
6914
6915 XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6916 return (!err) ? (int)pemLen : 0;
6917}
6918#endif /* !NO_BIO */
6919
6920#if !defined(NO_FILESYSTEM)
6921/* Read PEM encoded data from a file.
6922 *
6923 * Reads the entire contents in.
6924 *
6925 * @param [in] bio BIO to read from.
6926 * @param [out] name Name of content type.
6927 * @param [out] header Encryption headers.
6928 * @param [out] data DER encoding from PEM.
6929 * @param [out] len Length of DER data.
6930 * @return 1 on success.
6931 * @return 0 on failure.
6932 */
6933int wolfSSL_PEM_read(XFILE fp, char **name, char **header, unsigned char **data,
6934 long *len)
6935{
6936 int res = 1;
6937 char* pem = NULL;
6938 int pemLen = 0;
6939
6940 /* Validate parameters. */
6941 if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
6942 (data == NULL) || (len == NULL)) {
6943 res = 0;
6944 }
6945
6946 /* Load all the data from the file. */
6947 if ((res == 1) && (wolfssl_read_file(fp, &pem, &pemLen) != 0)) {
6948 res = 0;
6949 }
6950
6951 /* Read the PEM data. */
6952 if ((res == 1) && (pem_read_data(pem, pemLen, name, header, data, len) !=
6953 0)) {
6954 /* Dispose of any allocated memory. */
6955 XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6956 XFREE(*name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6957 XFREE(*header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
6958 *name = NULL;
6959 *header = NULL;
6960 res = 0;
6961 }
6962
6963 return res;
6964}
6965
6966/* Encode the DER data in PEM format into a file.
6967 *
6968 * @param [in] fp File pointer to write to.
6969 * @param [in] name Header/footer name.
6970 * @param [in] header Encryption header.
6971 * @param [in] data DER data.
6972 * @param [in] len Length of DER data.
6973 * @return 0 on success.
6974 * @return MEMORY_E when dynamic memory allocation fails.
6975 */
6976int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
6977 const unsigned char *data, long len)
6978{
6979 int err = 0;
6980 char* pem = NULL;
6981 word32 pemLen = 0;
6982
6983 /* Validate parameters. */
6984 if ((fp == XBADFILE) || (name == NULL) || (header == NULL) ||
6985 (data == NULL)) {
6986 err = 1;
6987 }
6988
6989 /* Encode into a buffer. */
6990 if ((!err) && (pem_write_data(name, header, data, len, &pem, &pemLen) !=
6991 0)) {
6992 pemLen = 0;
6993 err = 1;
6994 }
6995
6996 /* Write PEM to a file. */
6997 if ((!err) && (XFWRITE(pem, 1, pemLen, fp) != pemLen)) {
6998 pemLen = 0;
6999 }
7000
7001 XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7002 return (int)pemLen;
7003}
7004#endif
7005
7006/* Get EVP cipher info from encryption header string.
7007 *
7008 * @param [in] header Encryption header.
7009 * @param [out] cipher EVP Cipher info.
7010 * @return 1 on success.
7011 * @return 0 on failure.
7012 */
7013int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header, EncryptedInfo* cipher)
7014{
7015 int res = 1;
7016
7017 /* Validate parameters. */
7018 if ((header == NULL) || (cipher == NULL)) {
7019 res = 0;
7020 }
7021
7022 if (res == 1) {
7023 XMEMSET(cipher, 0, sizeof(*cipher));
7024
7025 if (wc_EncryptedInfoParse(cipher, &header, XSTRLEN(header)) != 0) {
7026 res = 0;
7027 }
7028 }
7029
7030 return res;
7031}
7032
7033/* Apply cipher to DER data.
7034 *
7035 * @param [in] cipher EVP cipher info.
7036 * @param [in, out] data On in, encrypted DER data.
7037 * On out, unencrypted DER data.
7038 * @param [in, out] len On in, length of encrypted DER data.
7039 * On out, length of unencrypted DER data.
7040 * @param [in] cb Password callback.
7041 * @param [in] ctx Context for password callback.
7042 * @return 1 on success.
7043 * @return 0 on failure.
7044 */
7045int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len,
7046 wc_pem_password_cb* cb, void* ctx)
7047{
7048 int ret = 1;
7049 char password[NAME_SZ];
7050 int passwordSz = 0;
7051
7052 /* Validate parameters. */
7053 if ((cipher == NULL) || (data == NULL) || (len == NULL) || (cb == NULL)) {
7054 ret = 0;
7055 }
7056
7057 if (ret == 1) {
7058 /* Get password and length. */
7059 passwordSz = cb(password, sizeof(password), PEM_PASS_READ, ctx);
7060 if (passwordSz < 0) {
7061 ret = 0;
7062 }
7063 }
7064
7065 if (ret == 1) {
7066 /* Decrypt the data using password and MD5. */
7067 if (wc_BufferKeyDecrypt(cipher, data, (word32)*len, (byte*)password,
7068 passwordSz, WC_MD5) != 0) {
7069 ret = WOLFSSL_FAILURE;
7070 }
7071 }
7072
7073 if (passwordSz > 0) {
7074 /* Ensure password is erased from memory. */
7075 ForceZero(password, (word32)passwordSz);
7076 }
7077
7078 return ret;
7079}
7080
7081#endif /* !NO_CERTS */
7082#endif /* OPENSSL_EXTRA */
7083
7084#ifdef OPENSSL_ALL
7085#if !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
7086
7087/* Encrypt the key into a buffer using PKCS$8 and a password.
7088 *
7089 * @param [in] pkey Private key to encrypt.
7090 * @param [in] enc EVP cipher.
7091 * @param [in] passwd Password to encrypt with.
7092 * @param [in] passwdSz Number of bytes in password.
7093 * @param [in] key Buffer to hold encrypted key.
7094 * @param [in, out] keySz On in, size of buffer in bytes.
7095 * On out, size of encrypted key in bytes.
7096 * @return 0 on success.
7097 * @return BAD_FUNC_ARG when EVP cipher not supported.
7098 */
7099int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
7100 const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, byte* key,
7101 word32* keySz)
7102{
7103 int ret;
7104 WC_RNG rng;
7105
7106 /* Initialize a new random number generator. */
7107 ret = wc_InitRng(&rng);
7108 if (ret == 0) {
7109 int encAlgId = 0;
7110
7111 /* Convert EVP cipher to a support encryption id. */
7112 #ifndef NO_DES3
7113 if (enc == EVP_DES_CBC) {
7114 encAlgId = DESb;
7115 }
7116 else if (enc == EVP_DES_EDE3_CBC) {
7117 encAlgId = DES3b;
7118 }
7119 else
7120 #endif
7121#if !defined(NO_AES) && defined(HAVE_AES_CBC)
7122 #ifdef WOLFSSL_AES_128
7123 if (enc == EVP_AES_128_CBC) {
7124 encAlgId = AES128CBCb;
7125 }
7126 else
7127 #endif
7128 #ifdef WOLFSSL_AES_256
7129 if (enc == EVP_AES_256_CBC) {
7130 encAlgId = AES256CBCb;
7131 }
7132 else
7133 #endif
7134#endif
7135 {
7136 ret = BAD_FUNC_ARG;
7137 }
7138
7139 if (ret == 0) {
7140 /* Encrypt private into buffer. */
7141 ret = TraditionalEnc((byte*)pkey->pkey.ptr + pkey->pkcs8HeaderSz,
7142 (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
7143 key, keySz, passwd, passwdSz, PKCS5, PBES2, encAlgId,
7144 NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL);
7145 if (ret > 0) {
7146 *keySz = (word32)ret;
7147 }
7148 }
7149 /* Dispose of random number generator. */
7150 wc_FreeRng(&rng);
7151 }
7152
7153 return ret;
7154}
7155
7156/* Encode private key in PKCS#8 format.
7157 *
7158 * @param [in] pkey Private key.
7159 * @param [out] key Buffer to hold encoding.
7160 * @param [in, out] keySz On in, size of buffer in bytes.
7161 * @param On out, size of encoded key in bytes.
7162 * @return 0 on success.
7163 */
7164int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
7165{
7166 int ret = 0;
7167 int algId = 0;
7168 const byte* curveOid = 0;
7169 word32 oidSz = 0;
7170
7171 /* Get the details of the private key. */
7172#ifdef HAVE_ECC
7173 if (pkey->type == WC_EVP_PKEY_EC) {
7174 /* ECC private and get curve OID information. */
7175 algId = ECDSAk;
7176 ret = wc_ecc_get_oid((word32)pkey->ecc->group->curve_oid, &curveOid,
7177 &oidSz);
7178 }
7179 else
7180#endif
7181 if (pkey->type == WC_EVP_PKEY_RSA) {
7182 /* RSA private has no curve information. */
7183 algId = RSAk;
7184 curveOid = NULL;
7185 oidSz = 0;
7186 }
7187 else if (pkey->type == WC_EVP_PKEY_DSA) {
7188 /* DSA has no curve information. */
7189 algId = DSAk;
7190 curveOid = NULL;
7191 oidSz = 0;
7192 }
7193#ifndef NO_DH
7194 else if (pkey->type == WC_EVP_PKEY_DH) {
7195 if (pkey->dh == NULL)
7196 return BAD_FUNC_ARG;
7197
7198 if (pkey->dh->priv_key != NULL || pkey->dh->pub_key != NULL) {
7199 /* Special case. DH buffer is always in PKCS8 format */
7200 if (keySz == NULL)
7201 return BAD_FUNC_ARG;
7202
7203 *keySz = (word32)pkey->pkey_sz;
7204 if (key == NULL)
7205 return LENGTH_ONLY_E;
7206
7207 XMEMCPY(key, pkey->pkey.ptr, pkey->pkey_sz);
7208 return pkey->pkey_sz;
7209 }
7210
7211 /* DH has no curve information. */
7212 algId = DHk;
7213 curveOid = NULL;
7214 oidSz = 0;
7215 }
7216#endif
7217 else {
7218 ret = NOT_COMPILED_IN;
7219 }
7220
7221 if (ret >= 0) {
7222 /* Encode private key in PKCS#8 format. */
7223 ret = wc_CreatePKCS8Key(key, keySz, (byte*)pkey->pkey.ptr +
7224 pkey->pkcs8HeaderSz, (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz,
7225 algId, curveOid, oidSz);
7226 }
7227
7228 return ret;
7229}
7230
7231#if !defined(NO_BIO) || (!defined(NO_FILESYSTEM) && \
7232 !defined(NO_STDIO_FILESYSTEM))
7233/* Write PEM encoded, PKCS#8 formatted private key to BIO.
7234 *
7235 * @param [out] pem Buffer holding PEM encoding.
7236 * @param [out] pemSz Size of data in buffer in bytes.
7237 * @param [in] pkey Private key to write.
7238 * @param [in] enc Encryption information to use. May be NULL.
7239 * @param [in] passwd Password to use when encrypting. May be NULL.
7240 * @param [in] passwdSz Size of password in bytes.
7241 * @param [in] cb Password callback. Used when passwd is NULL. May be
7242 * NULL.
7243 * @param [in] ctx Context for password callback.
7244 * @return Length of PEM encoding on success.
7245 * @return 0 on failure.
7246 */
7247static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
7248 WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
7249 int passwdSz, wc_pem_password_cb* cb, void* ctx)
7250{
7251 int res = 1;
7252 int ret = 0;
7253 char password[NAME_SZ];
7254 byte* key = NULL;
7255 word32 keySz = 0;
7256 word32 allocSz = 0;
7257 int type = PKCS8_PRIVATEKEY_TYPE;
7258
7259 /* Validate parameters. */
7260 if (pkey == NULL) {
7261 res = 0;
7262 }
7263
7264 if (res == 1) {
7265 /* Guestimate key size and PEM size. */
7266 if (pkcs8_encode(pkey, NULL, &keySz) !=
7267 WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
7268 res = 0;
7269 }
7270 }
7271 if (res == 1) {
7272 if (enc != NULL) {
7273 /* Add on enough for extra DER data when encrypting. */
7274 keySz += 128;
7275 }
7276 /* PEM encoding size from DER size. */
7277 *pemSz = (int)(keySz + 2) / 3 * 4;
7278 *pemSz += (*pemSz + 63) / 64;
7279 /* Header and footer. */
7280 if (enc != NULL) {
7281 /* Name is: 'ENCRYPTED PRIVATE KEY'. */
7282 *pemSz += 74;
7283 }
7284 else {
7285 /* Name is: 'PRIVATE KEY'. */
7286 *pemSz += 54;
7287 }
7288
7289 allocSz = (word32)*pemSz;
7290 /* Allocate enough memory to hold PEM encoded encrypted key. */
7291 *pem = (byte*)XMALLOC((size_t)allocSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7292 if (*pem == NULL) {
7293 allocSz = 0;
7294 res = 0;
7295 }
7296 else {
7297 /* Use end of PEM buffer for key data. */
7298 key = *pem + *pemSz - keySz;
7299 }
7300 }
7301
7302 if ((res == 1) && (enc != NULL)) {
7303 /* Set type for PEM. */
7304 type = PKCS8_ENC_PRIVATEKEY_TYPE;
7305
7306 if (passwd == NULL) {
7307 /* Get the password by using callback. */
7308 passwdSz = cb(password, sizeof(password), 1, ctx);
7309 if (passwdSz < 0) {
7310 res = 0;
7311 }
7312 passwd = password;
7313 }
7314
7315 if (res == 1) {
7316 /* Encrypt the private key. */
7317 ret = pkcs8_encrypt(pkey, enc, passwd, passwdSz, key, &keySz);
7318 if (ret <= 0) {
7319 res = 0;
7320 }
7321 }
7322
7323 /* Zeroize the password from memory. */
7324 if ((password == passwd) && (passwdSz > 0)) {
7325 ForceZero(password, (word32)passwdSz);
7326 }
7327 }
7328 else if ((res == 1) && (enc == NULL)) {
7329 /* Set type for PEM. */
7330 type = PKCS8_PRIVATEKEY_TYPE;
7331
7332 /* Encode private key in PKCS#8 format. */
7333 ret = pkcs8_encode(pkey, key, &keySz);
7334 if (ret < 0) {
7335 res = 0;
7336 }
7337 }
7338
7339 if (res == 1) {
7340 /* Encode PKCS#8 formatted key to PEM. */
7341 ret = wc_DerToPemEx(key, keySz, *pem, (word32)*pemSz, NULL, type);
7342 if (ret < 0) {
7343 res = 0;
7344 }
7345 else {
7346 *pemSz = ret;
7347 }
7348 }
7349
7350 /* Zero any remnants of the DER staging area that persist after PEM
7351 * conversion so plaintext private key material is not left in freed heap
7352 * memory. On success, only the bytes past the actual PEM output need
7353 * clearing; on failure, the whole buffer is zeroed since its state is
7354 * indeterminate. */
7355 if (*pem != NULL) {
7356 if (res == 1 && (word32)*pemSz < allocSz) {
7357 ForceZero(*pem + *pemSz, allocSz - (word32)*pemSz);
7358 }
7359 else if (res != 1) {
7360 ForceZero(*pem, allocSz);
7361 }
7362 }
7363
7364 /* Return appropriate return code. */
7365 return (res == 0) ? 0 : ret;
7366
7367}
7368#endif /* !NO_BIO || (!NO_FILESYSTEM && !NO_STDIO_FILESYSTEM) */
7369
7370#ifndef NO_BIO
7371/* Write PEM encoded, PKCS#8 formatted private key to BIO.
7372 *
7373 * TODO: OpenSSL returns 1 and 0 only.
7374 *
7375 * @param [in] bio BIO to write to.
7376 * @param [in] pkey Private key to write.
7377 * @param [in] enc Encryption information to use. May be NULL.
7378 * @param [in] passwd Password to use when encrypting. May be NULL.
7379 * @param [in] passwdSz Size of password in bytes.
7380 * @param [in] cb Password callback. Used when passwd is NULL. May be
7381 * NULL.
7382 * @param [in] ctx Context for password callback.
7383 * @return Length of PEM encoding on success.
7384 * @return 0 on failure.
7385 */
7386int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
7387 WOLFSSL_EVP_PKEY* pkey, const WOLFSSL_EVP_CIPHER* enc, char* passwd,
7388 int passwdSz, wc_pem_password_cb* cb, void* ctx)
7389{
7390 byte* pem = NULL;
7391 int pemSz = 0;
7392 int res = 1;
7393
7394 /* Validate parameters. */
7395 if (bio == NULL) {
7396 res = 0;
7397 }
7398 if (res == 1) {
7399 /* Write private key to memory. */
7400 res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
7401 passwdSz, cb, ctx);
7402 }
7403
7404 /* Write encoded key to BIO. */
7405 if ((res >= 1) && (wolfSSL_BIO_write(bio, pem, pemSz) != pemSz)) {
7406 res = 0;
7407 }
7408
7409 /* Dispose of dynamically allocated memory (pem and key). */
7410 XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7411 return res;
7412}
7413
7414int wolfSSL_PEM_write_bio_PKCS8_PRIV_KEY_INFO(WOLFSSL_BIO* bio,
7415 PKCS8_PRIV_KEY_INFO* keyInfo)
7416{
7417 return wolfSSL_PEM_write_bio_PKCS8PrivateKey(bio, keyInfo, NULL, NULL, 0,
7418 NULL, NULL);
7419}
7420#endif /* !NO_BIO */
7421
7422#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
7423/* Write PEM encoded, PKCS#8 formatted private key to BIO.
7424 *
7425 * TODO: OpenSSL returns 1 and 0 only.
7426 *
7427 * @param [in] f File pointer.
7428 * @param [in] pkey Private key to write.
7429 * @param [in] enc Encryption information to use. May be NULL.
7430 * @param [in] passwd Password to use when encrypting. May be NULL.
7431 * @param [in] passwdSz Size of password in bytes.
7432 * @param [in] cb Password callback. Used when passwd is NULL. May be
7433 * NULL.
7434 * @param [in] ctx Context for password callback.
7435 * @return Length of PEM encoding on success.
7436 * @return 0 on failure.
7437 */
7438int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey,
7439 const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz,
7440 wc_pem_password_cb* cb, void* ctx)
7441{
7442 byte* pem = NULL;
7443 int pemSz = 0;
7444 int res = 1;
7445
7446 /* Validate parameters. */
7447 if (f == XBADFILE) {
7448 res = 0;
7449 }
7450 if (res == 1) {
7451 /* Write private key to memory. */
7452 res = pem_write_mem_pkcs8privatekey(&pem, &pemSz, pkey, enc, passwd,
7453 passwdSz, cb, ctx);
7454 }
7455
7456 /* Write encoded key to file. */
7457 if ((res >= 1) && (XFWRITE(pem, 1, (size_t)pemSz, f) != (size_t)pemSz)) {
7458 res = 0;
7459 }
7460
7461 /* Dispose of dynamically allocated memory (pem and key). */
7462 XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7463 return res;
7464}
7465#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
7466
7467#endif /* !NO_PWDBASED && HAVE_PKCS8 */
7468#endif /* OPENSSL_ALL */
7469
7470/*******************************************************************************
7471 * END OF GENERIC PUBLIC KEY PEM APIs
7472 ******************************************************************************/
7473
7474#endif /* !WOLFSSL_PK_INCLUDED */