cjson
.github
workflows CI.yml ci-fuzz.yml
CONTRIBUTING.md
fuzzing
inputs test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9
.gitignore CMakeLists.txt afl-prepare-linux.sh afl.c afl.sh cjson_read_fuzzer.c fuzz_main.c json.dict ossfuzz.sh
library_config cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmake
tests
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.expected
json-patch-tests .editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.json
unity
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.py
docs ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txt
examples
example_1
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_2
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_3
helper UnityHelper.c UnityHelper.h
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
rakefile.rb rakefile_helper.rb readme.txt target_gcc_32.yml
unity_config.h
extras
eclipse error_parsers.txt
fixture
src unity_fixture.c unity_fixture.h unity_fixture_internals.h unity_fixture_malloc_overrides.h
rakefile.rb rakefile_helper.rb readme.txt
release build.info version.info
src unity.c unity.h unity_internals.h
.gitattributes .gitignore .travis.yml README.md
CMakeLists.txt cjson_add.c common.h compare_tests.c json_patch_tests.c minify_tests.c misc_tests.c misc_utils_tests.c old_utils_tests.c parse_array.c parse_examples.c parse_hex4.c parse_number.c parse_object.c parse_string.c parse_value.c parse_with_opts.c print_array.c print_number.c print_object.c print_string.c print_value.c readme_examples.c unity_setup.c
.editorconfig .gitattributes .gitignore .travis.yml CHANGELOG.md CMakeLists.txt CONTRIBUTORS.md LICENSE Makefile README.md SECURITY.md appveyor.yml cJSON.c cJSON.h cJSON_Utils.c cJSON_Utils.h test.c valgrind.supp
curl
.circleci config.yml
.github
ISSUE_TEMPLATE bug_report.yml config.yml docs.yml
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.yaml
workflows 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.yml
CODEOWNERS CONTRIBUTING.md FUNDING.yml dependabot.yml labeler.yml lock.yml stale.yml
CMake 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.cmake
LICENSES BSD-4-Clause-UC.txt ISC.txt curl.txt
docs
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.md
examples .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.c
internals 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.md
libcurl
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.inc
.gitignore ABI.md CMakeLists.txt Makefile.am Makefile.inc curl_easy_cleanup.md curl_easy_duphandle.md curl_easy_escape.md curl_easy_getinfo.md curl_easy_header.md curl_easy_init.md curl_easy_nextheader.md curl_easy_option_by_id.md curl_easy_option_by_name.md curl_easy_option_next.md curl_easy_pause.md curl_easy_perform.md curl_easy_recv.md curl_easy_reset.md curl_easy_send.md curl_easy_setopt.md curl_easy_ssls_export.md curl_easy_ssls_import.md curl_easy_strerror.md curl_easy_unescape.md curl_easy_upkeep.md curl_escape.md curl_formadd.md curl_formfree.md curl_formget.md curl_free.md curl_getdate.md curl_getenv.md curl_global_cleanup.md curl_global_init.md curl_global_init_mem.md curl_global_sslset.md curl_global_trace.md curl_mime_addpart.md curl_mime_data.md curl_mime_data_cb.md curl_mime_encoder.md curl_mime_filedata.md curl_mime_filename.md curl_mime_free.md curl_mime_headers.md curl_mime_init.md curl_mime_name.md curl_mime_subparts.md curl_mime_type.md curl_mprintf.md curl_multi_add_handle.md curl_multi_assign.md curl_multi_cleanup.md curl_multi_fdset.md curl_multi_get_handles.md curl_multi_get_offt.md curl_multi_info_read.md curl_multi_init.md curl_multi_notify_disable.md curl_multi_notify_enable.md curl_multi_perform.md curl_multi_poll.md curl_multi_remove_handle.md curl_multi_setopt.md curl_multi_socket.md curl_multi_socket_action.md curl_multi_socket_all.md curl_multi_strerror.md curl_multi_timeout.md curl_multi_wait.md curl_multi_waitfds.md curl_multi_wakeup.md curl_pushheader_byname.md curl_pushheader_bynum.md curl_share_cleanup.md curl_share_init.md curl_share_setopt.md curl_share_strerror.md curl_slist_append.md curl_slist_free_all.md curl_strequal.md curl_strnequal.md curl_unescape.md curl_url.md curl_url_cleanup.md curl_url_dup.md curl_url_get.md curl_url_set.md curl_url_strerror.md curl_version.md curl_version_info.md curl_ws_meta.md curl_ws_recv.md curl_ws_send.md curl_ws_start_frame.md libcurl-easy.md libcurl-env-dbg.md libcurl-env.md libcurl-errors.md libcurl-multi.md libcurl-security.md libcurl-share.md libcurl-thread.md libcurl-tutorial.md libcurl-url.md libcurl-ws.md libcurl.m4 libcurl.md mksymbolsmanpage.pl symbols-in-versions symbols.pl
tests CI.md FILEFORMAT.md HTTP.md TEST-SUITE.md
.gitignore ALTSVC.md BINDINGS.md BUG-BOUNTY.md BUGS.md CIPHERS-TLS12.md CIPHERS.md CMakeLists.txt CODE_OF_CONDUCT.md CODE_REVIEW.md CONTRIBUTE.md CURL-DISABLE.md CURLDOWN.md DEPRECATE.md DISTROS.md EARLY-RELEASE.md ECH.md EXPERIMENTAL.md FAQ.md FEATURES.md GOVERNANCE.md HELP-US.md HISTORY.md HSTS.md HTTP-COOKIES.md HTTP3.md HTTPSRR.md INFRASTRUCTURE.md INSTALL-CMAKE.md INSTALL.md INTERNALS.md IPFS.md KNOWN_BUGS.md KNOWN_RISKS.md MAIL-ETIQUETTE.md MANUAL.md Makefile.am README.md RELEASE-PROCEDURE.md ROADMAP.md RUSTLS.md SECURITY-ADVISORY.md SPONSORS.md SSL-PROBLEMS.md SSLCERTS.md THANKS THANKS-filter TODO.md TheArtOfHttpScripting.md URL-SYNTAX.md VERIFY.md VERSIONS.md VULN-DISCLOSURE-POLICY.md curl-config.md mk-ca-bundle.md options-in-versions runtests.md testcurl.md wcurl.md
include
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.h
Makefile.am README.md
lib
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.h
vauth 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.h
vquic curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.h
vssh libssh.c libssh2.c ssh.h vssh.c vssh.h
vtls 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.h
.gitignore CMakeLists.txt Makefile.am Makefile.inc Makefile.soname altsvc.c altsvc.h amigaos.c amigaos.h arpa_telnet.h asyn-ares.c asyn-base.c asyn-thrdd.c asyn.h bufq.c bufq.h bufref.c bufref.h cf-dns.c cf-dns.h cf-h1-proxy.c cf-h1-proxy.h cf-h2-proxy.c cf-h2-proxy.h cf-haproxy.c cf-haproxy.h cf-https-connect.c cf-https-connect.h cf-ip-happy.c cf-ip-happy.h cf-socket.c cf-socket.h cfilters.c cfilters.h config-mac.h config-os400.h config-riscos.h config-win32.h conncache.c conncache.h connect.c connect.h content_encoding.c content_encoding.h cookie.c cookie.h creds.c creds.h cshutdn.c cshutdn.h curl_addrinfo.c curl_addrinfo.h curl_config-cmake.h.in curl_ctype.h curl_endian.c curl_endian.h curl_fnmatch.c curl_fnmatch.h curl_fopen.c curl_fopen.h curl_get_line.c curl_get_line.h curl_gethostname.c curl_gethostname.h curl_gssapi.c curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memrchr.c curl_memrchr.h curl_ntlm_core.c curl_ntlm_core.h curl_printf.h curl_range.c curl_range.h curl_sasl.c curl_sasl.h curl_setup.h curl_sha256.h curl_sha512_256.c curl_sha512_256.h curl_share.c curl_share.h curl_sspi.c curl_sspi.h curl_threads.c curl_threads.h curl_trc.c curl_trc.h cw-out.c cw-out.h cw-pause.c cw-pause.h dict.c dict.h dllmain.c dnscache.c dnscache.h doh.c doh.h dynhds.c dynhds.h easy.c easy_lock.h easygetopt.c easyif.h easyoptions.c easyoptions.h escape.c escape.h fake_addrinfo.c fake_addrinfo.h file.c file.h fileinfo.c fileinfo.h formdata.c formdata.h ftp-int.h ftp.c ftp.h ftplistparser.c ftplistparser.h functypes.h getenv.c getinfo.c getinfo.h gopher.c gopher.h hash.c hash.h headers.c headers.h hmac.c hostip.c hostip.h hostip4.c hostip6.c hsts.c hsts.h http.c http.h http1.c http1.h http2.c http2.h http_aws_sigv4.c http_aws_sigv4.h http_chunks.c http_chunks.h http_digest.c http_digest.h http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h http_proxy.c http_proxy.h httpsrr.c httpsrr.h idn.c idn.h if2ip.c if2ip.h imap.c imap.h ldap.c libcurl.def libcurl.rc libcurl.vers.in llist.c llist.h macos.c macos.h md4.c md5.c memdebug.c mime.c mime.h mprintf.c mqtt.c mqtt.h multi.c multi_ev.c multi_ev.h multi_ntfy.c multi_ntfy.h multihandle.h multiif.h netrc.c netrc.h noproxy.c noproxy.h openldap.c optiontable.pl parsedate.c parsedate.h peer.c peer.h pingpong.c pingpong.h pop3.c pop3.h progress.c progress.h protocol.c protocol.h psl.c psl.h rand.c rand.h ratelimit.c ratelimit.h request.c request.h rtsp.c rtsp.h select.c select.h sendf.c sendf.h setopt.c setopt.h setup-os400.h setup-vms.h setup-win32.h sha256.c sigpipe.h slist.c slist.h smb.c smb.h smtp.c smtp.h sockaddr.h socketpair.c socketpair.h socks.c socks.h socks_gssapi.c socks_sspi.c splay.c splay.h strcase.c strcase.h strequal.c strerror.c strerror.h system_win32.c system_win32.h telnet.c telnet.h tftp.c tftp.h thrdpool.c thrdpool.h thrdqueue.c thrdqueue.h transfer.c transfer.h uint-bset.c uint-bset.h uint-hash.c uint-hash.h uint-spbset.c uint-spbset.h uint-table.c uint-table.h url.c url.h urlapi-int.h urlapi.c urldata.h version.c ws.c ws.h
m4 .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.m4
projects
OS400
rpg-examples HEADERAPI HTTPPOST INMEMORY SIMPLE1 SIMPLE2 SMTPSRCMBR
.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.h
Windows
tmpl .gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filters
.gitignore README.md generate.bat
vms 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.h
Makefile.am README.md
scripts .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 wcurl
src
toolx tool_time.c tool_time.h
.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.h
tests
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.prm
cmake CMakeLists.txt test.c test.cpp test.sh
data .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 test999
http
testenv
mod_curltest .gitignore mod_curltest.c
__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.py
.gitignore CMakeLists.txt Makefile.am config.ini.in conftest.py requirements.txt scorecard.py test_01_basic.py test_02_download.py test_03_goaway.py test_04_stuttered.py test_05_errors.py test_06_eyeballs.py test_07_upload.py test_08_caddy.py test_09_push.py test_10_proxy.py test_11_unix.py test_12_reuse.py test_13_proxy_auth.py test_14_auth.py test_15_tracing.py test_16_info.py test_17_ssl_use.py test_18_methods.py test_19_shutdown.py test_20_websockets.py test_21_resolve.py test_22_httpsrr.py test_30_vsftpd.py test_31_vsftpds.py test_32_ftps_vsftpd.py test_40_socks.py test_50_scp.py test_51_sftp.py
libtest .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.h
server .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.c
tunit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.c
unit .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.c
.gitignore CMakeLists.txt Makefile.am allversions.pm appveyor.pm azure.pm config.in configurehelp.pm.in devtest.pl dictserver.py directories.pm ech_combos.py ech_tests.sh ftpserver.pl getpart.pm globalconfig.pm http-server.pl http2-server.pl http3-server.pl memanalyze.pl memanalyzer.pm negtelnetserver.py nghttpx.conf pathhelp.pm processhelp.pm requirements.txt rtspserver.pl runner.pm runtests.pl secureserver.pl serverhelp.pm servers.pm smbserver.py sshhelp.pm sshserver.pl test1119.pl test1135.pl test1139.pl test1140.pl test1165.pl test1167.pl test1173.pl test1175.pl test1177.pl test1222.pl test1275.pl test1276.pl test1477.pl test1486.pl test1488.pl test1544.pl test1707.pl test745.pl test971.pl testcurl.pl testutil.pm tftpserver.pl util.py valgrind.pm valgrind.supp
.clang-tidy.yml .dir-locals.el .editorconfig .git-blame-ignore-revs .gitattributes .gitignore .mailmap CHANGES.md CMakeLists.txt COPYING Dockerfile GIT-INFO.md Makefile.am README README.md RELEASE-NOTES REUSE.toml SECURITY.md acinclude.m4 appveyor.sh appveyor.yml configure.ac curl-config.in libcurl.pc.in renovate.json
examples .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.lua
iniparser
.github
ISSUE_TEMPLATE config.yml
workflows disable-pull-requests.yml trigger-gitlab-ci.yml
cmake JoinPaths.cmake config.cmake.in pc.in
example iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.ini
src dictionary.c dictionary.h iniparser.c iniparser.h
test
ressources
bad_ini ends_well.ini twisted-errors.ini twisted-ofkey.ini twisted-ofval.ini
good_ini empty.ini spaced.ini spaced2.ini twisted.ini
gruezi.ini old.ini quotes.ini utf8.ini
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.h
.cmake-format.py .gitignore .gitlab-ci.yml .gitmessage .travis.yml AUTHORS CMakeLists.txt FAQ-en.md FAQ-zhcn.md INSTALL LICENSE README.md compile_commands.json
jinjac
example CMakeLists.txt example.c
jinjac_test_app CMakeLists.txt jinjac_test_app.c
libjinjac
include jinjac.h
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.h
CMakeLists.txt
test .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.jinja
.gitignore CMakeLists.txt LICENSE.txt README.md build_coverage.sh build_debug.sh build_release.sh cppcheck_analysis.sh
libev 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-h1
luajit
doc
img contact.png
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.html
dynasm 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.lua
etc luajit.1 luajit.pc
src
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.c
jit .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.lua
.gitignore Makefile Makefile.dep lauxlib.h lib_aux.c lib_base.c lib_bit.c lib_buffer.c lib_debug.c lib_ffi.c lib_init.c lib_io.c lib_jit.c lib_math.c lib_os.c lib_package.c lib_string.c lib_table.c lj_alloc.c lj_alloc.h lj_api.c lj_arch.h lj_asm.c lj_asm.h lj_asm_arm.h lj_asm_arm64.h lj_asm_mips.h lj_asm_ppc.h lj_asm_x86.h lj_assert.c lj_bc.c lj_bc.h lj_bcdump.h lj_bcread.c lj_bcwrite.c lj_buf.c lj_buf.h lj_carith.c lj_carith.h lj_ccall.c lj_ccall.h lj_ccallback.c lj_ccallback.h lj_cconv.c lj_cconv.h lj_cdata.c lj_cdata.h lj_char.c lj_char.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_crecord.c lj_crecord.h lj_ctype.c lj_ctype.h lj_debug.c lj_debug.h lj_def.h lj_dispatch.c lj_dispatch.h lj_emit_arm.h lj_emit_arm64.h lj_emit_mips.h lj_emit_ppc.h lj_emit_x86.h lj_err.c lj_err.h lj_errmsg.h lj_ff.h lj_ffrecord.c lj_ffrecord.h lj_frame.h lj_func.c lj_func.h lj_gc.c lj_gc.h lj_gdbjit.c lj_gdbjit.h lj_ir.c lj_ir.h lj_ircall.h lj_iropt.h lj_jit.h lj_lex.c lj_lex.h lj_lib.c lj_lib.h lj_load.c lj_mcode.c lj_mcode.h lj_meta.c lj_meta.h lj_obj.c lj_obj.h lj_opt_dce.c lj_opt_fold.c lj_opt_loop.c lj_opt_mem.c lj_opt_narrow.c lj_opt_sink.c lj_opt_split.c lj_parse.c lj_parse.h lj_prng.c lj_prng.h lj_profile.c lj_profile.h lj_record.c lj_record.h lj_serialize.c lj_serialize.h lj_snap.c lj_snap.h lj_state.c lj_state.h lj_str.c lj_str.h lj_strfmt.c lj_strfmt.h lj_strfmt_num.c lj_strscan.c lj_strscan.h lj_tab.c lj_tab.h lj_target.h lj_target_arm.h lj_target_arm64.h lj_target_mips.h lj_target_ppc.h lj_target_x86.h lj_trace.c lj_trace.h lj_traceerr.h lj_udata.c lj_udata.h lj_vm.h lj_vmevent.c lj_vmevent.h lj_vmmath.c ljamalg.c lua.h lua.hpp luaconf.h luajit.c luajit_rolling.h lualib.h msvcbuild.bat nxbuild.bat ps4build.bat ps5build.bat psvitabuild.bat vm_arm.dasc vm_arm64.dasc vm_mips.dasc vm_mips64.dasc vm_ppc.dasc vm_x64.dasc vm_x86.dasc xb1build.bat xedkbuild.bat
.gitattributes .gitignore .relver COPYRIGHT Makefile README
sqlite shell.c sqlite3.c sqlite3.h sqlite3ext.h
wolfssl
.github
ISSUE_TEMPLATE bug_report.yaml other.yaml
actions
install-apt-deps action.yml
scripts
zephyr-4.x external_libc.conf zephyr-test.sh
openssl-ech.sh tls-anvil-test.sh
workflows
disabled haproxy.yml hitch.yml hostap.yml
hostap-files
configs
07c9f183ea744ac04585fb6dd10220c75a5e2e74 hostapd.config tests wpa_supplicant.config
b607d2723e927a3446d89aed813f1aa6068186bb hostapd.config tests wpa_supplicant.config
hostap_2_10 extra.patch hostapd.config tests wpa_supplicant.config
Makefile README dbus-wpa_supplicant.conf
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.yml
PULL_REQUEST_TEMPLATE.md SECURITY.md membrowse-targets.json
Docker
OpenWrt Dockerfile README.md runTests.sh
packaging
debian Dockerfile
fedora Dockerfile
wolfCLU Dockerfile README.md
yocto Dockerfile buildAndPush.sh
Dockerfile Dockerfile.cross-compiler README.md buildAndPush.sh include.am run.sh
IDE
ARDUINO
sketches
wolfssl_client README.md
wolfssl_server README.md
wolfssl_version README.md
README.md
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.h
AURIX Cpu0_Main.c README.md include.am user_settings.h wolf_main.c
Android Android.bp README.md include.am user_settings.h
CRYPTOCELL README.md include.am main.c user_settings.h
CSBENCH include.am user_settings.h
ECLIPSE
DEOS
deos_wolfssl .options
README.md deos_malloc.c include.am tls_wolfssl.c tls_wolfssl.h user_settings.h
MICRIUM README.md client_wolfssl.c client_wolfssl.h include.am server_wolfssl.c server_wolfssl.h user_settings.h wolfsslRunTests.c
RTTHREAD README.md include.am user_settings.h wolfssl_test.c
SIFIVE README.md include.am
Espressif
ESP-IDF
examples
template
VisualGDB wolfssl_template_IDF_v5.1_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_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.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_client
VisualGDB README.md wolfssl_client_IDF_v5_ESP32.sln wolfssl_client_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include client-tls.h main.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild client-tls.c component.mk main.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbproj
wolfssl_server
VisualGDB README.md wolfssl_server_IDF_v5_ESP32.sln wolfssl_server_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h server-tls.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild component.mk main.c server-tls.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbproj
wolfssl_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.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32 sdkconfig.defaults.esp32c3 sdkconfig.defaults.esp32c6 sdkconfig.defaults.esp32h2 sdkconfig.defaults.esp32s2 sdkconfig.defaults.esp32s3 sdkconfig.defaults.esp8266 testAll.sh testMonitor.sh wolfssl_test_ESP8266.sln wolfssl_test_ESP8266.vgdbproj
wolfssl_test_idf
VisualGDB VisualGDB_wolfssl_test_idf.sln VisualGDB_wolfssl_test_idf.vgdbproj
main CMakeLists.txt Kconfig.projbuild component.mk main.c main_wip.c.ex time_helper.c time_helper.h
CMakeLists.txt Kconfig.projbuild README.md component.mk sdkconfig.defaults
README.md
libs CMakeLists.txt README.md component.mk tigard.cfg
test CMakeLists.txt README.md component.mk test_wolfssl.c
README.md README_32se.md UPDATE.md compileAllExamples.sh dummy_config_h dummy_test_paths.h setup.sh setup_win.bat user_settings.h
README.md include.am
GCC-ARM
Header user_settings.h
Source armtarget.c benchmark_main.c test_main.c tls_client.c tls_server.c wolf_main.c
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ld
Gaisler-BCC README.md include.am
HEXAGON
DSP Makefile wolfssl_dsp.idl
Makefile README.md build.sh ecc-verify-benchmark.c ecc-verify.c include.am user_settings.h
HEXIWEAR
wolfSSL_HW .cwGeneratedFileSetLog user_settings.h
IAR-EWARM
Projects
benchmark benchmark-main.c current_time.c wolfCrypt-benchmark.ewd wolfCrypt-benchmark.ewp
common minimum-startup.c wolfssl.icf
lib wolfSSL-Lib.ewd wolfSSL-Lib.ewp
test test-main.c wolfCrypt-test.ewd wolfCrypt-test.ewp
user_settings.h wolfssl.eww
embOS
SAMV71_XULT
embOS_SAMV71_XULT_Linker_Script samv71q21_wolfssl.icf
embOS_SAMV71_XULT_user_settings user_settings.h user_settings_simple_example.h user_settings_verbose_example.h
embOS_wolfcrypt_benchmark_SAMV71_XULT
Application runBenchmarks.c
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewp
embOS_wolfcrypt_lib_SAMV71_XULT README_wolfcrypt_lib wolfcrypt_lib.ewd wolfcrypt_lib.ewp
embOS_wolfcrypt_test_SAMV71_XULT
Application runWolfcryptTests.c
README_wolfcrypt_test wolfcrypt_test.ewd wolfcrypt_test.ewp
README_SAMV71
custom_port
custom_port_Linker_Script samv71q21_wolfssl.icf
custom_port_user_settings user_settings.h
wolfcrypt_benchmark_custom_port
Application runBenchmarks.c
wolfcrypt_test_custom_port
Application runWolfcryptTests.c
README_custom_port
extract_trial_here README_extract_trial_here
README
.gitignore README
IAR-MSP430 Makefile README.md include.am main.c user_settings.h
INTIME-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.vcxproj
Infineon README.md include.am user_settings.h
KDS
config user_settings.h
include.am
LINUX-SGX README.md build.sh clean.sh include.am sgx_t_static.mk
LPCXPRESSO
lib_wolfssl lpc_18xx_port.c user_settings.h
wolf_example
src lpc_18xx_startup.c wolfssl_example.c
readme.txt
README.md
M68K
benchmark Makefile main.cpp
testwolfcrypt Makefile main.cpp
Makefile README.md include.am user_settings.h
MCUEXPRESSO
RT1170 fsl_caam_c.patch fsl_caam_h.patch user_settings.h
benchmark
source run_benchmark.c
wolfssl liblinks.xml
README.md include.am user_settings.h wolfcrypt_test.c
MDK-ARM
LPC43xx time-LCP43xx.c
MDK-ARM
wolfSSL Retarget.c cert_data.c cert_data.h config-BARE-METAL.h config-FS.h config-RTX-TCP-FS.h config-WOLFLIB.h main.c shell.c time-CortexM3-4.c time-dummy.c wolfssl_MDK_ARM.c wolfssl_MDK_ARM.h
STM32F2xx_StdPeriph_Lib time-STM32F2xx.c
MDK5-ARM
Conf user_settings.h
Inc wolfssl_MDK_ARM.h
Projects
CryptBenchmark Abstract.txt CryptBenchmark.sct CryptBenchmark.uvoptx CryptBenchmark.uvprojx main.c
CryptTest Abstract.txt CryptTest.sct CryptTest.uvoptx CryptTest.uvprojx main.c
EchoClient Abstract.txt EchoClient.uvoptx EchoClient.uvprojx main.c wolfssl-link.sct
EchoServer Abstract.txt EchoServer.uvoptx EchoServer.uvprojx main.c wolfssl-link.sct
SimpleClient Abstract.txt SimpleClient.uvoptx SimpleClient.uvprojx main.c wolfssl-link.sct
SimpleServer Abstract.txt SimpleServer.uvoptx SimpleServer.uvprojx main.c wolfssl-link.sct
wolfSSL-Full Abstract.txt main.c shell.c time-CortexM3-4.c wolfsslFull.uvoptx wolfsslFull.uvprojx
wolfSSL-Lib Abstract.txt wolfSSL-Lib.uvoptx wolfSSL-Lib.uvprojx
Src ssl-dummy.c
README.md include.am
MPLABX16
wolfcrypt_test.X
nbproject
private configurations.xml private.xml
configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
README.md include.am main.c user_settings.h
MQX Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.h
MSVS-2019-AZSPHERE
client client.c client.h
server server.c server.h
shared util.h
wolfssl_new_azsphere
HardwareDefinitions
avnet_mt3620_sk
inc
hw template_appliance.h
template_appliance.json
mt3620_rdb
inc
hw template_appliance.h
template_appliance.json
seeed_mt3620_mdb
inc
hw template_appliance.h
template_appliance.json
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.c
README.md include.am user_settings.h
MYSQL CMakeLists_wolfCrypt.txt CMakeLists_wolfSSL.txt do.sh
NDS README.md
NETOS Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.c
OPENSTM32 README.md
PlatformIO
examples
wolfssl_benchmark
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspace
wolfssl_test
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_test.code-workspace
README.md wolfssl_platformio.code-workspace
README.md include.am
QNX
CAAM-DRIVER Makefile
example-client Makefile client-tls.c
example-cmac Makefile cmac-test.c
example-server Makefile server-tls.c
testwolfcrypt Makefile
wolfssl Makefile user_settings.h
README.md include.am
RISCV
SIFIVE-HIFIVE1 Makefile README.md include.am main.c user_settings.h
SIFIVE-UNLEASHED README.md include.am
include.am
ROWLEY-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.hzp
Renesas
cs+
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
t4_demo README_en.txt README_jp.txt t4_demo.mtpj wolf_client.c wolf_demo.h wolf_main.c wolf_server.c
test test.mtpj test_main.c
wolfssl_lib wolfssl_lib.mtpj
README include.am
e2studio
DK-S7G2
benchmark-template
src app_entry.c
example_server-template
src app_entry.c
wolfcrypttest-template
src app_entry.c
wolfssl-template-project configuration.xml
README.md include.am user_settings.h
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
tools generate_rsa_keypair.sh genhexbuf.pl rsa_pss_sign.sh
wolfssl
src .gitkeep
wolfcrypt
src .gitkeep
README include.am
RA6M3
benchmark-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
client-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
common
ra6m3g README.md
src freertos_tcp_port.c
user_settings.h util.h
server-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
test-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl
src .gitkeep
wolfcrypt .gitkeep
README.md README_APRA6M_en.md README_APRA6M_jp.md include.am
RA6M3G README.md
RA6M4
common user_settings.h wolfssl_demo.h
test
key_data key_data.h key_data_sce.c
src
SEGGER_RTT myprint.c
common .gitignore
test_main.c wolf_client.c wolfssl_sce_unit_test.c
test_RA6M4Debug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
README.md include.am
RX65N
GR-ROSE
common strings.h unistd.h user_settings.h wolfssl_dummy.c
smc smc.scfg
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
test.rcpc test_HardwareDebug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
README_EN.md README_JP.md include.am
RSK
resource section.esi
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h
InstructionManualForExample_RSK+RX65N-2MB_EN.pdf InstructionManualForExample_RSK+RX65N-2MB_JP.pdf README_EN.md README_JP.md include.am
RX72N
EnvisionKit
Simple
common sectioninfo.esi wolfssl_dummy.c
test
src
client simple_tcp_client.c simple_tls_tsip_client.c
server simple_tcp_server.c simple_tls_server.c
test_main.c wolfssl_simple_demo.h
test.rcpc test.scfg test_HardwareDebug.launch
wolfssl wolfssl.rcpc
README_EN.md README_JP.md
resource section.esi
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.c
InstructionManualForExample_RX72N_EnvisonKit_EN.pdf InstructionManualForExample_RX72N_EnvisonKit_JP.pdf README_EN.md README_JP.md include.am
RZN2L
common user_settings.h wolfssl_demo.h
test
src
serial_io app_print.c
test wolf_client.c wolf_server.c wolfssl_rsip_unit_test.c
wolfCrypt .gitignore
wolfSSL .gitignore
local_system_init.c rzn2l_tst_thread_entry.c wolfssl_dummy.c
README.md include.am
SK-S7G2
common user_settings.h
wolfssl_lib configuration.xml
.gitignore README.md include.am
STARCORE README.txt include.am starcore_test.c user_settings.h
STM32Cube README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.h
SimplicityStudio README.md include.am test_wolf.c user_settings.h
TRUESTUDIO
wolfssl user_settings.h
README include.am
VS-ARM README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VS-AZURE-SPHERE
client app_manifest.json client.c client.h client.vcxproj
server app_manifest.json server.c server.h server.vcxproj
shared util.h
wolfcrypt_test app_manifest.json wolfcrypt_test.vcxproj
README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VisualDSP include.am user_settings.h wolf_tasks.c
WICED-STUDIO README include.am user_settings.h
WIN README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxproj
WIN-SGX ReadMe.txt include.am wolfSSL_SGX.edl wolfSSL_SGX.sln wolfSSL_SGX.vcxproj
WIN-SRTP-KDF-140-3 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WIN10 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WINCE README.md include.am user_settings.h user_settings.h.140-2-deprecated
WORKBENCH README.md include.am
XCODE
Benchmark
wolfBench
Assets.xcassets
AppIcon.appiconset Contents.json
Base.lproj LaunchScreen.storyboard Main.storyboard
AppDelegate.h AppDelegate.m Info.plist ViewController.h ViewController.m main.m
wolfBench.xcodeproj project.pbxproj
include.am
wolfssl-FIPS.xcodeproj project.pbxproj
wolfssl.xcodeproj project.pbxproj
wolfssl_testsuite.xcodeproj project.pbxproj
README.md build-for-i386.sh include.am user_settings.h
XCODE-FIPSv2
macOS-C++
Intel user_settings.h
M1 user_settings.h
include.am user_settings.h
XCODE-FIPSv5 README include.am user_settings.h
XCODE-FIPSv6 README include.am user_settings.h
XilinxSDK
2018_2 lscript.ld
2019_2
wolfCrypt_example
src lscript.ld
wolfCrypt_example_system wolfCrypt_example_system.sprj
2022_1
wolfCrypt_FreeRTOS_example wolfCrypt_FreeRTOS_example.prj
wolfCrypt_FreeRTOS_example_system wolfCrypt_FreeRTOS_example_system.sprj
wolfCrypt_example wolfCrypt_example.prj
wolfCrypt_example_system wolfCrypt_example_system.sprj
.gitignore
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.c
apple-universal
wolfssl-multiplatform
wolfssl-multiplatform
Assets.xcassets
AccentColor.colorset Contents.json
AppIcon.appiconset Contents.json
Contents.json
ContentView.swift simple_client_example.c simple_client_example.h wolfssl-multiplatform-Bridging-Header.h wolfssl_multiplatform.entitlements wolfssl_multiplatformApp.swift wolfssl_test_driver.c wolfssl_test_driver.h
wolfssl-multiplatform.xcodeproj project.pbxproj
.gitignore README.md build-wolfssl-framework.sh include.am
iotsafe Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.h
iotsafe-raspberrypi Makefile README.md client-tls13.c include.am main.c
mynewt README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.sh
zephyr README.md include.am
include.am
RTOS
nuttx
wolfssl .gitignore Kconfig Make.defs Makefile README.md setup-wolfssl.sh user_settings.h
include.am
bsdkm Makefile README.md bsdkm_wc_port.h include.am wolfkmod.c wolfkmod_aes.c x86_vecreg.c
certs
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.pem
3072 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
4096 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
acert
rsa_pss acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem
acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem include.am
aia ca-issuers-cert.pem multi-aia-cert.pem overflow-aia-cert.pem
crl
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.pem
hash_der 0fdb2da4.r0
hash_pem 0fdb2da4.r0
bad_time_fmt.pem ca-int-ecc.pem ca-int.pem ca-int2-ecc.pem ca-int2.pem caEcc384Crl.pem caEccCrl.der caEccCrl.pem cliCrl.pem client-int-ecc.pem client-int.pem crl.der crl.pem crl.revoked crl2.der crl2.pem crl_reason.pem crl_rsapss.pem eccCliCRL.pem eccSrvCRL.pem gencrls.sh include.am server-goodaltCrl.pem server-goodaltwildCrl.pem server-goodcnCrl.pem server-goodcnwildCrl.pem server-int-ecc.pem server-int.pem wolfssl.cnf
dilithium bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.am
ecc 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.cnf
ed25519 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.pem
ed448 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.pem
external DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.am
falcon bench_falcon_level1_key.der bench_falcon_level5_key.der include.am
intermediate
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.conf
ca-ecc-bad-aki.der ca-ecc-bad-aki.pem ca-int-cert.der ca-int-cert.pem ca-int-ecc-cert.der ca-int-ecc-cert.pem ca-int-ecc-key.der ca-int-ecc-key.pem ca-int-key.der ca-int-key.pem ca-int2-cert.der ca-int2-cert.pem ca-int2-ecc-cert.der ca-int2-ecc-cert.pem ca-int2-ecc-key.der ca-int2-ecc-key.pem ca-int2-key.der ca-int2-key.pem client-chain-alt-ecc.pem client-chain-alt.pem client-chain-ecc.der client-chain-ecc.pem client-chain.der client-chain.pem client-int-cert.der client-int-cert.pem client-int-ecc-cert.der client-int-ecc-cert.pem genintcerts.sh include.am server-chain-alt-ecc.pem server-chain-alt.pem server-chain-ecc.der server-chain-ecc.pem server-chain-short.pem server-chain.der server-chain.pem server-int-cert.der server-int-cert.pem server-int-ecc-cert.der server-int-ecc-cert.pem
lms 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.am
mldsa 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.der
ocsp 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.der
p521 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.pem
renewcerts wolfssl.cnf
rpk client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.der
rsapss 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.pem
sia timestamping-sia-cert.pem
slhdsa 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.pem
sm2 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.pem
statickeys 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.pem
test
expired expired-ca.der expired-ca.pem expired-cert.der expired-cert.pem
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.p7s
test-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.sh
test-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.pem
xmss 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.am
ca-cert-chain.der ca-cert.der ca-cert.pem ca-ecc-cert.der ca-ecc-cert.pem ca-ecc-key.der ca-ecc-key.pem ca-ecc384-cert.der ca-ecc384-cert.pem ca-ecc384-key.der ca-ecc384-key.pem ca-key-pkcs8-attribute.der ca-key.der ca-key.pem check_dates.sh client-absolute-urn.pem client-ca-cert.der client-ca-cert.pem client-ca.pem client-cert-ext.der client-cert-ext.pem client-cert.der client-cert.pem client-crl-dist.der client-crl-dist.pem client-ecc-ca-cert.der client-ecc-ca-cert.pem client-ecc-cert.der client-ecc-cert.pem client-ecc384-cert.der client-ecc384-cert.pem client-ecc384-key.der client-ecc384-key.pem client-key.der client-key.pem client-keyEnc.pem client-keyPub.der client-keyPub.pem client-relative-uri.pem client-uri-cert.pem csr.attr.der csr.dsa.der csr.dsa.pem csr.ext.der csr.signed.der dh-priv-2048.der dh-priv-2048.pem dh-pub-2048.der dh-pub-2048.pem dh-pubkey-2048.der dh2048.der dh2048.pem dh3072.der dh3072.pem dh4096.der dh4096.pem dsa-pubkey-2048.der dsa2048.der dsa2048.pem dsa3072.der dsaparams.der dsaparams.pem ecc-client-key.der ecc-client-key.pem ecc-client-keyPub.der ecc-client-keyPub.pem ecc-key-comp.pem ecc-keyPkcs8.der ecc-keyPkcs8.pem ecc-keyPkcs8Enc.der ecc-keyPkcs8Enc.pem ecc-keyPub.der ecc-keyPub.pem ecc-params.der ecc-params.pem ecc-privOnlyCert.pem ecc-privOnlyKey.pem ecc-privkey.der ecc-privkey.pem ecc-privkeyPkcs8.der ecc-privkeyPkcs8.pem ecc-rsa-server.p12 empty-issuer-cert.pem entity-no-ca-bool-cert.pem entity-no-ca-bool-key.pem fpki-cert.der fpki-certpol-cert.der gen_revoked.sh include.am renewcerts.sh rid-cert.der rsa-pub-2048.pem rsa2048.der rsa3072.der server-cert-chain.der server-cert.der server-cert.pem server-ecc-comp.der server-ecc-comp.pem server-ecc-rsa.der server-ecc-rsa.pem server-ecc-self.der server-ecc-self.pem server-ecc.der server-ecc.pem server-ecc384-cert.der server-ecc384-cert.pem server-ecc384-key.der server-ecc384-key.pem server-key.der server-key.pem server-keyEnc.pem server-keyPkcs8.der server-keyPkcs8.pem server-keyPkcs8Enc.der server-keyPkcs8Enc.pem server-keyPkcs8Enc12.pem server-keyPkcs8Enc2.pem server-keyPub.der server-keyPub.pem server-revoked-cert.pem server-revoked-key.pem taoCert.txt test-ber-exp02-05-2022.p7b test-degenerate.p7b test-multiple-recipients.p7b test-servercert-rc2.p12 test-servercert.p12 test-stream-dec.p7b test-stream-sign.p7b wolfssl-website-ca.pem x942dh2048.der x942dh2048.pem
cmake
consumer CMakeLists.txt README.md main.c
modules FindARIA.cmake FindOQS.cmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.in
debian
source format
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.in
doc
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.h
header_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.h
formats
html
html_changes
search search.css search.js
customdoxygen.css doxygen.css menu.js menudata.js tabs.css
Doxyfile footer.html header.html mainpage.dox
pdf Doxyfile header.tex
images wolfssl_logo.png
QUIC.md README.txt README_DOXYGEN check_api.sh generate_documentation.sh include.am
examples
asn1 asn1.c dumpasn1.cfg gen_oid_names.rb include.am oid_names.h
async Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.h
benchmark include.am tls_bench.c tls_bench.h
client client.c client.h client.sln client.vcproj client.vcxproj include.am
configs 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.h
crypto_policies
default wolfssl.txt
future wolfssl.txt
legacy wolfssl.txt
echoclient echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quit
echoserver echoserver.c echoserver.h echoserver.sln echoserver.vcproj echoserver.vcxproj include.am
ocsp_responder include.am ocsp_responder.c ocsp_responder.h
pem include.am pem.c
sctp include.am sctp-client-dtls.c sctp-client.c sctp-server-dtls.c sctp-server.c
server include.am server.c server.h server.sln server.vcproj server.vcxproj
README.md include.am
linuxkm
patches
5.10.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch
5.10.236 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch
5.14.0-570.58.1.el9_6 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v14-570v58v1-el9_6.patch
5.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch
5.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch
5.17-ubuntu-jammy-tegra WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17-ubuntu-jammy-tegra.patch
6.1.73 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch
6.12 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch
6.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch
7.0 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-7v0.patch
regen-patches.sh
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.c
m4 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.m4
mcapi
wolfcrypt_mcapi.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
zlib.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README crypto.c crypto.h include.am mcapi_test.c user_settings.h
mplabx
wolfcrypt_benchmark.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README benchmark_main.c include.am test_main.c user_settings.h
mqx
util_lib
Sources include.am util.c util.h
wolfcrypt_benchmark
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
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.launch
wolfcrypt_test
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
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.launch
wolfssl include.am
wolfssl_client
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
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.launch
README
rpm include.am spec.in
scripts
bench bench_functions.sh
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.sh
src 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.c
sslSniffer
sslSnifferTest README_WIN.md include.am snifftest.c sslSniffTest.vcproj sslSniffTest.vcxproj
README.md sslSniffer.vcproj sslSniffer.vcxproj
support gen-debug-trace-error-codes.sh include.am wolfssl.pc.in
tests
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.h
emnet
IP IP.h
Makefile emnet_nonblock_test.c emnet_shim.c
freertos-mem-track-repro FreeRTOS.h repro.c run.sh semphr.h task.h user_settings.h
swdev .gitignore Makefile README.md swdev.c swdev.h swdev_loader.c swdev_loader.h user_settings.h
CONF_FILES_README.md NCONF_test.cnf README TXT_DB.txt api.c include.am quic.c srp.c suites.c test-altchains.conf test-chains.conf test-dhprime.conf test-dtls-downgrade.conf test-dtls-fails-cipher.conf test-dtls-fails.conf test-dtls-group.conf test-dtls-mtu.conf test-dtls-reneg-client.conf test-dtls-reneg-server.conf test-dtls-resume.conf test-dtls-sha2.conf test-dtls-srtp-fails.conf test-dtls-srtp.conf test-dtls.conf test-dtls13-cid.conf test-dtls13-downgrade-fails.conf test-dtls13-downgrade.conf test-dtls13-pq-hybrid-extra-frag.conf test-dtls13-pq-hybrid-extra.conf test-dtls13-pq-hybrid-frag.conf test-dtls13-pq-standalone-frag.conf test-dtls13-pq-standalone.conf test-dtls13-psk.conf test-dtls13.conf test-ecc-cust-curves.conf test-ed25519.conf test-ed448.conf test-enckeys.conf test-fails.conf test-maxfrag-dtls.conf test-maxfrag.conf test-p521.conf test-psk-no-id-sha2.conf test-psk-no-id.conf test-psk.conf test-rsapss.conf test-sctp-sha2.conf test-sctp.conf test-sha2.conf test-sig.conf test-sm2.conf test-tls-downgrade.conf test-tls13-down.conf test-tls13-ecc.conf test-tls13-pq-hybrid-extra.conf test-tls13-pq-hybrid.conf test-tls13-pq-standalone.conf test-tls13-psk-certs.conf test-tls13-psk.conf test-tls13-slhdsa-fail.conf test-tls13-slhdsa-sha2.conf test-tls13-slhdsa-shake.conf test-tls13.conf test-trustpeer.conf test.conf unit.c unit.h utils.c utils.h w64wrapper.c
testsuite include.am testsuite.c testsuite.sln testsuite.vcproj testsuite.vcxproj utils.c utils.h
tirtos
packages
ti
net
wolfssl
tests
EK_TM4C1294XL
wolfcrypt
benchmark TM4C1294NC.icf benchmark.cfg main.c package.bld.hide package.xdc
test TM4C1294NC.icf main.c package.bld.hide package.xdc test.cfg
package.bld package.xdc package.xs
.gitignore README include.am products.mak wolfssl.bld wolfssl.mak
wolfcrypt
benchmark README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.am
src
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.py
README.md esp32_aes.c esp32_mp.c esp32_sha.c esp32_util.c esp_sdk_mem_lib.c esp_sdk_time_lib.c esp_sdk_wifi_lib.c
Renesas 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.c
af_alg afalg_aes.c afalg_hash.c wc_afalg.c
aria aria-crypt.c aria-cryptocb.c
arm 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.c
atmel README.md atmel.c
autosar README.md cryif.c crypto.c csm.c include.am test.c
caam 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.c
cavium README.md README_Octeon.md cavium_nitrox.c cavium_octeon_sync.c
cuda README.md aes-cuda.cu
cypress README.md psoc6_crypto.c
devcrypto README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.c
intel README.md quickassist.c quickassist_mem.c quickassist_sync.c
iotsafe iotsafe.c
kcapi README.md kcapi_aes.c kcapi_dh.c kcapi_ecc.c kcapi_hash.c kcapi_hmac.c kcapi_rsa.c
liboqs liboqs.c
maxim README.md max3266x.c maxq10xx.c
mynewt mynewt_port.c
nxp README.md README_SE050.md casper_port.c dcp_port.c hashcrypt_port.c ksdk_port.c se050_port.c
pic32 pic32mz-crypt.c
ppc32 ppc32-sha256-asm.S ppc32-sha256-asm_c.c ppc32-sha256-asm_cr.c
psa README.md psa.c psa_aes.c psa_hash.c psa_pkcbs.c
riscv riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.c
rpi_pico README.md pico.c
silabs README.md silabs_aes.c silabs_ecc.c silabs_hash.c silabs_random.c
st README.md STM32MP13.md STM32MP25.md stm32.c stsafe.c
ti ti-aes.c ti-ccm.c ti-des3.c ti-hash.c
tropicsquare README.md tropic01.c
xilinx xil-aesgcm.c xil-sha3.c xil-versal-glue.c xil-versal-trng.c
nrf51.c
ASN_TEMPLATE.md aes.c aes_asm.S aes_asm.asm aes_gcm_asm.S aes_gcm_asm.asm aes_gcm_x86_asm.S aes_xts_asm.S aes_xts_asm.asm arc4.c ascon.c asm.c asn.c asn_orig.c async.c blake2b.c blake2s.c camellia.c chacha.c chacha20_poly1305.c chacha_asm.S chacha_asm.asm cmac.c coding.c compress.c cpuid.c cryptocb.c curve25519.c curve448.c des3.c dh.c dilithium.c dsa.c ecc.c ecc_fp.c eccsi.c ed25519.c ed448.c error.c evp.c evp_pk.c falcon.c fe_448.c fe_low_mem.c fe_operations.c fe_x25519_128.h fe_x25519_asm.S fp_mont_small.i fp_mul_comba_12.i fp_mul_comba_17.i fp_mul_comba_20.i fp_mul_comba_24.i fp_mul_comba_28.i fp_mul_comba_3.i fp_mul_comba_32.i fp_mul_comba_4.i fp_mul_comba_48.i fp_mul_comba_6.i fp_mul_comba_64.i fp_mul_comba_7.i fp_mul_comba_8.i fp_mul_comba_9.i fp_mul_comba_small_set.i fp_sqr_comba_12.i fp_sqr_comba_17.i fp_sqr_comba_20.i fp_sqr_comba_24.i fp_sqr_comba_28.i fp_sqr_comba_3.i fp_sqr_comba_32.i fp_sqr_comba_4.i fp_sqr_comba_48.i fp_sqr_comba_6.i fp_sqr_comba_64.i fp_sqr_comba_7.i fp_sqr_comba_8.i fp_sqr_comba_9.i fp_sqr_comba_small_set.i ge_448.c ge_low_mem.c ge_operations.c hash.c hmac.c hpke.c include.am integer.c kdf.c logging.c md2.c md4.c md5.c memory.c misc.c pkcs12.c pkcs7.c poly1305.c poly1305_asm.S poly1305_asm.asm puf.c pwdbased.c random.c rc2.c ripemd.c rng_bank.c rsa.c sakke.c sha.c sha256.c sha256_asm.S sha3.c sha3_asm.S sha512.c sha512_asm.S signature.c siphash.c sm2.c sm3.c sm3_asm.S sm4.c sp_arm32.c sp_arm64.c sp_armthumb.c sp_c32.c sp_c64.c sp_cortexm.c sp_dsp32.c sp_int.c sp_sm2_arm32.c sp_sm2_arm64.c sp_sm2_armthumb.c sp_sm2_c32.c sp_sm2_c64.c sp_sm2_cortexm.c sp_sm2_x86_64.c sp_sm2_x86_64_asm.S sp_x86_64.c sp_x86_64_asm.S sp_x86_64_asm.asm srp.c tfm.c wc_dsp.c wc_encrypt.c wc_lms.c wc_lms_impl.c wc_mldsa_asm.S wc_mlkem.c wc_mlkem_asm.S wc_mlkem_poly.c wc_pkcs11.c wc_port.c wc_she.c wc_slhdsa.c wc_xmss.c wc_xmss_impl.c wolfentropy.c wolfevent.c wolfmath.c
test README.md include.am test-VS2022.sln test-VS2022.vcxproj test-VS2022.vcxproj.user test.c test.h test.sln test.vcproj test_paths.h.in
wolfssl
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.h
wolfcrypt
port
Espressif esp-sdk-lib.h esp32-crypt.h esp_crt_bundle.h
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.h
af_alg afalg_hash.h wc_afalg.h
aria aria-crypt.h aria-cryptocb.h
arm cryptoCell.h
atmel atmel.h
autosar CryIf.h Crypto.h Csm.h StandardTypes.h
caam 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.h
cavium cavium_nitrox.h cavium_octeon_sync.h
cypress psoc6_crypto.h
devcrypto wc_devcrypto.h
intel quickassist.h quickassist_mem.h quickassist_sync.h
iotsafe iotsafe.h
kcapi kcapi_dh.h kcapi_ecc.h kcapi_hash.h kcapi_hmac.h kcapi_rsa.h wc_kcapi.h
liboqs liboqs.h
maxim max3266x-cryptocb.h max3266x.h maxq10xx.h
nxp casper_port.h dcp_port.h hashcrypt_port.h ksdk_port.h se050_port.h
pic32 pic32mz-crypt.h
psa psa.h
riscv riscv-64-asm.h
rpi_pico pico.h
silabs silabs_aes.h silabs_ecc.h silabs_hash.h silabs_random.h
st stm32.h stsafe.h
ti ti-ccm.h ti-hash.h
tropicsquare tropic01.h
xilinx xil-sha3.h xil-versal-glue.h xil-versal-trng.h
nrf51.h
aes.h arc4.h ascon.h asn.h asn_public.h async.h blake2-impl.h blake2-int.h blake2.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cpuid.h cryptocb.h curve25519.h curve448.h des3.h dh.h dilithium.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h falcon.h fe_448.h fe_operations.h fips_test.h ge_448.h ge_operations.h hash.h hmac.h hpke.h include.am integer.h kdf.h libwolfssl_sources.h libwolfssl_sources_asm.h logging.h md2.h md4.h md5.h mem_track.h memory.h misc.h mpi_class.h mpi_superclass.h oid_sum.h pkcs11.h pkcs12.h pkcs7.h poly1305.h puf.h pwdbased.h random.h rc2.h ripemd.h rng_bank.h rsa.h sakke.h selftest.h settings.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h sm2.h sm3.h sm4.h sp.h sp_int.h srp.h tfm.h types.h visibility.h wc_encrypt.h wc_lms.h wc_mlkem.h wc_pkcs11.h wc_port.h wc_she.h wc_slhdsa.h wc_xmss.h wolfentropy.h wolfevent.h wolfmath.h
callbacks.h certs_test.h certs_test_sm.h crl.h error-ssl.h include.am internal.h ocsp.h options.h.in quic.h sniffer.h sniffer_error.h sniffer_error.rc ssl.h test.h version.h version.h.in wolfio.h
wrapper
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.adb
.gitignore alire.toml examples.gpr
tests
src
support test_support.adb test_support.ads tests_root_suite.adb tests_root_suite.ads
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.adb
.gitignore README.md alire.toml tests.gpr valgrind.supp
.gitignore README.md ada_binding.c alire.toml default.gpr include.am restricted.adc user_settings.h wolfssl-full_runtime.adb wolfssl-full_runtime.ads wolfssl.adb wolfssl.ads wolfssl.gpr
CSharp
wolfCrypt-Test
Properties AssemblyInfo.cs
App.config wolfCrypt-Test.cs wolfCrypt-Test.csproj
wolfSSL-DTLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-PSK-Server.cs wolfSSL-DTLS-PSK-Server.csproj
wolfSSL-DTLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-Server.cs wolfSSL-DTLS-Server.csproj
wolfSSL-Example-IOCallbacks
Properties AssemblyInfo.cs
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csproj
wolfSSL-TLS-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Client.cs wolfSSL-TLS-Client.csproj
wolfSSL-TLS-PSK-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Client.cs wolfSSL-TLS-PSK-Client.csproj
wolfSSL-TLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Server.cs wolfSSL-TLS-PSK-Server.csproj
wolfSSL-TLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Server.cs wolfSSL-TLS-Server.csproj
wolfSSL-TLS-ServerThreaded
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csproj
wolfSSL_CSharp
Properties AssemblyInfo.cs Resources.Designer.cs Resources.resx
X509.cs wolfCrypt.cs wolfSSL.cs wolfSSL_CSharp.csproj
README.md include.am user_settings.h wolfSSL_CSharp.sln wolfssl.vcxproj
python README.md
rust
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.rs
tests
common mod.rs
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.rs
CHANGELOG.md Cargo.lock Cargo.toml Makefile README.md build.rs headers.h
Makefile README.md include.am
include.am
zephyr
samples
wolfssl_benchmark
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_test
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_sock
boards native_sim.conf
src tls_sock.c
CMakeLists.txt README install_sample.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_thread
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
src tls_threaded.c
CMakeLists.txt README install_sample.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl options.h
CMakeLists.txt Kconfig Kconfig.tls-generic README.md include.am module.yml user_settings-no-malloc.h user_settings.h zephyr_init.c
.codespellexcludelines .cyignore .editorconfig .gitignore .wolfssl_known_macro_extras AUTHORS CMakeLists.txt CMakePresets.json CMakeSettings.json COPYING ChangeLog.md INSTALL LICENSING LPCExpresso.cproject LPCExpresso.project Makefile.am README README-async.md README.md SCRIPTS-LIST SECURITY-POLICY.md SECURITY-REPORT-TEMPLATE.md Vagrantfile autogen.sh commit-tests.sh configure.ac fips-check.sh fips-hash.sh gencertbuf.pl input pull_to_vagrant.sh quit resource.h stamp-h.in valgrind-bash.supp valgrind-error.sh wnr-example.conf wolfssl-VS2022.vcxproj wolfssl.rc wolfssl.vcproj wolfssl.vcxproj wolfssl64.sln
.clangd .gitignore DOCS.md Makefile README.md assert.c core.c crypto.c env.c fs.c http.c ini.c json.c log.c luna.h main.c makext.mk path.c process.c request.c sqlite.c stash.c template.c util.c
wolfssl/wolfcrypt/src/ecc.c raw
    1/* ecc.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#ifdef WOLFSSL_ECC_NO_SMALL_STACK
   25#undef WOLFSSL_SMALL_STACK
   26#undef WOLFSSL_SMALL_STACK_CACHE
   27#endif
   28
   29/*
   30Possible ECC enable options:
   31 * HAVE_ECC:            Overall control of ECC                  default: on
   32 * HAVE_ECC_ENCRYPT:    ECC encrypt/decrypt w/AES and HKDF      default: off
   33 * HAVE_ECC_SIGN:       ECC sign                                default: on
   34 * HAVE_ECC_VERIFY:     ECC verify                              default: on
   35 * HAVE_ECC_DHE:        ECC build shared secret                 default: on
   36 * HAVE_ECC_CDH:        ECC cofactor DH shared secret           default: off
   37 * HAVE_ECC_KEY_IMPORT: ECC Key import                          default: on
   38 * HAVE_ECC_KEY_EXPORT: ECC Key export                          default: on
   39 * ECC_SHAMIR:          Enables Shamir calc method              default: on
   40 * HAVE_COMP_KEY:       Enables compressed key                  default: off
   41 * WOLFSSL_VALIDATE_ECC_IMPORT: Validate ECC key on import      default: off
   42 * WOLFSSL_VALIDATE_ECC_KEYGEN: Validate ECC key gen            default: off
   43 * WOLFSSL_CUSTOM_CURVES: Allow non-standard curves.            default: off
   44 *                        Includes the curve "a" variable in calculation
   45 * ECC_DUMP_OID:        Enables dump of OID encoding and sum    default: off
   46 * ECC_CACHE_CURVE:     Enables cache of curve info to improve performance
   47 *                                                              default: off
   48 * FP_ECC:              ECC Fixed Point Cache                   default: off
   49 *                      FP cache is not supported for SECP160R1, SECP160R2,
   50 *                      SECP160K1 and SECP224K1. These do not work with scalars
   51 *                      that are the length of the order when the order is
   52 *                      longer than the prime. Use wc_ecc_fp_free to free cache.
   53 * WOLFSSL_ECC_CURVE_STATIC:                                    default off (on for windows)
   54 *                      For the ECC curve parameters `ecc_set_type` use fixed
   55 *                      array for hex string
   56 * WC_ECC_NONBLOCK:     Enable non-blocking support for sign/verify/keygen/secret.
   57 *                      Requires SP with WOLFSSL_SP_NONBLOCK
   58 * WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
   59 *                      normal blocking API's
   60 * WOLFSSL_ECDSA_SET_K: Enables the setting of the 'k' value to use during ECDSA
   61 *                      signing. If the value is invalid, a new random 'k' is
   62 *                      generated in the loop. (For testing)
   63 *                                                              default: off
   64 * WOLFSSL_ECDSA_SET_K_ONE_LOOP:
   65 *                      Enables the setting of the 'k' value to use during ECDSA
   66 *                      signing. If the value is invalid then an error is
   67 *                      returned rather than generating a new 'k'. (For testing)
   68 *                                                              default: off
   69 * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of
   70 *                      deterministic ECC signatures. The following function
   71 *                      can be used to set the deterministic signing flag in the
   72 *                      ecc key structure.
   73 *                      int wc_ecc_set_deterministic(ecc_key* key, byte flag)
   74 *                                                              default: off
   75 *
   76 * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the
   77 *                      hash directly instead of doing bits2octets(H(m)), when
   78 *                      the variant macro is used the bits2octets operation on
   79 *                      the hash is removed.
   80 *                                                              default: off
   81 *
   82 * WC_PROTECT_ENCRYPTED_MEM:
   83 *                      Enables implementations that protect data that is in
   84 *                      encrypted memory.
   85 *                                                              default: off
   86 * WOLFSSL_ECC_GEN_REJECT_SAMPLING
   87 *                      Enables generation of scalar (private key and ECDSA
   88 *                      nonce) to be performed using reject sampling algorithm.
   89 *                      Use this when CPU state can be closely observed by
   90 *                      attacker.
   91 *                                                              default: off
   92 * WOLFSSL_ECC_BLIND_K
   93 *                      Blind the private key k by using a random mask.
   94 *                      The private key is never stored unprotected but an
   95 *                      unmasked copy is computed and stored each time it is
   96 *                      needed.
   97 *                                                              default: off
   98 * WOLFSSL_CHECK_VER_FAULTS
   99 *                      Sanity check on verification steps in case of faults.
  100 *                                                              default: off
  101 * ECC_TIMING_RESISTANT: Enables constant-time ECC operations   default: on
  102 *                      to prevent timing side-channel attacks.
  103 *                      Auto-enabled for FIPS and some embedded builds.
  104 * WC_NO_CACHE_RESISTANT: Disables cache-resistant operations   default: off
  105 *                      (conditional swaps) in ECC scalar multiply to
  106 *                      reduce overhead. Not recommended for secure use.
  107 * ALT_ECC_SIZE:        Uses alternate smaller fixed-size arrays default: off
  108 *                      for ECC points instead of full mp_int arrays,
  109 *                      reducing memory. Requires USE_FAST_MATH.
  110 * WOLFSSL_ECC_NO_SMALL_STACK: Disables WOLFSSL_SMALL_STACK     default: off
  111 *                      optimizations for ECC, using stack instead of heap.
  112 * HAVE_ECC_CHECK_PUBKEY_ORDER: Validates ECC public key order  default: on
  113 *                      during import. Auto-enabled unless
  114 *                      NO_ECC_CHECK_PUBKEY_ORDER is defined.
  115 * NO_ECC_CHECK_PUBKEY_ORDER: Disables public key order check   default: off
  116 *                      during ECC key import. Not recommended.
  117 * HAVE_ECC_MAKE_PUB:   Enables computing public key from       default: on
  118 *                      private key via wc_ecc_make_pub.
  119 * HAVE_ECC_VERIFY_HELPER: Enables ECC verify helper functions  default: on
  120 *                      Auto-enabled unless using hardware accelerators.
  121 * WOLFSSL_PUBLIC_ECC_ADD_DBL: Makes ecc_projective_add_point   default: off
  122 *                      and ecc_projective_dbl_point public APIs.
  123 * SQRTMOD_USE_MOD_EXP: Computes square root mod prime using    default: off
  124 *                      modular exponentiation instead of Jacobi method
  125 *                      for compressed key decompression.
  126 *
  127 * ECIES options:
  128 * WOLFSSL_ECIES_OLD:   Uses original wolfSSL ECIES format      default: off
  129 *                      (public key not in shared secret material).
  130 * WOLFSSL_ECIES_ISO18033: Uses ISO 18033 ECIES standard        default: off
  131 *                      (includes public key in shared secret).
  132 * WOLFSSL_ECIES_GEN_IV: Generates random IV for ECIES          default: off
  133 *                      encryption instead of deriving from KDF.
  134 *
  135 * Fixed Point Cache options (requires FP_ECC):
  136 * FP_ENTRIES:          Number of FP cache entries               default: 15
  137 * FP_LUT:              FP lookup table bit size (2-12). Larger  default: 8
  138 *                      values use more memory but faster verify.
  139 * FP_ECC_CONTROL:      Auto-selects cached FP ECC verify with  default: on
  140 *                      SP when WOLFSSL_HAVE_SP_ECC is available.
  141 *
  142 * SP Math ECC options:
  143 * WOLFSSL_HAVE_SP_ECC: Enables SP math optimizations for ECC   default: on
  144 *                      Provides significant performance improvement.
  145 * WOLFSSL_SP_NO_256:   Disables SP P-256 support               default: off
  146 * WOLFSSL_SP_384:      Enables SP P-384 support                default: off
  147 * WOLFSSL_SP_521:      Enables SP P-521 support                default: off
  148 * WOLFSSL_SP_1024:     Enables SP 1024-bit support for SAKKE   default: off
  149 * WOLFSSL_SP_SM2:      Enables SP SM2 curve support            default: off
  150 *                      Auto-enabled with WOLFSSL_SM2.
  151 *
  152 * Hardware/Offload options:
  153 * WOLFSSL_KCAPI_ECC:   Offload ECC to Linux Kernel Crypto API  default: off
  154 * WC_ASYNC_ENABLE_ECC: Enables async ECC with crypto callbacks default: off
  155 *                      Requires WOLFSSL_ASYNC_CRYPT.
  156 * WC_ASYNC_ENABLE_ECC_KEYGEN: Enables async ECC key gen        default: off
  157 * PLUTON_CRYPTO_ECC:   Uses ARM Pluton TEE for ECC operations  default: off
  158 * WOLFSSL_CAAM_BLACK_KEY_SM: Uses NXP CAAM secure memory for   default: off
  159 *                      encrypted black key storage.
  160 */
  161
  162/*
  163ECC Curve Types:
  164 * NO_ECC_SECP          Disables SECP curves                    default: off (not defined)
  165 * HAVE_ECC_SECPR2      Enables SECP R2 curves                  default: off
  166 * HAVE_ECC_SECPR3      Enables SECP R3 curves                  default: off
  167 * HAVE_ECC_BRAINPOOL   Enables Brainpool curves                default: off
  168 * HAVE_ECC_KOBLITZ     Enables Koblitz curves                  default: off
  169 * WOLFSSL_SM2          Enables SM2 curves                      default: off
  170 */
  171
  172/*
  173ECC Curve Sizes:
  174 * ECC_USER_CURVES: Allows custom combination of key sizes below
  175 * HAVE_ALL_CURVES: Enable all key sizes (on unless ECC_USER_CURVES is defined)
  176 * ECC_MIN_KEY_SZ: Minimum supported ECC key size
  177 * HAVE_ECC112: 112 bit key
  178 * HAVE_ECC128: 128 bit key
  179 * HAVE_ECC160: 160 bit key
  180 * HAVE_ECC192: 192 bit key
  181 * HAVE_ECC224: 224 bit key
  182 * HAVE_ECC239: 239 bit key
  183 * NO_ECC256: Disables 256 bit key (on by default)
  184 * HAVE_ECC320: 320 bit key
  185 * HAVE_ECC384: 384 bit key
  186 * HAVE_ECC512: 512 bit key
  187 * HAVE_ECC521: 521 bit key
  188 */
  189
  190
  191#ifdef HAVE_ECC
  192
  193/* Make sure custom curves is enabled for Brainpool or Koblitz curve types */
  194#if (defined(HAVE_ECC_BRAINPOOL) || defined(HAVE_ECC_KOBLITZ)) &&\
  195    !defined(WOLFSSL_CUSTOM_CURVES)
  196    #error Brainpool and Koblitz curves requires WOLFSSL_CUSTOM_CURVES
  197#endif
  198
  199#if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
  200    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
  201    #define FIPS_NO_WRAPPERS
  202
  203    #ifdef USE_WINDOWS_API
  204        #pragma code_seg(".fipsA$f")
  205        #pragma const_seg(".fipsB$f")
  206    #endif
  207#endif
  208
  209/* public ASN interface */
  210#include <wolfssl/wolfcrypt/asn_public.h>
  211
  212#include <wolfssl/wolfcrypt/ecc.h>
  213#include <wolfssl/wolfcrypt/asn.h>
  214#include <wolfssl/wolfcrypt/hash.h>
  215
  216#ifdef WOLFSSL_HAVE_SP_ECC
  217#include <wolfssl/wolfcrypt/sp.h>
  218#endif
  219
  220#ifdef HAVE_ECC_ENCRYPT
  221    #include <wolfssl/wolfcrypt/kdf.h>
  222    #include <wolfssl/wolfcrypt/aes.h>
  223#endif
  224
  225#ifdef WOLF_CRYPTO_CB
  226    #include <wolfssl/wolfcrypt/cryptocb.h>
  227#endif
  228
  229#ifdef NO_INLINE
  230    #include <wolfssl/wolfcrypt/misc.h>
  231#else
  232    #define WOLFSSL_MISC_INCLUDED
  233    #include <wolfcrypt/src/misc.c>
  234#endif
  235
  236#if FIPS_VERSION3_GE(6,0,0)
  237    const unsigned int wolfCrypt_FIPS_ecc_ro_sanity[2] =
  238                                                     { 0x1a2b3c4d, 0x00000005 };
  239    int wolfCrypt_FIPS_ECC_sanity(void)
  240    {
  241        return 0;
  242    }
  243#endif
  244
  245#if defined(FREESCALE_LTC_ECC)
  246    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
  247#endif
  248
  249#if defined(WOLFSSL_STM32_PKA)
  250    #include <wolfssl/wolfcrypt/port/st/stm32.h>
  251#endif
  252
  253#if defined(WOLFSSL_PSOC6_CRYPTO)
  254    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
  255#endif
  256
  257#if defined(WOLFSSL_CAAM)
  258    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
  259#endif
  260
  261#if defined(WOLFSSL_KCAPI_ECC)
  262    #include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
  263#endif
  264
  265#ifdef WOLFSSL_SE050
  266    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
  267#endif
  268
  269#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
  270    #include <xsecure_ellipticclient.h>
  271#endif
  272
  273#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
  274    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
  275    #include <wolfssl/wolfcrypt/hmac.h>
  276#endif
  277
  278#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && !defined(WOLFSSL_SP_ASM)
  279    /* force off unneeded vector register save/restore. */
  280    #undef SAVE_VECTOR_REGISTERS
  281    #define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
  282    #undef RESTORE_VECTOR_REGISTERS
  283    #define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
  284#endif
  285
  286#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
  287    !defined(WOLFSSL_MICROCHIP_TA100) && \
  288    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
  289    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \
  290    !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_PSOC6_CRYPTO) && \
  291    !defined(WOLFSSL_XILINX_CRYPT_VERSAL)
  292    #undef  HAVE_ECC_VERIFY_HELPER
  293    #define HAVE_ECC_VERIFY_HELPER
  294#endif
  295#if defined(WOLFSSL_SE050_NO_ECDSA_VERIFY) && defined(HAVE_ECC_VERIFY)
  296    #define HAVE_ECC_VERIFY_HELPER
  297#endif
  298
  299#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
  300        !defined(WOLFSSL_MICROCHIP_TA100) && \
  301    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
  302    !defined(WOLFSSL_KCAPI_ECC) && !defined(NO_ECC_MAKE_PUB) && \
  303    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
  304    #undef  HAVE_ECC_MAKE_PUB
  305    #define HAVE_ECC_MAKE_PUB
  306#endif
  307
  308
  309/* macro guard for ecc_check_pubkey_order functionality */
  310#if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \
  311     !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \
  312     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
  313     !defined(WOLFSSL_MICROCHIP_TA100) && \
  314     !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
  315     !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \
  316     defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM)
  317
  318    /* CAAM builds use public key validation as a means to check if an
  319     * imported private key is an encrypted black key or not */
  320    #undef  HAVE_ECC_CHECK_PUBKEY_ORDER
  321    #define HAVE_ECC_CHECK_PUBKEY_ORDER
  322#endif
  323
  324#if defined(WOLFSSL_SP_MATH_ALL) && SP_INT_BITS < MAX_ECC_BITS_NEEDED
  325#define MAX_ECC_BITS_USE    SP_INT_BITS
  326#else
  327#define MAX_ECC_BITS_USE    MAX_ECC_BITS_NEEDED
  328#endif
  329
  330#if !defined(WOLFSSL_CUSTOM_CURVES) && (ECC_MIN_KEY_SZ > 160) && \
  331    (!defined(HAVE_ECC_KOBLITZ) || (ECC_MIN_KEY_SZ > 224))
  332
  333#define ECC_KEY_MAX_BITS(key)                                       \
  334    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
  335        ((unsigned)((key)->dp->size * 8)))
  336#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
  337    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
  338        ((unsigned)((key)->dp->size * 8)))
  339
  340#else
  341
  342/* Add one bit for cases when order is a bit greater than prime. */
  343#define ECC_KEY_MAX_BITS(key)                                       \
  344    ((((key) == NULL) || ((key)->dp == NULL)) ? MAX_ECC_BITS_USE :  \
  345        ((unsigned)((key)->dp->size * 8 + 1)))
  346#define ECC_KEY_MAX_BITS_NONULLCHECK(key)                           \
  347    (((key)->dp == NULL) ? MAX_ECC_BITS_USE :                       \
  348        ((unsigned)((key)->dp->size * 8 + 1)))
  349
  350#endif
  351
  352#ifdef WOLFSSL_ECC_BLIND_K
  353mp_int* ecc_get_k(ecc_key* key)
  354{
  355    mp_xor_ct(key->k, key->kb, key->dp->size, key->ku);
  356    return key->ku;
  357}
  358void ecc_blind_k(ecc_key* key, mp_int* b)
  359{
  360    mp_xor_ct(key->k, b, key->dp->size, key->k);
  361    mp_xor_ct(key->kb, b, key->dp->size, key->kb);
  362}
  363int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
  364{
  365    int ret = 0;
  366    WC_RNG local_rng;
  367
  368#ifdef ECC_TIMING_RESISTANT
  369    if (rng == NULL) {
  370        rng = key->rng;
  371    }
  372#endif
  373    if (rng == NULL) {
  374        ret = wc_InitRng(&local_rng);
  375        if (ret == 0) {
  376            rng = &local_rng;
  377        }
  378    }
  379    if (ret == 0) {
  380        ret = mp_rand(key->kb, (key->dp->size + sizeof(mp_digit) - 1) /
  381            sizeof(mp_digit), rng);
  382        if (ret == 0) {
  383            mp_xor_ct(key->k, key->kb, key->dp->size, key->k);
  384        }
  385    }
  386
  387    if (rng == &local_rng) {
  388        wc_FreeRng(&local_rng);
  389    }
  390    return ret;
  391}
  392
  393mp_int* wc_ecc_key_get_priv(ecc_key* key)
  394{
  395    return ecc_get_k(key);
  396}
  397#endif
  398
  399/* forward declarations */
  400static int  wc_ecc_new_point_ex(ecc_point** point, void* heap);
  401static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
  402#if defined(HAVE_ECC_SIGN) && (defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
  403    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT))
  404static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key);
  405#endif
  406
  407/* internal ECC states */
  408enum {
  409    ECC_STATE_NONE = 0,
  410
  411    ECC_STATE_SHARED_SEC_GEN,
  412    ECC_STATE_SHARED_SEC_RES,
  413
  414    ECC_STATE_SIGN_DO,
  415    ECC_STATE_SIGN_ENCODE,
  416
  417    ECC_STATE_VERIFY_DECODE,
  418    ECC_STATE_VERIFY_DO,
  419    ECC_STATE_VERIFY_RES
  420};
  421
  422
  423/* map
  424   ptmul -> mulmod
  425*/
  426
  427/* 256-bit curve on by default whether user curves or not */
  428#if (defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 112
  429    #define ECC112
  430#endif
  431#if (defined(HAVE_ECC128) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 128
  432    #define ECC128
  433#endif
  434#if (defined(HAVE_ECC160) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 160
  435    #define ECC160
  436#endif
  437#if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 192
  438    #define ECC192
  439#endif
  440#if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 224
  441    #define ECC224
  442#endif
  443#if (defined(HAVE_ECC239) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 239
  444    #define ECC239
  445#endif
  446#if (!defined(NO_ECC256)  || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
  447    #define ECC256
  448#endif
  449#if (defined(HAVE_ECC320) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 320
  450    #define ECC320
  451#endif
  452#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
  453    #define ECC384
  454#endif
  455#if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 512
  456    #define ECC512
  457#endif
  458#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
  459    #define ECC521
  460#endif
  461
  462/* The encoded OID's for ECC curves */
  463#ifdef ECC112
  464    #ifndef NO_ECC_SECP
  465        #ifdef HAVE_OID_ENCODING
  466            #define CODED_SECP112R1    {1,3,132,0,6}
  467            #define CODED_SECP112R1_SZ 5
  468        #else
  469            #define CODED_SECP112R1    {0x2B,0x81,0x04,0x00,0x06}
  470            #define CODED_SECP112R1_SZ 5
  471        #endif
  472        #ifndef WOLFSSL_ECC_CURVE_STATIC
  473            static const ecc_oid_t ecc_oid_secp112r1[] = CODED_SECP112R1;
  474        #else
  475            #define ecc_oid_secp112r1 CODED_SECP112R1
  476        #endif
  477        #define ecc_oid_secp112r1_sz CODED_SECP112R1_SZ
  478    #endif /* !NO_ECC_SECP */
  479    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
  480        #ifdef HAVE_OID_ENCODING
  481            #define CODED_SECP112R2    {1,3,132,0,7}
  482            #define CODED_SECP112R2_SZ 5
  483        #else
  484            #define CODED_SECP112R2    {0x2B,0x81,0x04,0x00,0x07}
  485            #define CODED_SECP112R2_SZ 5
  486        #endif
  487        #ifndef WOLFSSL_ECC_CURVE_STATIC
  488            static const ecc_oid_t ecc_oid_secp112r2[] = CODED_SECP112R2;
  489        #else
  490            #define ecc_oid_secp112r2 CODED_SECP112R2
  491        #endif
  492        #define ecc_oid_secp112r2_sz CODED_SECP112R2_SZ
  493    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
  494#endif /* ECC112 */
  495#ifdef ECC128
  496    #ifndef NO_ECC_SECP
  497        #ifdef HAVE_OID_ENCODING
  498            #define CODED_SECP128R1    {1,3,132,0,28}
  499            #define CODED_SECP128R1_SZ 5
  500        #else
  501            #define CODED_SECP128R1    {0x2B,0x81,0x04,0x00,0x1C}
  502            #define CODED_SECP128R1_SZ 5
  503        #endif
  504        #ifndef WOLFSSL_ECC_CURVE_STATIC
  505            static const ecc_oid_t ecc_oid_secp128r1[] = CODED_SECP128R1;
  506        #else
  507            #define ecc_oid_secp128r1 CODED_SECP128R1
  508        #endif
  509        #define ecc_oid_secp128r1_sz CODED_SECP128R1_SZ
  510    #endif /* !NO_ECC_SECP */
  511    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
  512        #ifdef HAVE_OID_ENCODING
  513            #define CODED_SECP128R2    {1,3,132,0,29}
  514            #define CODED_SECP128R2_SZ 5
  515        #else
  516            #define CODED_SECP128R2    {0x2B,0x81,0x04,0x00,0x1D}
  517            #define CODED_SECP128R2_SZ 5
  518        #endif
  519        #ifndef WOLFSSL_ECC_CURVE_STATIC
  520            static const ecc_oid_t ecc_oid_secp128r2[] = CODED_SECP128R2;
  521        #else
  522            #define ecc_oid_secp128r2 CODED_SECP128R2
  523        #endif
  524        #define ecc_oid_secp128r2_sz CODED_SECP128R2_SZ
  525    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
  526#endif /* ECC128 */
  527#ifdef ECC160
  528#ifndef FP_ECC
  529    #ifndef NO_ECC_SECP
  530        #ifdef HAVE_OID_ENCODING
  531            #define CODED_SECP160R1    {1,3,132,0,8}
  532            #define CODED_SECP160R1_SZ 5
  533        #else
  534            #define CODED_SECP160R1    {0x2B,0x81,0x04,0x00,0x08}
  535            #define CODED_SECP160R1_SZ 5
  536        #endif
  537        #ifndef WOLFSSL_ECC_CURVE_STATIC
  538            static const ecc_oid_t ecc_oid_secp160r1[] = CODED_SECP160R1;
  539        #else
  540            #define ecc_oid_secp160r1 CODED_SECP160R1
  541        #endif
  542        #define ecc_oid_secp160r1_sz CODED_SECP160R1_SZ
  543    #endif /* !NO_ECC_SECP */
  544    #ifdef HAVE_ECC_SECPR2
  545        #ifdef HAVE_OID_ENCODING
  546            #define CODED_SECP160R2    {1,3,132,0,30}
  547            #define CODED_SECP160R2_SZ 5
  548        #else
  549            #define CODED_SECP160R2    {0x2B,0x81,0x04,0x00,0x1E}
  550            #define CODED_SECP160R2_SZ 5
  551        #endif
  552        #ifndef WOLFSSL_ECC_CURVE_STATIC
  553            static const ecc_oid_t ecc_oid_secp160r2[] = CODED_SECP160R2;
  554        #else
  555            #define ecc_oid_secp160r2 CODED_SECP160R2
  556        #endif
  557        #define ecc_oid_secp160r2_sz CODED_SECP160R2_SZ
  558    #endif /* HAVE_ECC_SECPR2 */
  559    #ifdef HAVE_ECC_KOBLITZ
  560        #ifdef HAVE_OID_ENCODING
  561            #define CODED_SECP160K1    {1,3,132,0,9}
  562            #define CODED_SECP160K1_SZ 5
  563        #else
  564            #define CODED_SECP160K1    {0x2B,0x81,0x04,0x00,0x09}
  565            #define CODED_SECP160K1_SZ 5
  566        #endif
  567        #ifndef WOLFSSL_ECC_CURVE_STATIC
  568            static const ecc_oid_t ecc_oid_secp160k1[] = CODED_SECP160K1;
  569        #else
  570            #define ecc_oid_secp160k1 CODED_SECP160K1
  571        #endif
  572        #define ecc_oid_secp160k1_sz CODED_SECP160K1_SZ
  573    #endif /* HAVE_ECC_KOBLITZ */
  574#endif /* !FP_ECC */
  575    #ifdef HAVE_ECC_BRAINPOOL
  576        #ifdef HAVE_OID_ENCODING
  577            #define CODED_BRAINPOOLP160R1    {1,3,36,3,3,2,8,1,1,1}
  578            #define CODED_BRAINPOOLP160R1_SZ 10
  579        #else
  580            #define CODED_BRAINPOOLP160R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01}
  581            #define CODED_BRAINPOOLP160R1_SZ 9
  582        #endif
  583        #ifndef WOLFSSL_ECC_CURVE_STATIC
  584            static const ecc_oid_t ecc_oid_brainpoolp160r1[] = CODED_BRAINPOOLP160R1;
  585        #else
  586            #define ecc_oid_brainpoolp160r1 CODED_BRAINPOOLP160R1
  587        #endif
  588        #define ecc_oid_brainpoolp160r1_sz CODED_BRAINPOOLP160R1_SZ
  589    #endif /* HAVE_ECC_BRAINPOOL */
  590#endif /* ECC160 */
  591#ifdef ECC192
  592    #ifndef NO_ECC_SECP
  593        #ifdef HAVE_OID_ENCODING
  594            #define CODED_SECP192R1    {1,2,840,10045,3,1,1}
  595            #define CODED_SECP192R1_SZ 7
  596        #else
  597            #define CODED_SECP192R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01}
  598            #define CODED_SECP192R1_SZ 8
  599        #endif
  600        #ifndef WOLFSSL_ECC_CURVE_STATIC
  601            static const ecc_oid_t ecc_oid_secp192r1[] = CODED_SECP192R1;
  602        #else
  603            #define ecc_oid_secp192r1 CODED_SECP192R1
  604        #endif
  605        #define ecc_oid_secp192r1_sz CODED_SECP192R1_SZ
  606    #endif /* !NO_ECC_SECP */
  607    #ifdef HAVE_ECC_SECPR2
  608        #ifdef HAVE_OID_ENCODING
  609            #define CODED_PRIME192V2    {1,2,840,10045,3,1,2}
  610            #define CODED_PRIME192V2_SZ 7
  611        #else
  612            #define CODED_PRIME192V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02}
  613            #define CODED_PRIME192V2_SZ 8
  614        #endif
  615        #ifndef WOLFSSL_ECC_CURVE_STATIC
  616            static const ecc_oid_t ecc_oid_prime192v2[] = CODED_PRIME192V2;
  617        #else
  618            #define ecc_oid_prime192v2 CODED_PRIME192V2
  619        #endif
  620        #define ecc_oid_prime192v2_sz CODED_PRIME192V2_SZ
  621    #endif /* HAVE_ECC_SECPR2 */
  622    #ifdef HAVE_ECC_SECPR3
  623        #ifdef HAVE_OID_ENCODING
  624            #define CODED_PRIME192V3    {1,2,840,10045,3,1,3}
  625            #define CODED_PRIME192V3_SZ 7
  626        #else
  627            #define CODED_PRIME192V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03}
  628            #define CODED_PRIME192V3_SZ 8
  629        #endif
  630        #ifndef WOLFSSL_ECC_CURVE_STATIC
  631            static const ecc_oid_t ecc_oid_prime192v3[] = CODED_PRIME192V3;
  632        #else
  633            #define ecc_oid_prime192v3 CODED_PRIME192V3
  634        #endif
  635        #define ecc_oid_prime192v3_sz CODED_PRIME192V3_SZ
  636    #endif /* HAVE_ECC_SECPR3 */
  637    #ifdef HAVE_ECC_KOBLITZ
  638        #ifdef HAVE_OID_ENCODING
  639            #define CODED_SECP192K1    {1,3,132,0,31}
  640            #define CODED_SECP192K1_SZ 5
  641        #else
  642            #define CODED_SECP192K1    {0x2B,0x81,0x04,0x00,0x1F}
  643            #define CODED_SECP192K1_SZ 5
  644        #endif
  645        #ifndef WOLFSSL_ECC_CURVE_STATIC
  646            static const ecc_oid_t ecc_oid_secp192k1[] = CODED_SECP192K1;
  647        #else
  648            #define ecc_oid_secp192k1 CODED_SECP192K1
  649        #endif
  650        #define ecc_oid_secp192k1_sz CODED_SECP192K1_SZ
  651    #endif /* HAVE_ECC_KOBLITZ */
  652    #ifdef HAVE_ECC_BRAINPOOL
  653        #ifdef HAVE_OID_ENCODING
  654            #define CODED_BRAINPOOLP192R1    {1,3,36,3,3,2,8,1,1,3}
  655            #define CODED_BRAINPOOLP192R1_SZ 10
  656        #else
  657            #define CODED_BRAINPOOLP192R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03}
  658            #define CODED_BRAINPOOLP192R1_SZ 9
  659        #endif
  660        #ifndef WOLFSSL_ECC_CURVE_STATIC
  661            static const ecc_oid_t ecc_oid_brainpoolp192r1[] = CODED_BRAINPOOLP192R1;
  662        #else
  663            #define ecc_oid_brainpoolp192r1 CODED_BRAINPOOLP192R1
  664        #endif
  665        #define ecc_oid_brainpoolp192r1_sz CODED_BRAINPOOLP192R1_SZ
  666    #endif /* HAVE_ECC_BRAINPOOL */
  667#endif /* ECC192 */
  668#ifdef ECC224
  669    #ifndef NO_ECC_SECP
  670        #ifdef HAVE_OID_ENCODING
  671            #define CODED_SECP224R1    {1,3,132,0,33}
  672            #define CODED_SECP224R1_SZ 5
  673        #else
  674            #define CODED_SECP224R1    {0x2B,0x81,0x04,0x00,0x21}
  675            #define CODED_SECP224R1_SZ 5
  676        #endif
  677        #ifndef WOLFSSL_ECC_CURVE_STATIC
  678            static const ecc_oid_t ecc_oid_secp224r1[] = CODED_SECP224R1;
  679        #else
  680            #define ecc_oid_secp224r1 CODED_SECP224R1
  681        #endif
  682        #define ecc_oid_secp224r1_sz CODED_SECP224R1_SZ
  683    #endif /* !NO_ECC_SECP */
  684    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
  685        #ifdef HAVE_OID_ENCODING
  686            #define CODED_SECP224K1    {1,3,132,0,32}
  687            #define CODED_SECP224K1_SZ 5
  688        #else
  689            #define CODED_SECP224K1    {0x2B,0x81,0x04,0x00,0x20}
  690            #define CODED_SECP224K1_SZ 5
  691        #endif
  692        #ifndef WOLFSSL_ECC_CURVE_STATIC
  693            static const ecc_oid_t ecc_oid_secp224k1[] = CODED_SECP224K1;
  694        #else
  695            #define ecc_oid_secp224k1 CODED_SECP224K1
  696        #endif
  697        #define ecc_oid_secp224k1_sz CODED_SECP224K1_SZ
  698    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
  699    #ifdef HAVE_ECC_BRAINPOOL
  700        #ifdef HAVE_OID_ENCODING
  701            #define CODED_BRAINPOOLP224R1    {1,3,36,3,3,2,8,1,1,5}
  702            #define CODED_BRAINPOOLP224R1_SZ 10
  703        #else
  704            #define CODED_BRAINPOOLP224R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05}
  705            #define CODED_BRAINPOOLP224R1_SZ 9
  706        #endif
  707        #ifndef WOLFSSL_ECC_CURVE_STATIC
  708            static const ecc_oid_t ecc_oid_brainpoolp224r1[] = CODED_BRAINPOOLP224R1;
  709        #else
  710            #define ecc_oid_brainpoolp224r1 CODED_BRAINPOOLP224R1
  711        #endif
  712        #define ecc_oid_brainpoolp224r1_sz CODED_BRAINPOOLP224R1_SZ
  713    #endif /* HAVE_ECC_BRAINPOOL */
  714#endif /* ECC224 */
  715#ifdef ECC239
  716    #ifndef NO_ECC_SECP
  717        #ifdef HAVE_OID_ENCODING
  718            #define CODED_PRIME239V1    {1,2,840,10045,3,1,4}
  719            #define CODED_PRIME239V1_SZ 7
  720        #else
  721            #define CODED_PRIME239V1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04}
  722            #define CODED_PRIME239V1_SZ 8
  723        #endif
  724        #ifndef WOLFSSL_ECC_CURVE_STATIC
  725            static const ecc_oid_t ecc_oid_prime239v1[] = CODED_PRIME239V1;
  726        #else
  727            #define ecc_oid_prime239v1 CODED_PRIME239V1
  728        #endif
  729        #define ecc_oid_prime239v1_sz CODED_PRIME239V1_SZ
  730    #endif /* !NO_ECC_SECP */
  731    #ifdef HAVE_ECC_SECPR2
  732        #ifdef HAVE_OID_ENCODING
  733            #define CODED_PRIME239V2    {1,2,840,10045,3,1,5}
  734            #define CODED_PRIME239V2_SZ 7
  735        #else
  736            #define CODED_PRIME239V2    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05}
  737            #define CODED_PRIME239V2_SZ 8
  738        #endif
  739        #ifndef WOLFSSL_ECC_CURVE_STATIC
  740            static const ecc_oid_t ecc_oid_prime239v2[] = CODED_PRIME239V2;
  741        #else
  742            #define ecc_oid_prime239v2 CODED_PRIME239V2
  743        #endif
  744        #define ecc_oid_prime239v2_sz CODED_PRIME239V2_SZ
  745    #endif /* HAVE_ECC_SECPR2 */
  746    #ifdef HAVE_ECC_SECPR3
  747        #ifdef HAVE_OID_ENCODING
  748            #define CODED_PRIME239V3    {1,2,840,10045,3,1,6}
  749            #define CODED_PRIME239V3_SZ 7
  750        #else
  751            #define CODED_PRIME239V3    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06}
  752            #define CODED_PRIME239V3_SZ 8
  753        #endif
  754        #ifndef WOLFSSL_ECC_CURVE_STATIC
  755            static const ecc_oid_t ecc_oid_prime239v3[] = CODED_PRIME239V3;
  756        #else
  757            #define ecc_oid_prime239v3 CODED_PRIME239V3
  758        #endif
  759        #define ecc_oid_prime239v3_sz CODED_PRIME239V3_SZ
  760    #endif /* HAVE_ECC_SECPR3 */
  761#endif /* ECC239 */
  762#ifdef ECC256
  763    #ifndef NO_ECC_SECP
  764        #ifdef HAVE_OID_ENCODING
  765            #define CODED_SECP256R1    {1,2,840,10045,3,1,7}
  766            #define CODED_SECP256R1_SZ 7
  767        #else
  768            #define CODED_SECP256R1    {0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}
  769            #define CODED_SECP256R1_SZ 8
  770        #endif
  771        #ifndef WOLFSSL_ECC_CURVE_STATIC
  772            static const ecc_oid_t ecc_oid_secp256r1[] = CODED_SECP256R1;
  773        #else
  774            #define ecc_oid_secp256r1 CODED_SECP256R1
  775        #endif
  776        #define ecc_oid_secp256r1_sz CODED_SECP256R1_SZ
  777    #endif /* !NO_ECC_SECP */
  778    #ifdef HAVE_ECC_KOBLITZ
  779        #ifdef HAVE_OID_ENCODING
  780            #define CODED_SECP256K1    {1,3,132,0,10}
  781            #define CODED_SECP256K1_SZ 5
  782        #else
  783            #define CODED_SECP256K1    {0x2B,0x81,0x04,0x00,0x0A}
  784            #define CODED_SECP256K1_SZ 5
  785        #endif
  786        #ifndef WOLFSSL_ECC_CURVE_STATIC
  787            static const ecc_oid_t ecc_oid_secp256k1[] = CODED_SECP256K1;
  788        #else
  789            #define ecc_oid_secp256k1 CODED_SECP256K1
  790        #endif
  791        #define ecc_oid_secp256k1_sz CODED_SECP256K1_SZ
  792    #endif /* HAVE_ECC_KOBLITZ */
  793    #ifdef HAVE_ECC_BRAINPOOL
  794        #ifdef HAVE_OID_ENCODING
  795            #define CODED_BRAINPOOLP256R1    {1,3,36,3,3,2,8,1,1,7}
  796            #define CODED_BRAINPOOLP256R1_SZ 10
  797        #else
  798            #define CODED_BRAINPOOLP256R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07}
  799            #define CODED_BRAINPOOLP256R1_SZ 9
  800        #endif
  801        #ifndef WOLFSSL_ECC_CURVE_STATIC
  802            static const ecc_oid_t ecc_oid_brainpoolp256r1[] = CODED_BRAINPOOLP256R1;
  803        #else
  804            #define ecc_oid_brainpoolp256r1 CODED_BRAINPOOLP256R1
  805        #endif
  806        #define ecc_oid_brainpoolp256r1_sz CODED_BRAINPOOLP256R1_SZ
  807    #endif /* HAVE_ECC_BRAINPOOL */
  808#endif /* ECC256 */
  809    #if defined(WOLFSSL_SM2)
  810        #ifdef HAVE_OID_ENCODING
  811            #define CODED_SM2P256V1    {1,2,156,10197,1,301}
  812            #define CODED_SM2P256V1_SZ 6
  813        #else
  814            #define CODED_SM2P256V1 {0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2d}
  815            #define CODED_SM2P256V1_SZ 8
  816        #endif
  817        #ifndef WOLFSSL_ECC_CURVE_STATIC
  818            static const ecc_oid_t ecc_oid_sm2p256v1[] = CODED_SM2P256V1;
  819        #else
  820            #define ecc_oid_sm2p256v1 CODED_SM2P256V1
  821        #endif
  822        #define ecc_oid_sm2p256v1_sz CODED_SM2P256V1_SZ
  823    #endif /* WOLFSSL_SM2 */
  824#ifdef ECC320
  825    #ifdef HAVE_ECC_BRAINPOOL
  826        #ifdef HAVE_OID_ENCODING
  827            #define CODED_BRAINPOOLP320R1    {1,3,36,3,3,2,8,1,1,9}
  828            #define CODED_BRAINPOOLP320R1_SZ 10
  829        #else
  830            #define CODED_BRAINPOOLP320R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09}
  831            #define CODED_BRAINPOOLP320R1_SZ 9
  832        #endif
  833        #ifndef WOLFSSL_ECC_CURVE_STATIC
  834            static const ecc_oid_t ecc_oid_brainpoolp320r1[] = CODED_BRAINPOOLP320R1;
  835        #else
  836            #define ecc_oid_brainpoolp320r1 CODED_BRAINPOOLP320R1
  837        #endif
  838        #define ecc_oid_brainpoolp320r1_sz CODED_BRAINPOOLP320R1_SZ
  839    #endif /* HAVE_ECC_BRAINPOOL */
  840#endif /* ECC320 */
  841#ifdef ECC384
  842    #ifndef NO_ECC_SECP
  843        #ifdef HAVE_OID_ENCODING
  844            #define CODED_SECP384R1    {1,3,132,0,34}
  845            #define CODED_SECP384R1_SZ 5
  846        #else
  847            #define CODED_SECP384R1    {0x2B,0x81,0x04,0x00,0x22}
  848            #define CODED_SECP384R1_SZ 5
  849        #endif
  850        #ifndef WOLFSSL_ECC_CURVE_STATIC
  851            static const ecc_oid_t ecc_oid_secp384r1[] = CODED_SECP384R1;
  852            #define CODED_SECP384R1_OID ecc_oid_secp384r1
  853        #else
  854            #define ecc_oid_secp384r1 CODED_SECP384R1
  855        #endif
  856        #define ecc_oid_secp384r1_sz CODED_SECP384R1_SZ
  857    #endif /* !NO_ECC_SECP */
  858    #ifdef HAVE_ECC_BRAINPOOL
  859        #ifdef HAVE_OID_ENCODING
  860            #define CODED_BRAINPOOLP384R1    {1,3,36,3,3,2,8,1,1,11}
  861            #define CODED_BRAINPOOLP384R1_SZ 10
  862        #else
  863            #define CODED_BRAINPOOLP384R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B}
  864            #define CODED_BRAINPOOLP384R1_SZ 9
  865        #endif
  866        #ifndef WOLFSSL_ECC_CURVE_STATIC
  867            static const ecc_oid_t ecc_oid_brainpoolp384r1[] = CODED_BRAINPOOLP384R1;
  868        #else
  869            #define ecc_oid_brainpoolp384r1 CODED_BRAINPOOLP384R1
  870        #endif
  871        #define ecc_oid_brainpoolp384r1_sz CODED_BRAINPOOLP384R1_SZ
  872    #endif /* HAVE_ECC_BRAINPOOL */
  873#endif /* ECC384 */
  874#ifdef ECC512
  875    #ifdef HAVE_ECC_BRAINPOOL
  876        #ifdef HAVE_OID_ENCODING
  877            #define CODED_BRAINPOOLP512R1    {1,3,36,3,3,2,8,1,1,13}
  878            #define CODED_BRAINPOOLP512R1_SZ 10
  879        #else
  880            #define CODED_BRAINPOOLP512R1    {0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D}
  881            #define CODED_BRAINPOOLP512R1_SZ 9
  882        #endif
  883        #ifndef WOLFSSL_ECC_CURVE_STATIC
  884            static const ecc_oid_t ecc_oid_brainpoolp512r1[] = CODED_BRAINPOOLP512R1;
  885        #else
  886            #define ecc_oid_brainpoolp512r1 CODED_BRAINPOOLP512R1
  887        #endif
  888        #define ecc_oid_brainpoolp512r1_sz CODED_BRAINPOOLP512R1_SZ
  889    #endif /* HAVE_ECC_BRAINPOOL */
  890#endif /* ECC512 */
  891#ifdef ECC521
  892    #ifndef NO_ECC_SECP
  893        #ifdef HAVE_OID_ENCODING
  894            #define CODED_SECP521R1     {1,3,132,0,35}
  895            #define CODED_SECP521R1_SZ 5
  896        #else
  897            #define CODED_SECP521R1     {0x2B,0x81,0x04,0x00,0x23}
  898            #define CODED_SECP521R1_SZ 5
  899        #endif
  900        #ifndef WOLFSSL_ECC_CURVE_STATIC
  901            static const ecc_oid_t ecc_oid_secp521r1[] = CODED_SECP521R1;
  902        #else
  903            #define ecc_oid_secp521r1 CODED_SECP521R1
  904        #endif
  905        #define ecc_oid_secp521r1_sz CODED_SECP521R1_SZ
  906    #endif /* !NO_ECC_SECP */
  907#endif /* ECC521 */
  908
  909
  910/* This holds the key settings.
  911   ***MUST*** be organized by size from smallest to largest. */
  912
  913#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
  914    #undef ecc_sets
  915    #undef ecc_sets_count
  916#endif
  917
  918#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
  919static
  920#endif
  921const ecc_set_type ecc_sets[] = {
  922#ifdef ECC112
  923    #ifndef NO_ECC_SECP
  924    {
  925        14,                             /* size/bytes */
  926        ECC_SECP112R1,                  /* ID         */
  927        "SECP112R1",                    /* curve name */
  928        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
  929        "DB7C2ABF62E35E668076BEAD2088", /* A          */
  930        "659EF8BA043916EEDE8911702B22", /* B          */
  931        "DB7C2ABF62E35E7628DFAC6561C5", /* order      */
  932        "9487239995A5EE76B55F9C2F098",  /* Gx         */
  933        "A89CE5AF8724C0A23E0E0FF77500", /* Gy         */
  934        ecc_oid_secp112r1,              /* oid/oidSz  */
  935        ecc_oid_secp112r1_sz,
  936        ECC_SECP112R1_OID,              /* oid sum    */
  937        1,                              /* cofactor   */
  938    },
  939    #endif /* !NO_ECC_SECP */
  940    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
  941    {
  942        14,                             /* size/bytes */
  943        ECC_SECP112R2,                  /* ID         */
  944        "SECP112R2",                    /* curve name */
  945        "DB7C2ABF62E35E668076BEAD208B", /* prime      */
  946        "6127C24C05F38A0AAAF65C0EF02C", /* A          */
  947        "51DEF1815DB5ED74FCC34C85D709", /* B          */
  948        "36DF0AAFD8B8D7597CA10520D04B", /* order      */
  949        "4BA30AB5E892B4E1649DD0928643", /* Gx         */
  950        "ADCD46F5882E3747DEF36E956E97", /* Gy         */
  951        ecc_oid_secp112r2,              /* oid/oidSz  */
  952        ecc_oid_secp112r2_sz,
  953        ECC_SECP112R2_OID,              /* oid sum    */
  954        4,                              /* cofactor   */
  955    },
  956    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
  957#endif /* ECC112 */
  958#ifdef ECC128
  959    #ifndef NO_ECC_SECP
  960    {
  961        16,                                 /* size/bytes */
  962        ECC_SECP128R1,                      /* ID         */
  963        "SECP128R1",                        /* curve name */
  964        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
  965        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
  966        "E87579C11079F43DD824993C2CEE5ED3", /* B          */
  967        "FFFFFFFE0000000075A30D1B9038A115", /* order      */
  968        "161FF7528B899B2D0C28607CA52C5B86", /* Gx         */
  969        "CF5AC8395BAFEB13C02DA292DDED7A83", /* Gy         */
  970        ecc_oid_secp128r1,                  /* oid/oidSz  */
  971        ecc_oid_secp128r1_sz,
  972        ECC_SECP128R1_OID,                  /* oid sum    */
  973        1,                                  /* cofactor   */
  974    },
  975    #endif /* !NO_ECC_SECP */
  976    #if defined(HAVE_ECC_SECPR2) && defined(HAVE_ECC_KOBLITZ)
  977    {
  978        16,                                 /* size/bytes */
  979        ECC_SECP128R2,                      /* ID         */
  980        "SECP128R2",                        /* curve name */
  981        "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
  982        "D6031998D1B3BBFEBF59CC9BBFF9AEE1", /* A          */
  983        "5EEEFCA380D02919DC2C6558BB6D8A5D", /* B          */
  984        "3FFFFFFF7FFFFFFFBE0024720613B5A3", /* order      */
  985        "7B6AA5D85E572983E6FB32A7CDEBC140", /* Gx         */
  986        "27B6916A894D3AEE7106FE805FC34B44", /* Gy         */
  987        ecc_oid_secp128r2,                  /* oid/oidSz  */
  988        ecc_oid_secp128r2_sz,
  989        ECC_SECP128R2_OID,                  /* oid sum    */
  990        4,                                  /* cofactor   */
  991    },
  992    #endif /* HAVE_ECC_SECPR2 && HAVE_ECC_KOBLITZ */
  993#endif /* ECC128 */
  994#ifdef ECC160
  995#ifndef FP_ECC
  996    #ifndef NO_ECC_SECP
  997    {
  998        20,                                         /* size/bytes */
  999        ECC_SECP160R1,                              /* ID         */
 1000        "SECP160R1",                                /* curve name */
 1001        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", /* prime      */
 1002        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", /* A          */
 1003        "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", /* B          */
 1004        "100000000000000000001F4C8F927AED3CA752257",/* order      */
 1005        "4A96B5688EF573284664698968C38BB913CBFC82", /* Gx         */
 1006        "23A628553168947D59DCC912042351377AC5FB32", /* Gy         */
 1007        ecc_oid_secp160r1,                          /* oid/oidSz  */
 1008        ecc_oid_secp160r1_sz,
 1009        ECC_SECP160R1_OID,                          /* oid sum    */
 1010        1,                                          /* cofactor   */
 1011    },
 1012    #endif /* !NO_ECC_SECP */
 1013    #ifdef HAVE_ECC_SECPR2
 1014    {
 1015        20,                                         /* size/bytes */
 1016        ECC_SECP160R2,                              /* ID         */
 1017        "SECP160R2",                                /* curve name */
 1018        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
 1019        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", /* A          */
 1020        "B4E134D3FB59EB8BAB57274904664D5AF50388BA", /* B          */
 1021        "100000000000000000000351EE786A818F3A1A16B",/* order      */
 1022        "52DCB034293A117E1F4FF11B30F7199D3144CE6D", /* Gx         */
 1023        "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", /* Gy         */
 1024        ecc_oid_secp160r2,                          /* oid/oidSz  */
 1025        ecc_oid_secp160r2_sz,
 1026        ECC_SECP160R2_OID,                          /* oid sum    */
 1027        1,                                          /* cofactor   */
 1028    },
 1029    #endif /* HAVE_ECC_SECPR2 */
 1030    #ifdef HAVE_ECC_KOBLITZ
 1031    {
 1032        20,                                         /* size/bytes */
 1033        ECC_SECP160K1,                              /* ID         */
 1034        "SECP160K1",                                /* curve name */
 1035        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", /* prime      */
 1036        "0000000000000000000000000000000000000000", /* A          */
 1037        "0000000000000000000000000000000000000007", /* B          */
 1038        "100000000000000000001B8FA16DFAB9ACA16B6B3",/* order      */
 1039        "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", /* Gx         */
 1040        "938CF935318FDCED6BC28286531733C3F03C4FEE", /* Gy         */
 1041        ecc_oid_secp160k1,                          /* oid/oidSz  */
 1042        ecc_oid_secp160k1_sz,
 1043        ECC_SECP160K1_OID,                          /* oid sum    */
 1044        1,                                          /* cofactor   */
 1045    },
 1046    #endif /* HAVE_ECC_KOBLITZ */
 1047#endif /* !FP_ECC */
 1048    #ifdef HAVE_ECC_BRAINPOOL
 1049    {
 1050        20,                                         /* size/bytes */
 1051        ECC_BRAINPOOLP160R1,                        /* ID         */
 1052        "BRAINPOOLP160R1",                          /* curve name */
 1053        "E95E4A5F737059DC60DFC7AD95B3D8139515620F", /* prime      */
 1054        "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", /* A          */
 1055        "1E589A8595423412134FAA2DBDEC95C8D8675E58", /* B          */
 1056        "E95E4A5F737059DC60DF5991D45029409E60FC09", /* order      */
 1057        "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", /* Gx         */
 1058        "1667CB477A1A8EC338F94741669C976316DA6321", /* Gy         */
 1059        ecc_oid_brainpoolp160r1,                    /* oid/oidSz  */
 1060        ecc_oid_brainpoolp160r1_sz,
 1061        ECC_BRAINPOOLP160R1_OID,                    /* oid sum    */
 1062        1,                                          /* cofactor   */
 1063    },
 1064    #endif /* HAVE_ECC_BRAINPOOL */
 1065#endif /* ECC160 */
 1066#ifdef ECC192
 1067    #ifndef NO_ECC_SECP
 1068    {
 1069        24,                                                 /* size/bytes */
 1070        ECC_SECP192R1,                                      /* ID         */
 1071        "SECP192R1",                                        /* curve name */
 1072        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
 1073        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
 1074        "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", /* B          */
 1075        "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", /* order      */
 1076        "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", /* Gx         */
 1077        "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",  /* Gy         */
 1078        ecc_oid_secp192r1,                                  /* oid/oidSz  */
 1079        ecc_oid_secp192r1_sz,
 1080        ECC_SECP192R1_OID,                                  /* oid sum    */
 1081        1,                                                  /* cofactor   */
 1082    },
 1083    #endif /* !NO_ECC_SECP */
 1084    #ifdef HAVE_ECC_SECPR2
 1085    {
 1086        24,                                                 /* size/bytes */
 1087        ECC_PRIME192V2,                                     /* ID         */
 1088        "PRIME192V2",                                       /* curve name */
 1089        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
 1090        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
 1091        "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", /* B          */
 1092        "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", /* order      */
 1093        "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", /* Gx         */
 1094        "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", /* Gy         */
 1095        ecc_oid_prime192v2,                                 /* oid/oidSz  */
 1096        ecc_oid_prime192v2_sz,
 1097        ECC_PRIME192V2_OID,                                 /* oid sum    */
 1098        1,                                                  /* cofactor   */
 1099    },
 1100    #endif /* HAVE_ECC_SECPR2 */
 1101    #ifdef HAVE_ECC_SECPR3
 1102    {
 1103        24,                                                 /* size/bytes */
 1104        ECC_PRIME192V3,                                     /* ID         */
 1105        "PRIME192V3",                                       /* curve name */
 1106        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", /* prime      */
 1107        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", /* A          */
 1108        "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", /* B          */
 1109        "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", /* order      */
 1110        "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", /* Gx         */
 1111        "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", /* Gy         */
 1112        ecc_oid_prime192v3,                                 /* oid/oidSz  */
 1113        ecc_oid_prime192v3_sz,
 1114        ECC_PRIME192V3_OID,                                 /* oid sum    */
 1115        1,                                                  /* cofactor   */
 1116    },
 1117    #endif /* HAVE_ECC_SECPR3 */
 1118    #ifdef HAVE_ECC_KOBLITZ
 1119    {
 1120        24,                                                 /* size/bytes */
 1121        ECC_SECP192K1,                                      /* ID         */
 1122        "SECP192K1",                                        /* curve name */
 1123        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", /* prime      */
 1124        "000000000000000000000000000000000000000000000000", /* A          */
 1125        "000000000000000000000000000000000000000000000003", /* B          */
 1126        "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", /* order      */
 1127        "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", /* Gx         */
 1128        "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", /* Gy         */
 1129        ecc_oid_secp192k1,                                  /* oid/oidSz  */
 1130        ecc_oid_secp192k1_sz,
 1131        ECC_SECP192K1_OID,                                  /* oid sum    */
 1132        1,                                                  /* cofactor   */
 1133    },
 1134    #endif /* HAVE_ECC_KOBLITZ */
 1135    #ifdef HAVE_ECC_BRAINPOOL
 1136    {
 1137        24,                                                 /* size/bytes */
 1138        ECC_BRAINPOOLP192R1,                                /* ID         */
 1139        "BRAINPOOLP192R1",                                  /* curve name */
 1140        "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", /* prime      */
 1141        "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", /* A          */
 1142        "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", /* B          */
 1143        "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", /* order      */
 1144        "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", /* Gx         */
 1145        "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", /* Gy         */
 1146        ecc_oid_brainpoolp192r1,                            /* oid/oidSz  */
 1147        ecc_oid_brainpoolp192r1_sz,
 1148        ECC_BRAINPOOLP192R1_OID,                            /* oid sum    */
 1149        1,                                                  /* cofactor   */
 1150    },
 1151    #endif /* HAVE_ECC_BRAINPOOL */
 1152#endif /* ECC192 */
 1153#ifdef ECC224
 1154    #ifndef NO_ECC_SECP
 1155    {
 1156        28,                                                         /* size/bytes */
 1157        ECC_SECP224R1,                                              /* ID         */
 1158        "SECP224R1",                                                /* curve name */
 1159        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", /* prime      */
 1160        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", /* A          */
 1161        "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", /* B          */
 1162        "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", /* order      */
 1163        "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", /* Gx         */
 1164        "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", /* Gy         */
 1165        ecc_oid_secp224r1,                                          /* oid/oidSz  */
 1166        ecc_oid_secp224r1_sz,
 1167        ECC_SECP224R1_OID,                                          /* oid sum    */
 1168        1,                                                          /* cofactor   */
 1169    },
 1170    #endif /* !NO_ECC_SECP */
 1171    #if defined(HAVE_ECC_KOBLITZ) && !defined(FP_ECC)
 1172    {
 1173        28,                                                         /* size/bytes */
 1174        ECC_SECP224K1,                                              /* ID         */
 1175        "SECP224K1",                                                /* curve name */
 1176        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", /* prime      */
 1177        "00000000000000000000000000000000000000000000000000000000", /* A          */
 1178        "00000000000000000000000000000000000000000000000000000005", /* B          */
 1179        "10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",/* order      */
 1180        "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", /* Gx         */
 1181        "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", /* Gy         */
 1182        ecc_oid_secp224k1,                                          /* oid/oidSz  */
 1183        ecc_oid_secp224k1_sz,
 1184        ECC_SECP224K1_OID,                                          /* oid sum    */
 1185        1,                                                          /* cofactor   */
 1186    },
 1187    #endif /* HAVE_ECC_KOBLITZ && !FP_ECC */
 1188    #ifdef HAVE_ECC_BRAINPOOL
 1189    {
 1190        28,                                                         /* size/bytes */
 1191        ECC_BRAINPOOLP224R1,                                        /* ID         */
 1192        "BRAINPOOLP224R1",                                          /* curve name */
 1193        "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", /* prime      */
 1194        "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", /* A          */
 1195        "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", /* B          */
 1196        "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", /* order      */
 1197        "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", /* Gx         */
 1198        "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", /* Gy         */
 1199        ecc_oid_brainpoolp224r1,                                    /* oid/oidSz  */
 1200        ecc_oid_brainpoolp224r1_sz,
 1201        ECC_BRAINPOOLP224R1_OID,                                    /* oid sum    */
 1202        1,                                                          /* cofactor   */
 1203    },
 1204    #endif /* HAVE_ECC_BRAINPOOL */
 1205#endif /* ECC224 */
 1206#ifdef ECC239
 1207    #ifndef NO_ECC_SECP
 1208    {
 1209        30,                                                             /* size/bytes */
 1210        ECC_PRIME239V1,                                                 /* ID         */
 1211        "PRIME239V1",                                                   /* curve name */
 1212        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
 1213        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
 1214        "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", /* B          */
 1215        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", /* order      */
 1216        "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", /* Gx         */
 1217        "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", /* Gy         */
 1218        ecc_oid_prime239v1,                                             /* oid/oidSz  */
 1219        ecc_oid_prime239v1_sz,
 1220        ECC_PRIME239V1_OID,                                             /* oid sum    */
 1221        1,                                                              /* cofactor   */
 1222    },
 1223    #endif /* !NO_ECC_SECP */
 1224    #ifdef HAVE_ECC_SECPR2
 1225    {
 1226        30,                                                             /* size/bytes */
 1227        ECC_PRIME239V2,                                                 /* ID         */
 1228        "PRIME239V2",                                                   /* curve name */
 1229        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
 1230        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
 1231        "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", /* B          */
 1232        "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", /* order      */
 1233        "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", /* Gx         */
 1234        "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", /* Gy         */
 1235        ecc_oid_prime239v2,                                             /* oid/oidSz  */
 1236        ecc_oid_prime239v2_sz,
 1237        ECC_PRIME239V2_OID,                                             /* oid sum    */
 1238        1,                                                              /* cofactor   */
 1239    },
 1240    #endif /* HAVE_ECC_SECPR2 */
 1241    #ifdef HAVE_ECC_SECPR3
 1242    {
 1243        30,                                                             /* size/bytes */
 1244        ECC_PRIME239V3,                                                 /* ID         */
 1245        "PRIME239V3",                                                   /* curve name */
 1246        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", /* prime      */
 1247        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", /* A          */
 1248        "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", /* B          */
 1249        "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", /* order      */
 1250        "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", /* Gx         */
 1251        "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", /* Gy         */
 1252        ecc_oid_prime239v3,                                             /* oid/oidSz  */
 1253        ecc_oid_prime239v3_sz,
 1254        ECC_PRIME239V3_OID,                                             /* oid sum    */
 1255        1,                                                              /* cofactor   */
 1256    },
 1257    #endif /* HAVE_ECC_SECPR3 */
 1258#endif /* ECC239 */
 1259#ifdef ECC256
 1260    #ifndef NO_ECC_SECP
 1261    {
 1262        32,                                                                 /* size/bytes */
 1263        ECC_SECP256R1,                                                      /* ID         */
 1264        "SECP256R1",                                                        /* curve name */
 1265        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
 1266        "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
 1267        "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", /* B          */
 1268        "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", /* order      */
 1269        "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", /* Gx         */
 1270        "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", /* Gy         */
 1271        ecc_oid_secp256r1,                                                  /* oid/oidSz  */
 1272        ecc_oid_secp256r1_sz,
 1273        ECC_SECP256R1_OID,                                                  /* oid sum    */
 1274        1,                                                                  /* cofactor   */
 1275    },
 1276    #endif /* !NO_ECC_SECP */
 1277    #ifdef HAVE_ECC_KOBLITZ
 1278    {
 1279        32,                                                                 /* size/bytes */
 1280        ECC_SECP256K1,                                                      /* ID         */
 1281        "SECP256K1",                                                        /* curve name */
 1282        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", /* prime      */
 1283        "0000000000000000000000000000000000000000000000000000000000000000", /* A          */
 1284        "0000000000000000000000000000000000000000000000000000000000000007", /* B          */
 1285        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", /* order      */
 1286        "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", /* Gx         */
 1287        "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", /* Gy         */
 1288        ecc_oid_secp256k1,                                                  /* oid/oidSz  */
 1289        ecc_oid_secp256k1_sz,
 1290        ECC_SECP256K1_OID,                                                  /* oid sum    */
 1291        1,                                                                  /* cofactor   */
 1292    },
 1293    #endif /* HAVE_ECC_KOBLITZ */
 1294    #ifdef HAVE_ECC_BRAINPOOL
 1295    {
 1296        32,                                                                 /* size/bytes */
 1297        ECC_BRAINPOOLP256R1,                                                /* ID         */
 1298        "BRAINPOOLP256R1",                                                  /* curve name */
 1299        "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", /* prime      */
 1300        "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", /* A          */
 1301        "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", /* B          */
 1302        "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", /* order      */
 1303        "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", /* Gx         */
 1304        "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", /* Gy         */
 1305        ecc_oid_brainpoolp256r1,                                            /* oid/oidSz  */
 1306        ecc_oid_brainpoolp256r1_sz,
 1307        ECC_BRAINPOOLP256R1_OID,                                            /* oid sum    */
 1308        1,                                                                  /* cofactor   */
 1309    },
 1310    #endif /* HAVE_ECC_BRAINPOOL */
 1311#endif /* ECC256 */
 1312    #if defined(WOLFSSL_SM2)
 1313    {
 1314        32,                                                     /* size/bytes */
 1315        ECC_SM2P256V1,                                          /* ID         */
 1316        "SM2P256V1",                                            /* curve name */
 1317
 1318        /* bottom of draft-shen-sm2-ecdsa-02, recommended values */
 1319        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", /* prime */
 1320        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", /* A */
 1321        "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", /* B */
 1322        "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", /* order */
 1323        "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", /* Gx */
 1324        "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", /* Gy */
 1325        ecc_oid_sm2p256v1,                                      /* oid/oidSz  */
 1326        ecc_oid_sm2p256v1_sz,
 1327        ECC_SM2P256V1_OID,                                      /* oid sum    */
 1328        1,                                                      /* cofactor   */
 1329    },
 1330    #endif /* WOLFSSL_SM2 */
 1331#ifdef ECC320
 1332    #ifdef HAVE_ECC_BRAINPOOL
 1333    {
 1334        40,                                                                                 /* size/bytes */
 1335        ECC_BRAINPOOLP320R1,                                                                /* ID         */
 1336        "BRAINPOOLP320R1",                                                                  /* curve name */
 1337        "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", /* prime      */
 1338        "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", /* A          */
 1339        "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", /* B          */
 1340        "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", /* order      */
 1341        "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", /* Gx         */
 1342        "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", /* Gy         */
 1343        ecc_oid_brainpoolp320r1, ecc_oid_brainpoolp320r1_sz,                                /* oid/oidSz  */
 1344        ECC_BRAINPOOLP320R1_OID,                                                            /* oid sum    */
 1345        1,                                                                                  /* cofactor   */
 1346    },
 1347    #endif /* HAVE_ECC_BRAINPOOL */
 1348#endif /* ECC320 */
 1349#ifdef ECC384
 1350    #ifndef NO_ECC_SECP
 1351    {
 1352        48,                                                                                                 /* size/bytes */
 1353        ECC_SECP384R1,                                                                                      /* ID         */
 1354        "SECP384R1",                                                                                        /* curve name */
 1355        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", /* prime      */
 1356        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", /* A          */
 1357        "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", /* B          */
 1358        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", /* order      */
 1359        "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", /* Gx         */
 1360        "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", /* Gy         */
 1361        ecc_oid_secp384r1, ecc_oid_secp384r1_sz,                                                            /* oid/oidSz  */
 1362        ECC_SECP384R1_OID,                                                                                  /* oid sum    */
 1363        1,                                                                                                  /* cofactor   */
 1364    },
 1365    #endif /* !NO_ECC_SECP */
 1366    #ifdef HAVE_ECC_BRAINPOOL
 1367    {
 1368        48,                                                                                                 /* size/bytes */
 1369        ECC_BRAINPOOLP384R1,                                                                                /* ID         */
 1370        "BRAINPOOLP384R1",                                                                                  /* curve name */
 1371        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", /* prime      */
 1372        "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", /* A          */
 1373        "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", /* B          */
 1374        "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", /* order      */
 1375        "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", /* Gx         */
 1376        "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", /* Gy         */
 1377        ecc_oid_brainpoolp384r1, ecc_oid_brainpoolp384r1_sz,                                                /* oid/oidSz  */
 1378        ECC_BRAINPOOLP384R1_OID,                                                                            /* oid sum    */
 1379        1,                                                                                                  /* cofactor   */
 1380    },
 1381    #endif /* HAVE_ECC_BRAINPOOL */
 1382#endif /* ECC384 */
 1383#ifdef ECC512
 1384    #ifdef HAVE_ECC_BRAINPOOL
 1385    {
 1386        64,                                                                                                                                 /* size/bytes */
 1387        ECC_BRAINPOOLP512R1,                                                                                                                /* ID         */
 1388        "BRAINPOOLP512R1",                                                                                                                  /* curve name */
 1389        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", /* prime      */
 1390        "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", /* A          */
 1391        "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", /* B          */
 1392        "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", /* order      */
 1393        "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", /* Gx         */
 1394        "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", /* Gy         */
 1395        ecc_oid_brainpoolp512r1, ecc_oid_brainpoolp512r1_sz,                                                                                /* oid/oidSz  */
 1396        ECC_BRAINPOOLP512R1_OID,                                                                                                            /* oid sum    */
 1397        1,                                                                                                                                  /* cofactor   */
 1398    },
 1399    #endif /* HAVE_ECC_BRAINPOOL */
 1400#endif /* ECC512 */
 1401#ifdef ECC521
 1402    #ifndef NO_ECC_SECP
 1403    {
 1404        66,                                                                                                                                    /* size/bytes */
 1405        ECC_SECP521R1,                                                                                                                         /* ID         */
 1406        "SECP521R1",                                                                                                                           /* curve name */
 1407        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* prime      */
 1408        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", /* A          */
 1409        "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",  /* B          */
 1410        "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", /* order      */
 1411        "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",  /* Gx         */
 1412        "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", /* Gy         */
 1413        ecc_oid_secp521r1, ecc_oid_secp521r1_sz,                                                                                               /* oid/oidSz  */
 1414        ECC_SECP521R1_OID,                                                                                                                     /* oid sum    */
 1415        1,                                                                                                                                     /* cofactor   */
 1416    },
 1417    #endif /* !NO_ECC_SECP */
 1418#endif /* ECC521 */
 1419#ifdef WOLFCRYPT_HAVE_SAKKE
 1420    {
 1421        128,
 1422        ECC_SAKKE_1,
 1423        "SAKKE1",
 1424        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FEB",
 1425        "997ABB1F0A563FDA65C61198DAD0657A416C0CE19CB48261BE9AE358B3E01A2EF40AAB27E2FC0F1B228730D531A59CB0E791B39FF7C88A19356D27F4A666A6D0E26C6487326B4CD4512AC5CD65681CE1B6AFF4A831852A82A7CF3C521C3C09AA9F94D6AF56971F1FFCE3E82389857DB080C5DF10AC7ACE87666D807AFEA85FE8",
 1426        "0",
 1427        "265EAEC7C2958FF69971846636B4195E905B0338672D20986FA6B8D62CF8068BBD02AAC9F8BF03C6C8A1CC354C69672C39E46CE7FDF222864D5B49FD2999A9B4389B1921CC9AD335144AB173595A07386DABFD2A0C614AA0A9F3CF14870F026AA7E535ABD5A5C7C7FF38FA08E2615F6C203177C42B1EB3A1D99B601EBFAA17FB",
 1428        "53FC09EE332C29AD0A7990053ED9B52A2B1A2FD60AEC69C698B2F204B6FF7CBFB5EDB6C0F6CE2308AB10DB9030B09E1043D5F22CDB9DFA55718BD9E7406CE8909760AF765DD5BCCB337C86548B72F2E1A702C3397A60DE74A7C1514DBA66910DD5CFB4CC80728D87EE9163A5B63F73EC80EC46C4967E0979880DC8ABEAE63895",
 1429        "0A8249063F6009F1F9F1F0533634A135D3E82016029906963D778D821E141178F5EA69F4654EC2B9E7F7F5E5F0DE55F66B598CCF9A140B2E416CFF0CA9E032B970DAE117AD547C6CCAD696B5B7652FE0AC6F1E80164AA989492D979FC5A4D5F213515AD7E9CB99A980BDAD5AD5BB4636ADB9B5706A67DCDE75573FD71BEF16D7",
 1430        #ifndef WOLFSSL_ECC_CURVE_STATIC
 1431            NULL, 0,
 1432        #else
 1433            {0}, 0,
 1434        #endif
 1435        0,
 1436        4,
 1437    },
 1438#endif
 1439#if defined(WOLFSSL_CUSTOM_CURVES) && defined(ECC_CACHE_CURVE)
 1440    /* place holder for custom curve index for cache */
 1441    {
 1442        1, /* non-zero */
 1443        ECC_CURVE_CUSTOM,
 1444        #ifndef WOLFSSL_ECC_CURVE_STATIC
 1445            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 1446        #else
 1447            {0},{0},{0},{0},{0},{0},{0},{0},
 1448        #endif
 1449        0, 0, 0
 1450    },
 1451#endif
 1452    {
 1453        0,
 1454        ECC_CURVE_INVALID,
 1455        #ifndef WOLFSSL_ECC_CURVE_STATIC
 1456            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 1457        #else
 1458            {0},{0},{0},{0},{0},{0},{0},{0},
 1459        #endif
 1460        0, 0, 0
 1461    }
 1462};
 1463#define ECC_SET_COUNT   (sizeof(ecc_sets)/sizeof(ecc_set_type))
 1464#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0)
 1465static
 1466#endif
 1467const size_t ecc_sets_count = ECC_SET_COUNT - 1;
 1468
 1469const ecc_set_type *wc_ecc_get_sets(void) {
 1470    return ecc_sets;
 1471}
 1472size_t wc_ecc_get_sets_count(void) {
 1473    return ecc_sets_count;
 1474}
 1475
 1476#ifdef HAVE_OID_ENCODING
 1477    /* encoded OID cache */
 1478    typedef struct {
 1479        word32 oidSz;
 1480        byte oid[ECC_MAX_OID_LEN];
 1481    } oid_cache_t;
 1482    static oid_cache_t ecc_oid_cache[ECC_SET_COUNT];
 1483
 1484    static wolfSSL_Mutex ecc_oid_cache_lock
 1485        WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_oid_cache_lock);
 1486#ifndef WOLFSSL_MUTEX_INITIALIZER
 1487    static volatile int eccOidLockInit = 0;
 1488#endif
 1489#endif /* HAVE_OID_ENCODING */
 1490
 1491/* Forward declarations */
 1492#if defined(HAVE_COMP_KEY) && defined(HAVE_ECC_KEY_EXPORT)
 1493static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen);
 1494#endif
 1495#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
 1496static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
 1497    mp_int* prime, mp_int* order);
 1498#endif
 1499static int _ecc_validate_public_key(ecc_key* key, int partial, int priv);
 1500#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
 1501    !defined(WOLFSSL_KCAPI_ECC)
 1502static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
 1503#endif
 1504
 1505
 1506#ifdef HAVE_COMP_KEY
 1507#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
 1508    !defined(WOLFSSL_CRYPTOCELL)
 1509
 1510#ifndef WOLFSSL_SP_MATH
 1511#if !defined(SQRTMOD_USE_MOD_EXP)
 1512static int mp_jacobi(mp_int* a, mp_int* n, int* c);
 1513#endif
 1514static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
 1515#endif
 1516#endif
 1517#endif
 1518
 1519
 1520/* Curve Specs */
 1521typedef struct ecc_curve_spec {
 1522    const ecc_set_type* dp;
 1523
 1524    mp_int* prime;
 1525    mp_int* Af;
 1526    mp_int* Bf;
 1527    mp_int* order;
 1528    mp_int* Gx;
 1529    mp_int* Gy;
 1530
 1531#ifdef ECC_CACHE_CURVE
 1532    mp_int prime_lcl;
 1533    mp_int Af_lcl;
 1534    mp_int Bf_lcl;
 1535    mp_int order_lcl;
 1536    mp_int Gx_lcl;
 1537    mp_int Gy_lcl;
 1538#else
 1539#ifdef WOLFSSL_SP_MATH_ALL
 1540    unsigned char* spec_ints;
 1541#else
 1542    mp_int* spec_ints;
 1543#endif
 1544    word32 spec_count;
 1545    word32 spec_use;
 1546#endif
 1547
 1548    byte load_mask;
 1549} ecc_curve_spec;
 1550
 1551    #define ECC_CURVE_FIELD_NONE    0x00
 1552    #define ECC_CURVE_FIELD_PRIME   0x01
 1553    #define ECC_CURVE_FIELD_AF      0x02
 1554    #define ECC_CURVE_FIELD_BF      0x04
 1555    #define ECC_CURVE_FIELD_ORDER   0x08
 1556    #define ECC_CURVE_FIELD_GX      0x10
 1557    #define ECC_CURVE_FIELD_GY      0x20
 1558    #define ECC_CURVE_FIELD_ALL     0x3F
 1559    #define ECC_CURVE_FIELD_COUNT   6
 1560
 1561#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 1562static const u32 xil_curve_type[ECC_CURVE_MAX] = {
 1563        [ECC_SECP384R1] = WOLFSSL_XSECURE_ECC_NIST_P384,
 1564        [ECC_SECP521R1] = WOLFSSL_XSECURE_ECC_NIST_P521,
 1565};
 1566
 1567static void buf_reverse(byte *outbuf, const byte *inbuf, word32 len)
 1568{
 1569    word32 up, down;
 1570    up = 0;
 1571    down = len - 1;
 1572    while (up < len)
 1573        outbuf[up++] = inbuf[down--];
 1574}
 1575
 1576static int xil_mpi_import(mp_int *mpi,
 1577                          const byte *inbuf,
 1578                          word32 len,
 1579                          void* heap)
 1580{
 1581    int err;
 1582#ifdef WOLFSSL_SMALL_STACK
 1583    byte* buf = NULL;
 1584#else
 1585    byte buf[MAX_ECC_BYTES];
 1586
 1587    if (len > MAX_ECC_BYTES)
 1588        return BUFFER_E;
 1589#endif
 1590
 1591    WC_ALLOC_VAR_EX(buf, byte, len, heap, DYNAMIC_TYPE_PRIVATE_KEY,
 1592        return MEMORY_E);
 1593    buf_reverse(buf, inbuf, len);
 1594
 1595    err = mp_read_unsigned_bin(mpi, buf, len);
 1596    ForceZero(buf, len);
 1597    WC_FREE_VAR_EX(buf, heap, DYNAMIC_TYPE_PRIVATE_KEY);
 1598    return err;
 1599}
 1600#endif
 1601
 1602#ifdef ECC_CACHE_CURVE
 1603    /* cache (mp_int) of the curve parameters */
 1604    #ifdef WOLFSSL_NO_MALLOC
 1605    static ecc_curve_spec ecc_curve_spec_cache[ECC_SET_COUNT];
 1606    #else
 1607    static ecc_curve_spec* ecc_curve_spec_cache[ECC_SET_COUNT];
 1608    #endif
 1609    #ifndef SINGLE_THREADED
 1610        static wolfSSL_Mutex ecc_curve_cache_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_curve_cache_mutex);
 1611    #endif
 1612
 1613    #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL
 1614    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
 1615    #define FREE_CURVE_SPECS() WC_DO_NOTHING
 1616#elif defined(WOLFSSL_SMALL_STACK)
 1617#ifdef WOLFSSL_SP_MATH_ALL
 1618    #define DECLARE_CURVE_SPECS(intcount)                               \
 1619        unsigned char* spec_ints = NULL;                                \
 1620        ecc_curve_spec curve_lcl;                                       \
 1621        ecc_curve_spec* curve = &curve_lcl;                             \
 1622        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
 1623        curve->spec_count = intcount
 1624
 1625    #define ALLOC_CURVE_SPECS(intcount, err)                            \
 1626    do {                                                                \
 1627        spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(  \
 1628            MAX_ECC_BITS_USE)) * (intcount), NULL,                      \
 1629            DYNAMIC_TYPE_ECC);                                          \
 1630        if (spec_ints == NULL)                                          \
 1631            (err) = MEMORY_E;                                           \
 1632        else {                                                          \
 1633            curve->spec_ints = spec_ints;                               \
 1634            (err) = MP_OKAY;                                            \
 1635        }                                                               \
 1636    } while (0)
 1637#else
 1638    #define DECLARE_CURVE_SPECS(intcount)                               \
 1639        mp_int* spec_ints = NULL;                                       \
 1640        ecc_curve_spec curve_lcl;                                       \
 1641        ecc_curve_spec* curve = &curve_lcl;                             \
 1642        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
 1643        curve->spec_count = intcount
 1644
 1645    #define ALLOC_CURVE_SPECS(intcount, err)                            \
 1646    do {                                                                \
 1647        spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \
 1648                            DYNAMIC_TYPE_ECC);                          \
 1649        if (spec_ints == NULL)                                          \
 1650            (err) = MEMORY_E;                                           \
 1651        else {                                                          \
 1652            curve->spec_ints = spec_ints;                               \
 1653            (err) = MP_OKAY;                                            \
 1654        }                                                               \
 1655    } while (0)
 1656#endif
 1657    #define FREE_CURVE_SPECS()                                          \
 1658        XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC)
 1659#else
 1660#ifdef WOLFSSL_SP_MATH_ALL
 1661    #define DECLARE_CURVE_SPECS(intcount)                               \
 1662        unsigned char spec_ints[MP_INT_SIZEOF(MP_BITS_CNT(              \
 1663            MAX_ECC_BITS_USE)) * (intcount)];                           \
 1664        ecc_curve_spec curve_lcl;                                       \
 1665        ecc_curve_spec* curve = &curve_lcl;                             \
 1666        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
 1667        curve->spec_ints = spec_ints;                                   \
 1668        curve->spec_count = (intcount)
 1669#else
 1670    #define DECLARE_CURVE_SPECS(intcount)                               \
 1671        mp_int spec_ints[(intcount)];                                   \
 1672        ecc_curve_spec curve_lcl;                                       \
 1673        ecc_curve_spec* curve = &curve_lcl;                             \
 1674        XMEMSET(curve, 0, sizeof(ecc_curve_spec));                      \
 1675        curve->spec_ints = spec_ints;                                   \
 1676        curve->spec_count = (intcount)
 1677#endif
 1678    #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY
 1679    #define FREE_CURVE_SPECS() WC_DO_NOTHING
 1680#endif /* ECC_CACHE_CURVE */
 1681
 1682static void wc_ecc_curve_cache_free_spec_item(ecc_curve_spec* curve, mp_int* item,
 1683    byte mask)
 1684{
 1685    if (item) {
 1686    #ifdef HAVE_WOLF_BIGINT
 1687        wc_bigint_free(&item->raw);
 1688    #endif
 1689        mp_clear(item);
 1690    }
 1691    curve->load_mask = (byte)(curve->load_mask & ~mask);
 1692}
 1693static void wc_ecc_curve_cache_free_spec(ecc_curve_spec* curve)
 1694{
 1695    if (curve == NULL) {
 1696        return;
 1697    }
 1698
 1699    if (curve->load_mask & ECC_CURVE_FIELD_PRIME)
 1700        wc_ecc_curve_cache_free_spec_item(curve, curve->prime, ECC_CURVE_FIELD_PRIME);
 1701    if (curve->load_mask & ECC_CURVE_FIELD_AF)
 1702        wc_ecc_curve_cache_free_spec_item(curve, curve->Af, ECC_CURVE_FIELD_AF);
 1703    if (curve->load_mask & ECC_CURVE_FIELD_BF)
 1704        wc_ecc_curve_cache_free_spec_item(curve, curve->Bf, ECC_CURVE_FIELD_BF);
 1705    if (curve->load_mask & ECC_CURVE_FIELD_ORDER)
 1706        wc_ecc_curve_cache_free_spec_item(curve, curve->order, ECC_CURVE_FIELD_ORDER);
 1707    if (curve->load_mask & ECC_CURVE_FIELD_GX)
 1708        wc_ecc_curve_cache_free_spec_item(curve, curve->Gx, ECC_CURVE_FIELD_GX);
 1709    if (curve->load_mask & ECC_CURVE_FIELD_GY)
 1710        wc_ecc_curve_cache_free_spec_item(curve, curve->Gy, ECC_CURVE_FIELD_GY);
 1711
 1712    curve->load_mask = 0;
 1713}
 1714
 1715static void wc_ecc_curve_free(ecc_curve_spec* curve)
 1716{
 1717    if (curve) {
 1718    #ifdef ECC_CACHE_CURVE
 1719        #ifdef WOLFSSL_CUSTOM_CURVES
 1720        /* only free custom curves (rest are globally cached) */
 1721        if (curve->dp && curve->dp->id == ECC_CURVE_CUSTOM) {
 1722            wc_ecc_curve_cache_free_spec(curve);
 1723            XFREE(curve, NULL, DYNAMIC_TYPE_ECC);
 1724        }
 1725        #endif
 1726    #else
 1727        wc_ecc_curve_cache_free_spec(curve);
 1728    #endif
 1729    }
 1730}
 1731
 1732static int wc_ecc_curve_cache_load_item(ecc_curve_spec* curve, const char* src,
 1733    mp_int** dst, byte mask)
 1734{
 1735    int err;
 1736
 1737#ifndef ECC_CACHE_CURVE
 1738    /* get mp_int from temp */
 1739    if (curve->spec_use >= curve->spec_count) {
 1740        WOLFSSL_MSG("Invalid DECLARE_CURVE_SPECS count");
 1741        return ECC_BAD_ARG_E;
 1742    }
 1743#ifdef WOLFSSL_SP_MATH_ALL
 1744    *dst = (mp_int*)(curve->spec_ints + MP_INT_SIZEOF(MP_BITS_CNT(
 1745        MAX_ECC_BITS_USE)) * curve->spec_use++);
 1746#else
 1747    *dst = &curve->spec_ints[curve->spec_use++];
 1748#endif
 1749#endif
 1750
 1751#ifdef WOLFSSL_SP_MATH_ALL
 1752    err = mp_init_size(*dst, MP_BITS_CNT(MAX_ECC_BITS_USE));
 1753#else
 1754    err = mp_init(*dst);
 1755#endif
 1756    if (err == MP_OKAY) {
 1757        curve->load_mask |= mask;
 1758
 1759        err = mp_read_radix(*dst, src, MP_RADIX_HEX);
 1760
 1761    #ifdef HAVE_WOLF_BIGINT
 1762        if (err == MP_OKAY)
 1763            err = wc_mp_to_bigint(*dst, &(*dst)->raw);
 1764    #endif
 1765    }
 1766    return err;
 1767}
 1768
 1769static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
 1770    byte load_mask)
 1771{
 1772    int ret = 0;
 1773    ecc_curve_spec* curve;
 1774    byte load_items = 0; /* mask of items to load */
 1775#ifdef ECC_CACHE_CURVE
 1776    int x;
 1777#endif
 1778
 1779    if (dp == NULL || pCurve == NULL)
 1780        return BAD_FUNC_ARG;
 1781
 1782#ifdef ECC_CACHE_CURVE
 1783    x = wc_ecc_get_curve_idx(dp->id);
 1784    if (x == ECC_CURVE_INVALID)
 1785        return ECC_BAD_ARG_E;
 1786
 1787#if !defined(SINGLE_THREADED)
 1788    ret = wc_LockMutex(&ecc_curve_cache_mutex);
 1789    if (ret != 0) {
 1790        return ret;
 1791    }
 1792#endif
 1793
 1794#ifdef WOLFSSL_NO_MALLOC
 1795    curve = &ecc_curve_spec_cache[x];
 1796#else
 1797    /* make sure cache has been allocated */
 1798    if (ecc_curve_spec_cache[x] == NULL
 1799    #ifdef WOLFSSL_CUSTOM_CURVES
 1800        || dp->id == ECC_CURVE_CUSTOM
 1801    #endif
 1802    ) {
 1803        curve = (ecc_curve_spec*)XMALLOC(sizeof(ecc_curve_spec), NULL, DYNAMIC_TYPE_ECC);
 1804        if (curve == NULL) {
 1805        #if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
 1806            wc_UnLockMutex(&ecc_curve_cache_mutex);
 1807        #endif
 1808            return MEMORY_E;
 1809        }
 1810        XMEMSET(curve, 0, sizeof(ecc_curve_spec));
 1811
 1812        /* set curve pointer to cache */
 1813    #ifdef WOLFSSL_CUSTOM_CURVES
 1814        if (dp->id != ECC_CURVE_CUSTOM)
 1815    #endif
 1816        {
 1817            ecc_curve_spec_cache[x] = curve;
 1818        }
 1819    }
 1820    else {
 1821        curve = ecc_curve_spec_cache[x];
 1822    }
 1823#endif /* WOLFSSL_NO_MALLOC */
 1824
 1825    /* return new or cached curve */
 1826    *pCurve = curve;
 1827#else
 1828    curve = *pCurve;
 1829#endif /* ECC_CACHE_CURVE */
 1830
 1831    /* make sure the curve is initialized */
 1832    if (curve->dp != dp) {
 1833        curve->load_mask = 0;
 1834
 1835    #ifdef ECC_CACHE_CURVE
 1836        curve->prime = &curve->prime_lcl;
 1837        curve->Af = &curve->Af_lcl;
 1838        curve->Bf = &curve->Bf_lcl;
 1839        curve->order = &curve->order_lcl;
 1840        curve->Gx = &curve->Gx_lcl;
 1841        curve->Gy = &curve->Gy_lcl;
 1842    #endif
 1843    }
 1844    curve->dp = dp; /* set dp info */
 1845
 1846    /* determine items to load */
 1847    load_items = (byte)(((byte)~(word32)curve->load_mask) & load_mask);
 1848    curve->load_mask |= load_items;
 1849
 1850    /* load items */
 1851    if (load_items & ECC_CURVE_FIELD_PRIME)
 1852        ret += wc_ecc_curve_cache_load_item(curve, dp->prime, &curve->prime,
 1853            ECC_CURVE_FIELD_PRIME);
 1854    if (load_items & ECC_CURVE_FIELD_AF)
 1855        ret += wc_ecc_curve_cache_load_item(curve, dp->Af, &curve->Af,
 1856            ECC_CURVE_FIELD_AF);
 1857    if (load_items & ECC_CURVE_FIELD_BF)
 1858        ret += wc_ecc_curve_cache_load_item(curve, dp->Bf, &curve->Bf,
 1859            ECC_CURVE_FIELD_BF);
 1860    if (load_items & ECC_CURVE_FIELD_ORDER)
 1861        ret += wc_ecc_curve_cache_load_item(curve, dp->order, &curve->order,
 1862            ECC_CURVE_FIELD_ORDER);
 1863    if (load_items & ECC_CURVE_FIELD_GX)
 1864        ret += wc_ecc_curve_cache_load_item(curve, dp->Gx, &curve->Gx,
 1865            ECC_CURVE_FIELD_GX);
 1866    if (load_items & ECC_CURVE_FIELD_GY)
 1867        ret += wc_ecc_curve_cache_load_item(curve, dp->Gy, &curve->Gy,
 1868            ECC_CURVE_FIELD_GY);
 1869
 1870    /* check for error */
 1871    if (ret != 0) {
 1872        wc_ecc_curve_free(curve);
 1873        ret = MP_READ_E;
 1874    }
 1875
 1876#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED)
 1877    wc_UnLockMutex(&ecc_curve_cache_mutex);
 1878#endif
 1879
 1880    return ret;
 1881}
 1882
 1883#ifdef ECC_CACHE_CURVE
 1884int wc_ecc_curve_cache_init(void)
 1885{
 1886    int ret = 0;
 1887#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
 1888        !defined(WOLFSSL_MUTEX_INITIALIZER)
 1889    ret = wc_InitMutex(&ecc_curve_cache_mutex);
 1890#endif
 1891    return ret;
 1892}
 1893
 1894void wc_ecc_curve_cache_free(void)
 1895{
 1896    int x;
 1897    /* free all ECC curve caches */
 1898    for (x = 0; x < (int)ECC_SET_COUNT; x++) {
 1899    #ifdef WOLFSSL_NO_MALLOC
 1900        wc_ecc_curve_cache_free_spec(&ecc_curve_spec_cache[x]);
 1901        XMEMSET(&ecc_curve_spec_cache[x], 0, sizeof(ecc_curve_spec_cache[x]));
 1902    #else
 1903        if (ecc_curve_spec_cache[x]) {
 1904            wc_ecc_curve_cache_free_spec(ecc_curve_spec_cache[x]);
 1905            XFREE(ecc_curve_spec_cache[x], NULL, DYNAMIC_TYPE_ECC);
 1906            ecc_curve_spec_cache[x] = NULL;
 1907        }
 1908    #endif /* WOLFSSL_NO_MALLOC */
 1909    }
 1910
 1911#if defined(ECC_CACHE_CURVE) && !defined(SINGLE_THREADED) && \
 1912        !defined(WOLFSSL_MUTEX_INITIALIZER)
 1913    wc_FreeMutex(&ecc_curve_cache_mutex);
 1914#endif
 1915}
 1916#endif /* ECC_CACHE_CURVE */
 1917
 1918
 1919/* Retrieve the curve name for the ECC curve id.
 1920 *
 1921 * curve_id  The id of the curve.
 1922 * returns the name stored from the curve if available, otherwise NULL.
 1923 */
 1924const char* wc_ecc_get_name(int curve_id)
 1925{
 1926    int curve_idx = wc_ecc_get_curve_idx(curve_id);
 1927    if (curve_idx == ECC_CURVE_INVALID)
 1928        return NULL;
 1929    return ecc_sets[curve_idx].name;
 1930}
 1931
 1932int wc_ecc_set_curve(ecc_key* key, int keysize, int curve_id)
 1933{
 1934    if (key == NULL || (keysize <= 0 && curve_id < 0)) {
 1935        return BAD_FUNC_ARG;
 1936    }
 1937
 1938    if (keysize > ECC_MAXSIZE) {
 1939        return ECC_BAD_ARG_E;
 1940    }
 1941
 1942    /* handle custom case */
 1943    if (key->idx != ECC_CUSTOM_IDX) {
 1944        int x;
 1945
 1946        /* default values */
 1947        key->idx = 0;
 1948        key->dp = NULL;
 1949
 1950        /* find ecc_set based on curve_id or key size */
 1951        for (x = 0; ecc_sets[x].size != 0; x++) {
 1952            if (curve_id > ECC_CURVE_DEF) {
 1953                if (curve_id == ecc_sets[x].id)
 1954                  break;
 1955            }
 1956            else if (keysize <= ecc_sets[x].size) {
 1957                break;
 1958            }
 1959        }
 1960        if (ecc_sets[x].size == 0) {
 1961            WOLFSSL_MSG("ECC Curve not found");
 1962            return ECC_CURVE_OID_E;
 1963        }
 1964
 1965        key->idx = x;
 1966        key->dp  = &ecc_sets[x];
 1967    }
 1968
 1969    return 0;
 1970}
 1971
 1972
 1973#ifdef ALT_ECC_SIZE
 1974static void alt_fp_init(mp_int* a)
 1975{
 1976    a->size = FP_SIZE_ECC;
 1977    mp_zero(a);
 1978}
 1979#endif /* ALT_ECC_SIZE */
 1980
 1981
 1982#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
 1983    !defined(WOLFSSL_CRYPTOCELL) && \
 1984    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
 1985      defined(WOLFSSL_IMXRT1170_CAAM))
 1986
 1987#if !defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_PUBLIC_ECC_ADD_DBL)
 1988static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
 1989                                     mp_int* modulus, mp_digit mp);
 1990
 1991/**
 1992   Add two ECC points
 1993   P        The point to add
 1994   Q        The point to add
 1995   R        [out] The destination of the double
 1996   a        ECC curve parameter a
 1997   modulus  The modulus of the field the ECC curve is in
 1998   mp       The "b" value from montgomery_setup()
 1999   return   MP_OKAY on success
 2000*/
 2001static int _ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
 2002                                     mp_int* a, mp_int* modulus, mp_digit mp)
 2003{
 2004#if !defined(WOLFSSL_SP_MATH)
 2005   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2006   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2007#ifdef ALT_ECC_SIZE
 2008   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2009   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2010   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2011#endif
 2012   mp_int  *x, *y, *z;
 2013   int     err;
 2014
 2015   /* if Q == R then swap P and Q, so we don't require a local x,y,z */
 2016   if (Q == R) {
 2017      ecc_point* tPt  = P;
 2018      P = Q;
 2019      Q = tPt;
 2020   }
 2021
 2022#ifdef WOLFSSL_SMALL_STACK
 2023#ifdef WOLFSSL_SMALL_STACK_CACHE
 2024   if (R->key != NULL) {
 2025       t1 = R->key->t1;
 2026       t2 = R->key->t2;
 2027#ifdef ALT_ECC_SIZE
 2028       rx = R->key->x;
 2029       ry = R->key->y;
 2030       rz = R->key->z;
 2031#endif
 2032   }
 2033   else
 2034#endif /* WOLFSSL_SMALL_STACK_CACHE */
 2035#endif /* WOLFSSL_SMALL_STACK */
 2036   {
 2037      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2038      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2039   #ifdef MP_INT_SIZE_CHECK_NULL
 2040      if (t1 == NULL || t2 == NULL) {
 2041         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2042         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2043         return MEMORY_E;
 2044      }
 2045   #endif
 2046#ifdef ALT_ECC_SIZE
 2047      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2048      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2049      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2050   #ifdef MP_INT_SIZE_CHECK_NULL
 2051      if (rx == NULL || ry == NULL || rz == NULL) {
 2052         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2053         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2054         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2055         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2056         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2057         return MEMORY_E;
 2058      }
 2059   #endif
 2060#endif
 2061   }
 2062
 2063   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
 2064   if (err == MP_OKAY) {
 2065      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
 2066   }
 2067   if (err != MP_OKAY) {
 2068#ifdef WOLFSSL_SMALL_STACK
 2069   #ifdef WOLFSSL_SMALL_STACK_CACHE
 2070      if (R->key == NULL)
 2071   #endif
 2072#endif
 2073      {
 2074      #ifdef ALT_ECC_SIZE
 2075         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2076         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2077         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2078      #endif
 2079         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2080         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2081      }
 2082      return err;
 2083   }
 2084
 2085   /* should we dbl instead? */
 2086   if (err == MP_OKAY) {
 2087#ifdef ECC_TIMING_RESISTANT
 2088      err = mp_submod_ct(modulus, Q->y, modulus, t1);
 2089#else
 2090      err = mp_sub(modulus, Q->y, t1);
 2091#endif
 2092   }
 2093   if (err == MP_OKAY) {
 2094      if ( (mp_cmp(P->x, Q->x) == MP_EQ) &&
 2095           (mp_get_digit_count(Q->z) && mp_cmp(P->z, Q->z) == MP_EQ) &&
 2096           (mp_cmp(P->y, Q->y) == MP_EQ || mp_cmp(P->y, t1) == MP_EQ)) {
 2097          mp_clear(t1);
 2098          mp_clear(t2);
 2099   #ifdef WOLFSSL_SMALL_STACK
 2100      #ifdef WOLFSSL_SMALL_STACK_CACHE
 2101         if (R->key == NULL)
 2102      #endif
 2103   #endif
 2104         {
 2105         #ifdef ALT_ECC_SIZE
 2106            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2107            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2108            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2109         #endif
 2110            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2111            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2112         }
 2113         return _ecc_projective_dbl_point(P, R, a, modulus, mp);
 2114      }
 2115   }
 2116
 2117   if (err != MP_OKAY) {
 2118      goto done;
 2119   }
 2120
 2121/* If use ALT_ECC_SIZE we need to use local stack variable since
 2122   ecc_point x,y,z is reduced size */
 2123#ifdef ALT_ECC_SIZE
 2124   /* Use local stack variable */
 2125   x = rx;
 2126   y = ry;
 2127   z = rz;
 2128
 2129   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
 2130   if (err == MP_OKAY) {
 2131      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
 2132   }
 2133   if (err == MP_OKAY) {
 2134      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
 2135   }
 2136   if (err != MP_OKAY) {
 2137      goto done;
 2138   }
 2139#else
 2140   /* Use destination directly */
 2141   x = R->x;
 2142   y = R->y;
 2143   z = R->z;
 2144#endif
 2145
 2146   if (err == MP_OKAY)
 2147       err = mp_copy(P->x, x);
 2148   if (err == MP_OKAY)
 2149       err = mp_copy(P->y, y);
 2150   if (err == MP_OKAY)
 2151       err = mp_copy(P->z, z);
 2152
 2153   /* if Z is one then these are no-operations */
 2154   if (err == MP_OKAY) {
 2155       if (!mp_iszero(Q->z)) {
 2156           /* T1 = Z' * Z' */
 2157           err = mp_sqr(Q->z, t1);
 2158           if (err == MP_OKAY)
 2159               err = mp_montgomery_reduce(t1, modulus, mp);
 2160
 2161           /* X = X * T1 */
 2162           if (err == MP_OKAY)
 2163               err = mp_mul(t1, x, x);
 2164           if (err == MP_OKAY)
 2165               err = mp_montgomery_reduce(x, modulus, mp);
 2166
 2167           /* T1 = Z' * T1 */
 2168           if (err == MP_OKAY)
 2169               err = mp_mul(Q->z, t1, t1);
 2170           if (err == MP_OKAY)
 2171               err = mp_montgomery_reduce(t1, modulus, mp);
 2172
 2173           /* Y = Y * T1 */
 2174           if (err == MP_OKAY)
 2175               err = mp_mul(t1, y, y);
 2176           if (err == MP_OKAY)
 2177               err = mp_montgomery_reduce(y, modulus, mp);
 2178       }
 2179   }
 2180
 2181   /* T1 = Z*Z */
 2182   if (err == MP_OKAY)
 2183       err = mp_sqr(z, t1);
 2184   if (err == MP_OKAY)
 2185       err = mp_montgomery_reduce(t1, modulus, mp);
 2186
 2187   /* T2 = X' * T1 */
 2188   if (err == MP_OKAY)
 2189       err = mp_mul(Q->x, t1, t2);
 2190   if (err == MP_OKAY)
 2191       err = mp_montgomery_reduce(t2, modulus, mp);
 2192
 2193   /* T1 = Z * T1 */
 2194   if (err == MP_OKAY)
 2195       err = mp_mul(z, t1, t1);
 2196   if (err == MP_OKAY)
 2197       err = mp_montgomery_reduce(t1, modulus, mp);
 2198
 2199   /* T1 = Y' * T1 */
 2200   if (err == MP_OKAY)
 2201       err = mp_mul(Q->y, t1, t1);
 2202   if (err == MP_OKAY)
 2203       err = mp_montgomery_reduce(t1, modulus, mp);
 2204
 2205   /* Y = Y - T1 */
 2206   if (err == MP_OKAY)
 2207       err = mp_submod_ct(y, t1, modulus, y);
 2208   /* T1 = 2T1 */
 2209   if (err == MP_OKAY)
 2210       err = mp_addmod_ct(t1, t1, modulus, t1);
 2211   /* T1 = Y + T1 */
 2212   if (err == MP_OKAY)
 2213       err = mp_addmod_ct(t1, y, modulus, t1);
 2214   /* X = X - T2 */
 2215   if (err == MP_OKAY)
 2216       err = mp_submod_ct(x, t2, modulus, x);
 2217   /* T2 = 2T2 */
 2218   if (err == MP_OKAY)
 2219       err = mp_addmod_ct(t2, t2, modulus, t2);
 2220   /* T2 = X + T2 */
 2221   if (err == MP_OKAY)
 2222       err = mp_addmod_ct(t2, x, modulus, t2);
 2223
 2224   if (err == MP_OKAY) {
 2225       if (!mp_iszero(Q->z)) {
 2226           /* Z = Z * Z' */
 2227           err = mp_mul(z, Q->z, z);
 2228           if (err == MP_OKAY)
 2229               err = mp_montgomery_reduce(z, modulus, mp);
 2230       }
 2231   }
 2232
 2233   /* Z = Z * X */
 2234   if (err == MP_OKAY)
 2235       err = mp_mul(z, x, z);
 2236   if (err == MP_OKAY)
 2237       err = mp_montgomery_reduce(z, modulus, mp);
 2238
 2239   /* T1 = T1 * X  */
 2240   if (err == MP_OKAY)
 2241       err = mp_mul(t1, x, t1);
 2242   if (err == MP_OKAY)
 2243       err = mp_montgomery_reduce(t1, modulus, mp);
 2244
 2245   /* X = X * X */
 2246   if (err == MP_OKAY)
 2247       err = mp_sqr(x, x);
 2248   if (err == MP_OKAY)
 2249       err = mp_montgomery_reduce(x, modulus, mp);
 2250
 2251   /* T2 = T2 * x */
 2252   if (err == MP_OKAY)
 2253       err = mp_mul(t2, x, t2);
 2254   if (err == MP_OKAY)
 2255       err = mp_montgomery_reduce(t2, modulus, mp);
 2256
 2257   /* T1 = T1 * X  */
 2258   if (err == MP_OKAY)
 2259       err = mp_mul(t1, x, t1);
 2260   if (err == MP_OKAY)
 2261       err = mp_montgomery_reduce(t1, modulus, mp);
 2262
 2263   /* X = Y*Y */
 2264   if (err == MP_OKAY)
 2265       err = mp_sqr(y, x);
 2266   if (err == MP_OKAY)
 2267       err = mp_montgomery_reduce(x, modulus, mp);
 2268
 2269   /* X = X - T2 */
 2270   if (err == MP_OKAY)
 2271       err = mp_submod_ct(x, t2, modulus, x);
 2272   /* T2 = T2 - X */
 2273   if (err == MP_OKAY)
 2274       err = mp_submod_ct(t2, x, modulus, t2);
 2275   /* T2 = T2 - X */
 2276   if (err == MP_OKAY)
 2277       err = mp_submod_ct(t2, x, modulus, t2);
 2278   /* T2 = T2 * Y */
 2279   if (err == MP_OKAY)
 2280       err = mp_mul(t2, y, t2);
 2281   if (err == MP_OKAY)
 2282       err = mp_montgomery_reduce(t2, modulus, mp);
 2283
 2284   /* Y = T2 - T1 */
 2285   if (err == MP_OKAY)
 2286       err = mp_submod_ct(t2, t1, modulus, y);
 2287   /* Y = Y/2 */
 2288   if (err == MP_OKAY)
 2289       err = mp_div_2_mod_ct(y, modulus, y);
 2290
 2291#ifdef ALT_ECC_SIZE
 2292   if (err == MP_OKAY)
 2293       err = mp_copy(x, R->x);
 2294   if (err == MP_OKAY)
 2295       err = mp_copy(y, R->y);
 2296   if (err == MP_OKAY)
 2297       err = mp_copy(z, R->z);
 2298#endif
 2299
 2300done:
 2301
 2302   /* clean up */
 2303   mp_clear(t1);
 2304   mp_clear(t2);
 2305#ifdef WOLFSSL_SMALL_STACK
 2306#ifdef WOLFSSL_SMALL_STACK_CACHE
 2307   if (R->key == NULL)
 2308#endif
 2309#endif
 2310   {
 2311   #ifdef ALT_ECC_SIZE
 2312      FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2313      FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2314      FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2315   #endif
 2316      FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2317      FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2318   }
 2319
 2320   return err;
 2321#else
 2322    int modBits = mp_count_bits(modulus);
 2323
 2324    (void)a;
 2325    (void)mp;
 2326
 2327#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 2328    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
 2329       return sp_ecc_proj_add_point_sm2_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
 2330                                            R->x, R->y, R->z);
 2331    }
 2332#endif
 2333#ifndef WOLFSSL_SP_NO_256
 2334    if (modBits == 256) {
 2335        return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z,
 2336                                         R->x, R->y, R->z);
 2337    }
 2338#endif
 2339#ifdef WOLFSSL_SP_384
 2340    if (modBits == 384) {
 2341        return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z,
 2342                                         R->x, R->y, R->z);
 2343    }
 2344#endif
 2345#ifdef WOLFSSL_SP_521
 2346    if (modBits == 521) {
 2347        return sp_ecc_proj_add_point_521(P->x, P->y, P->z, Q->x, Q->y, Q->z,
 2348                                         R->x, R->y, R->z);
 2349    }
 2350#endif
 2351    return ECC_BAD_ARG_E;
 2352#endif
 2353}
 2354
 2355int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R,
 2356                             mp_int* a, mp_int* modulus, mp_digit mp)
 2357{
 2358    if (P == NULL || Q == NULL || R == NULL || modulus == NULL) {
 2359        return ECC_BAD_ARG_E;
 2360    }
 2361
 2362    if (mp_cmp(P->x, modulus) != MP_LT ||
 2363        mp_cmp(P->y, modulus) != MP_LT ||
 2364        mp_cmp(P->z, modulus) != MP_LT ||
 2365        mp_cmp(Q->x, modulus) != MP_LT ||
 2366        mp_cmp(Q->y, modulus) != MP_LT ||
 2367        mp_cmp(Q->z, modulus) != MP_LT) {
 2368        return ECC_OUT_OF_RANGE_E;
 2369    }
 2370
 2371    return _ecc_projective_add_point(P, Q, R, a, modulus, mp);
 2372}
 2373
 2374/* ### Point doubling in Jacobian coordinate system ###
 2375 *
 2376 * let us have a curve:                 y^2 = x^3 + a*x + b
 2377 * in Jacobian coordinates it becomes:  y^2 = x^3 + a*x*z^4 + b*z^6
 2378 *
 2379 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
 2380 * Xr = M^2 - 2*S
 2381 * Yr = M * (S - Xr) - 8*T
 2382 * Zr = 2 * Yp * Zp
 2383 *
 2384 * M = 3 * Xp^2 + a*Zp^4
 2385 * T = Yp^4
 2386 * S = 4 * Xp * Yp^2
 2387 *
 2388 * SPECIAL CASE: when a == 3 we can compute M as
 2389 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
 2390 */
 2391
 2392/**
 2393   Double an ECC point
 2394   P   The point to double
 2395   R   [out] The destination of the double
 2396   a   ECC curve parameter a
 2397   modulus  The modulus of the field the ECC curve is in
 2398   mp       The "b" value from montgomery_setup()
 2399   return   MP_OKAY on success
 2400*/
 2401static int _ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
 2402                                     mp_int* modulus, mp_digit mp)
 2403{
 2404#if !defined(WOLFSSL_SP_MATH)
 2405   DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2406   DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2407#ifdef ALT_ECC_SIZE
 2408   DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2409   DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2410   DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2411#endif
 2412   mp_int *x, *y, *z;
 2413   int    err;
 2414
 2415#ifdef WOLFSSL_SMALL_STACK
 2416#ifdef WOLFSSL_SMALL_STACK_CACHE
 2417   if (R->key != NULL) {
 2418       t1 = R->key->t1;
 2419       t2 = R->key->t2;
 2420   #ifdef ALT_ECC_SIZE
 2421       rx = R->key->x;
 2422       ry = R->key->y;
 2423       rz = R->key->z;
 2424   #endif
 2425   }
 2426   else
 2427#endif /* WOLFSSL_SMALL_STACK_CACHE */
 2428#endif
 2429   {
 2430      NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2431      NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2432   #ifdef MP_INT_SIZE_CHECK_NULL
 2433      if (t1 == NULL || t2 == NULL) {
 2434         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2435         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2436         return MEMORY_E;
 2437      }
 2438   #endif
 2439   #ifdef ALT_ECC_SIZE
 2440      NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2441      NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2442      NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2443   #ifdef MP_INT_SIZE_CHECK_NULL
 2444      if (rx == NULL || ry == NULL || rz == NULL) {
 2445          FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2446          FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2447          FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2448          FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2449          FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2450          return MEMORY_E;
 2451      }
 2452   #endif
 2453   #endif
 2454   }
 2455
 2456   err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
 2457   if (err == MP_OKAY) {
 2458      err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
 2459   }
 2460   if (err != MP_OKAY) {
 2461#ifdef WOLFSSL_SMALL_STACK
 2462   #ifdef WOLFSSL_SMALL_STACK_CACHE
 2463      if (R->key == NULL)
 2464   #endif
 2465#endif
 2466      {
 2467      #ifdef ALT_ECC_SIZE
 2468         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2469         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2470         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2471      #endif
 2472         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2473         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2474      }
 2475      return err;
 2476   }
 2477
 2478/* If use ALT_ECC_SIZE we need to use local stack variable since
 2479   ecc_point x,y,z is reduced size */
 2480#ifdef ALT_ECC_SIZE
 2481   /* Use local stack variable */
 2482   x = rx;
 2483   y = ry;
 2484   z = rz;
 2485
 2486   err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
 2487   if (err == MP_OKAY) {
 2488      err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
 2489   }
 2490   if (err == MP_OKAY) {
 2491      err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
 2492   }
 2493   if (err != MP_OKAY) {
 2494#ifdef WOLFSSL_SMALL_STACK
 2495   #ifdef WOLFSSL_SMALL_STACK_CACHE
 2496      if (R->key == NULL)
 2497   #endif
 2498#endif
 2499      {
 2500      #ifdef ALT_ECC_SIZE
 2501         FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2502         FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2503         FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2504      #endif
 2505         FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2506         FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2507      }
 2508      return err;
 2509   }
 2510#else
 2511   /* Use destination directly */
 2512   x = R->x;
 2513   y = R->y;
 2514   z = R->z;
 2515#endif
 2516
 2517   if (err == MP_OKAY)
 2518       err = mp_copy(P->x, x);
 2519   if (err == MP_OKAY)
 2520       err = mp_copy(P->y, y);
 2521   if (err == MP_OKAY)
 2522       err = mp_copy(P->z, z);
 2523
 2524   /* T1 = Z * Z */
 2525   if (err == MP_OKAY)
 2526       err = mp_sqr(z, t1);
 2527   if (err == MP_OKAY)
 2528       err = mp_montgomery_reduce(t1, modulus, mp);
 2529
 2530   /* Z = Y * Z */
 2531   if (err == MP_OKAY)
 2532       err = mp_mul(z, y, z);
 2533   if (err == MP_OKAY)
 2534       err = mp_montgomery_reduce(z, modulus, mp);
 2535
 2536   /* Z = 2Z */
 2537   if (err == MP_OKAY)
 2538       err = mp_addmod_ct(z, z, modulus, z);
 2539
 2540   /* Determine if curve "a" should be used in calc */
 2541#ifdef WOLFSSL_CUSTOM_CURVES
 2542   if (err == MP_OKAY) {
 2543      /* Use a and prime to determine if a == 3 */
 2544      err = mp_submod(modulus, a, modulus, t2);
 2545   }
 2546   if (err == MP_OKAY && mp_iszero((MP_INT_SIZE*)t2)) {
 2547      /* T2 = X * X */
 2548      err = mp_sqr(x, t2);
 2549      if (err == MP_OKAY)
 2550          err = mp_montgomery_reduce(t2, modulus, mp);
 2551      /* T1 = T2 + T1 */
 2552      if (err == MP_OKAY)
 2553          err = mp_addmod_ct(t2, t2, modulus, t1);
 2554      /* T1 = T2 + T1 */
 2555      if (err == MP_OKAY)
 2556          err = mp_addmod_ct(t1, t2, modulus, t1);
 2557   }
 2558   else if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
 2559      /* use "a" in calc */
 2560
 2561      /* T2 = T1 * T1 */
 2562      err = mp_sqr(t1, t2);
 2563      if (err == MP_OKAY)
 2564          err = mp_montgomery_reduce(t2, modulus, mp);
 2565      /* T1 = T2 * a */
 2566      if (err == MP_OKAY)
 2567          err = mp_mulmod(t2, a, modulus, t1);
 2568      /* T2 = X * X */
 2569      if (err == MP_OKAY)
 2570          err = mp_sqr(x, t2);
 2571      if (err == MP_OKAY)
 2572          err = mp_montgomery_reduce(t2, modulus, mp);
 2573      /* T1 = T2 + T1 */
 2574      if (err == MP_OKAY)
 2575          err = mp_addmod_ct(t1, t2, modulus, t1);
 2576      /* T1 = T2 + T1 */
 2577      if (err == MP_OKAY)
 2578          err = mp_addmod_ct(t1, t2, modulus, t1);
 2579      /* T1 = T2 + T1 */
 2580      if (err == MP_OKAY)
 2581          err = mp_addmod_ct(t1, t2, modulus, t1);
 2582   }
 2583   else
 2584#endif /* WOLFSSL_CUSTOM_CURVES */
 2585   {
 2586      /* assumes "a" == 3 */
 2587      (void)a;
 2588
 2589      /* T2 = X - T1 */
 2590      if (err == MP_OKAY)
 2591          err = mp_submod_ct(x, t1, modulus, t2);
 2592      /* T1 = X + T1 */
 2593      if (err == MP_OKAY)
 2594          err = mp_addmod_ct(t1, x, modulus, t1);
 2595      /* T2 = T1 * T2 */
 2596      if (err == MP_OKAY)
 2597          err = mp_mul(t1, t2, t2);
 2598      if (err == MP_OKAY)
 2599          err = mp_montgomery_reduce(t2, modulus, mp);
 2600
 2601      /* T1 = 2T2 */
 2602      if (err == MP_OKAY)
 2603          err = mp_addmod_ct(t2, t2, modulus, t1);
 2604      /* T1 = T1 + T2 */
 2605      if (err == MP_OKAY)
 2606          err = mp_addmod_ct(t1, t2, modulus, t1);
 2607   }
 2608
 2609   /* Y = 2Y */
 2610   if (err == MP_OKAY)
 2611       err = mp_addmod_ct(y, y, modulus, y);
 2612   /* Y = Y * Y */
 2613   if (err == MP_OKAY)
 2614       err = mp_sqr(y, y);
 2615   if (err == MP_OKAY)
 2616       err = mp_montgomery_reduce(y, modulus, mp);
 2617
 2618   /* T2 = Y * Y */
 2619   if (err == MP_OKAY)
 2620       err = mp_sqr(y, t2);
 2621   if (err == MP_OKAY)
 2622       err = mp_montgomery_reduce(t2, modulus, mp);
 2623
 2624   /* T2 = T2/2 */
 2625   if (err == MP_OKAY)
 2626       err = mp_div_2_mod_ct(t2, modulus, t2);
 2627
 2628   /* Y = Y * X */
 2629   if (err == MP_OKAY)
 2630       err = mp_mul(y, x, y);
 2631   if (err == MP_OKAY)
 2632       err = mp_montgomery_reduce(y, modulus, mp);
 2633
 2634   /* X = T1 * T1 */
 2635   if (err == MP_OKAY)
 2636       err = mp_sqr(t1, x);
 2637   if (err == MP_OKAY)
 2638       err = mp_montgomery_reduce(x, modulus, mp);
 2639
 2640   /* X = X - Y */
 2641   if (err == MP_OKAY)
 2642       err = mp_submod_ct(x, y, modulus, x);
 2643   /* X = X - Y */
 2644   if (err == MP_OKAY)
 2645       err = mp_submod_ct(x, y, modulus, x);
 2646
 2647   /* Y = Y - X */
 2648   if (err == MP_OKAY)
 2649       err = mp_submod_ct(y, x, modulus, y);
 2650   /* Y = Y * T1 */
 2651   if (err == MP_OKAY)
 2652       err = mp_mul(y, t1, y);
 2653   if (err == MP_OKAY)
 2654       err = mp_montgomery_reduce(y, modulus, mp);
 2655
 2656   /* Y = Y - T2 */
 2657   if (err == MP_OKAY)
 2658       err = mp_submod_ct(y, t2, modulus, y);
 2659
 2660#ifdef ALT_ECC_SIZE
 2661   if (err == MP_OKAY)
 2662       err = mp_copy(x, R->x);
 2663   if (err == MP_OKAY)
 2664       err = mp_copy(y, R->y);
 2665   if (err == MP_OKAY)
 2666       err = mp_copy(z, R->z);
 2667#endif
 2668
 2669   /* clean up */
 2670   mp_clear(t1);
 2671   mp_clear(t2);
 2672
 2673#ifdef WOLFSSL_SMALL_STACK
 2674#ifdef WOLFSSL_SMALL_STACK_CACHE
 2675   if (R->key == NULL)
 2676#endif
 2677#endif
 2678   {
 2679    #ifdef ALT_ECC_SIZE
 2680       FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2681       FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2682       FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2683    #endif
 2684       FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2685       FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2686    }
 2687
 2688   return err;
 2689#else
 2690    int modBits = mp_count_bits(modulus);
 2691
 2692    (void)a;
 2693    (void)mp;
 2694
 2695#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 2696    if ((modBits == 256) && (!mp_is_bit_set(modulus, 224))) {
 2697       return sp_ecc_proj_dbl_point_sm2_256(P->x, P->y, P->z, R->x, R->y, R->z);
 2698    }
 2699#endif
 2700#ifndef WOLFSSL_SP_NO_256
 2701    if (modBits == 256) {
 2702        return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z);
 2703    }
 2704#endif
 2705#ifdef WOLFSSL_SP_384
 2706    if (modBits == 384) {
 2707        return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z);
 2708    }
 2709#endif
 2710#ifdef WOLFSSL_SP_521
 2711    if (modBits == 521) {
 2712        return sp_ecc_proj_dbl_point_521(P->x, P->y, P->z, R->x, R->y, R->z);
 2713    }
 2714#endif
 2715    return ECC_BAD_ARG_E;
 2716#endif
 2717}
 2718
 2719int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a,
 2720                             mp_int* modulus, mp_digit mp)
 2721{
 2722    if (P == NULL || R == NULL || modulus == NULL)
 2723        return ECC_BAD_ARG_E;
 2724
 2725    if (mp_cmp(P->x, modulus) != MP_LT ||
 2726        mp_cmp(P->y, modulus) != MP_LT ||
 2727        mp_cmp(P->z, modulus) != MP_LT) {
 2728        return ECC_OUT_OF_RANGE_E;
 2729    }
 2730
 2731    return _ecc_projective_dbl_point(P, R, a, modulus, mp);
 2732}
 2733
 2734#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
 2735    !defined(WOLFSSL_CRYPTOCELL)
 2736
 2737
 2738/**
 2739  Map a projective Jacobian point back to affine space
 2740  P        [in/out] The point to map
 2741  modulus  The modulus of the field the ECC curve is in
 2742  mp       The "b" value from montgomery_setup()
 2743  ct       Operation should be constant time.
 2744  return   MP_OKAY on success
 2745*/
 2746int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
 2747{
 2748    int err = MP_OKAY;
 2749    (void)ct;
 2750
 2751    if (P == NULL || modulus == NULL){
 2752        return ECC_BAD_ARG_E;
 2753    }
 2754    {
 2755        #if !defined(WOLFSSL_SP_MATH)
 2756        DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2757        DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2758        #ifdef ALT_ECC_SIZE
 2759        DECL_MP_INT_SIZE_DYN(rx, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2760        DECL_MP_INT_SIZE_DYN(ry, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2761        DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 2762        #endif
 2763        mp_int *x, *y, *z;
 2764
 2765        /* special case for point at infinity */
 2766        if (mp_cmp_d(P->z, 0) == MP_EQ) {
 2767            err = mp_set(P->x, 0);
 2768            if (err == MP_OKAY)
 2769                err = mp_set(P->y, 0);
 2770            if (err == MP_OKAY)
 2771                err = mp_set(P->z, 1);
 2772            return err;
 2773        }
 2774
 2775        #ifdef WOLFSSL_SMALL_STACK
 2776        #ifdef WOLFSSL_SMALL_STACK_CACHE
 2777        if (P->key != NULL) {
 2778            t1 = P->key->t1;
 2779            t2 = P->key->t2;
 2780        #ifdef ALT_ECC_SIZE
 2781            rx = P->key->x;
 2782            ry = P->key->y;
 2783            rz = P->key->z;
 2784        #endif
 2785        }
 2786        else
 2787        #endif /* WOLFSSL_SMALL_STACK_CACHE */
 2788        #endif
 2789        {
 2790            NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2791            NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2792        #ifdef MP_INT_SIZE_CHECK_NULL
 2793            if (t1 == NULL || t2 == NULL) {
 2794                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2795                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2796                return MEMORY_E;
 2797            }
 2798        #endif
 2799        #ifdef ALT_ECC_SIZE
 2800            NEW_MP_INT_SIZE(rx, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2801            NEW_MP_INT_SIZE(ry, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2802            NEW_MP_INT_SIZE(rz, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 2803        #ifdef MP_INT_SIZE_CHECK_NULL
 2804            if (rx == NULL || ry == NULL || rz == NULL) {
 2805                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2806                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2807                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2808                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2809                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2810                return MEMORY_E;
 2811            }
 2812        #endif
 2813        #endif
 2814        }
 2815
 2816        err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
 2817        if (err == MP_OKAY) {
 2818            err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
 2819        }
 2820        if (err != MP_OKAY) {
 2821        #ifdef WOLFSSL_SMALL_STACK
 2822        #ifdef WOLFSSL_SMALL_STACK_CACHE
 2823            if (P->key == NULL)
 2824        #endif
 2825        #endif
 2826            {
 2827            #ifdef ALT_ECC_SIZE
 2828                FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2829                FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2830                FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2831            #endif
 2832                FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2833                FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2834            }
 2835            return MEMORY_E;
 2836        }
 2837
 2838        #ifdef ALT_ECC_SIZE
 2839        /* Use local stack variable */
 2840        x = rx;
 2841        y = ry;
 2842        z = rz;
 2843
 2844        err = INIT_MP_INT_SIZE(x, mp_bitsused(modulus));
 2845        if (err == MP_OKAY) {
 2846            err = INIT_MP_INT_SIZE(y, mp_bitsused(modulus));
 2847        }
 2848        if (err == MP_OKAY) {
 2849            err = INIT_MP_INT_SIZE(z, mp_bitsused(modulus));
 2850        }
 2851        if (err != MP_OKAY) {
 2852            goto done;
 2853        }
 2854
 2855        if (err == MP_OKAY)
 2856            err = mp_copy(P->x, x);
 2857        if (err == MP_OKAY)
 2858            err = mp_copy(P->y, y);
 2859        if (err == MP_OKAY)
 2860            err = mp_copy(P->z, z);
 2861
 2862        if (err != MP_OKAY) {
 2863            goto done;
 2864        }
 2865        #else
 2866        /* Use destination directly */
 2867        x = P->x;
 2868        y = P->y;
 2869        z = P->z;
 2870        #endif
 2871
 2872        /* get 1/z */
 2873        if (err == MP_OKAY) {
 2874        #if defined(ECC_TIMING_RESISTANT) && (defined(USE_FAST_MATH) || \
 2875                        defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL))
 2876            if (ct) {
 2877                err = mp_invmod_mont_ct(z, modulus, t1, mp);
 2878                if (err == MP_OKAY)
 2879                    err = mp_montgomery_reduce(t1, modulus, mp);
 2880            }
 2881            else
 2882        #endif
 2883            {
 2884                /* first map z back to normal */
 2885                err = mp_montgomery_reduce(z, modulus, mp);
 2886                if (err == MP_OKAY)
 2887                    err = mp_invmod(z, modulus, t1);
 2888            }
 2889        }
 2890
 2891        /* get 1/z^2 and 1/z^3 */
 2892        if (err == MP_OKAY)
 2893            err = mp_sqr(t1, t2);
 2894        if (err == MP_OKAY)
 2895            err = mp_mod(t2, modulus, t2);
 2896        if (err == MP_OKAY)
 2897            err = mp_mul(t1, t2, t1);
 2898        if (err == MP_OKAY)
 2899            err = mp_mod(t1, modulus, t1);
 2900
 2901        /* multiply against x/y */
 2902        if (err == MP_OKAY)
 2903            err = mp_mul(x, t2, x);
 2904        if (err == MP_OKAY)
 2905            err = mp_montgomery_reduce(x, modulus, mp);
 2906        if (err == MP_OKAY)
 2907            err = mp_mul(y, t1, y);
 2908        if (err == MP_OKAY)
 2909            err = mp_montgomery_reduce(y, modulus, mp);
 2910
 2911        if (err == MP_OKAY)
 2912            err = mp_set(z, 1);
 2913
 2914        #ifdef ALT_ECC_SIZE
 2915        /* return result */
 2916        if (err == MP_OKAY)
 2917            err = mp_copy(x, P->x);
 2918        if (err == MP_OKAY)
 2919            err = mp_copy(y, P->y);
 2920        if (err == MP_OKAY)
 2921            err = mp_copy(z, P->z);
 2922
 2923        done:
 2924        #endif
 2925
 2926        /* clean up */
 2927        mp_clear(t1);
 2928        mp_clear(t2);
 2929
 2930        #ifdef WOLFSSL_SMALL_STACK
 2931        #ifdef WOLFSSL_SMALL_STACK_CACHE
 2932        if (P->key == NULL)
 2933        #endif
 2934        #endif
 2935        {
 2936        #ifdef ALT_ECC_SIZE
 2937            FREE_MP_INT_SIZE(rz, NULL, DYNAMIC_TYPE_ECC);
 2938            FREE_MP_INT_SIZE(ry, NULL, DYNAMIC_TYPE_ECC);
 2939            FREE_MP_INT_SIZE(rx, NULL, DYNAMIC_TYPE_ECC);
 2940        #endif
 2941            FREE_MP_INT_SIZE(t2, NULL, DYNAMIC_TYPE_ECC);
 2942            FREE_MP_INT_SIZE(t1, NULL, DYNAMIC_TYPE_ECC);
 2943        }
 2944
 2945        return err;
 2946        /* end !defined(WOLFSSL_SP_MATH) */
 2947
 2948        #else
 2949        /* begin defined(WOLFSSL_SP_MATH) */
 2950        if (P == NULL || modulus == NULL)
 2951            return ECC_BAD_ARG_E;
 2952
 2953        (void)mp;
 2954        (void)ct;
 2955
 2956        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 2957        if ((mp_count_bits(modulus) == 256) &&
 2958            (!mp_is_bit_set(modulus, 224))) {
 2959            err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
 2960        }
 2961        #elif !defined(WOLFSSL_SP_NO_256)
 2962        if (mp_count_bits(modulus) == 256) {
 2963            err = sp_ecc_map_256(P->x, P->y, P->z);
 2964        }
 2965        #elif defined(WOLFSSL_SP_384)
 2966        if (mp_count_bits(modulus) == 384) {
 2967            err = sp_ecc_map_384(P->x, P->y, P->z);
 2968        }
 2969        #elif defined(WOLFSSL_SP_521)
 2970        if (mp_count_bits(modulus) == 521) {
 2971            err = sp_ecc_map_521(P->x, P->y, P->z);
 2972        }
 2973        #else
 2974        err = ECC_BAD_ARG_E;
 2975        #endif
 2976
 2977        WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err);
 2978    return err;
 2979#endif /* WOLFSSL_SP_MATH */
 2980    }
 2981}
 2982#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
 2983
 2984int ecc_map(ecc_point* P, mp_int* modulus, mp_digit mp)
 2985{
 2986    return ecc_map_ex(P, modulus, mp, 0);
 2987}
 2988#endif /* !WOLFSSL_SP_MATH || WOLFSSL_PUBLIC_ECC_ADD_DBL */
 2989
 2990#if !defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_STM32_PKA) && \
 2991    !defined(WOLFSSL_CRYPTOCELL)
 2992#if !defined(WOLFSSL_SP_MATH)
 2993
 2994#ifndef ECC_TIMING_RESISTANT
 2995
 2996/* size of sliding window, don't change this! */
 2997#define WINSIZE  4
 2998#define M_POINTS 8
 2999
 3000static int ecc_mulmod(const mp_int* k, ecc_point* tG, ecc_point* R,
 3001    ecc_point** M, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
 3002{
 3003   int      err = MP_OKAY;
 3004   int      i;
 3005   int      first = 1, bitbuf = 0, bitcpy = 0, j;
 3006   int      bitcnt = 0, mode = 0, digidx = 0;
 3007   mp_digit buf;
 3008   int      infinity;
 3009
 3010   (void)rng;
 3011
 3012   /* calc the M tab, which holds kG for k==8..15 */
 3013   /* M[0] == 8G */
 3014   if (err == MP_OKAY)
 3015       err = ecc_projective_dbl_point_safe(tG, M[0], a, modulus, mp);
 3016   if (err == MP_OKAY)
 3017       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
 3018   if (err == MP_OKAY)
 3019       err = ecc_projective_dbl_point_safe(M[0], M[0], a, modulus, mp);
 3020
 3021   /* now find (8+k)G for k=1..7 */
 3022   if (err == MP_OKAY)
 3023       for (j = 9; j < 16; j++) {
 3024           err = ecc_projective_add_point_safe(M[j-9], tG, M[j-M_POINTS], a,
 3025                                                        modulus, mp, &infinity);
 3026           if (err != MP_OKAY) break;
 3027       }
 3028
 3029   /* setup sliding window */
 3030   if (err == MP_OKAY) {
 3031       mode   = 0;
 3032       bitcnt = 1;
 3033       buf    = 0;
 3034       digidx = mp_get_digit_count(k) - 1;
 3035       bitcpy = bitbuf = 0;
 3036       first  = 1;
 3037
 3038       /* perform ops */
 3039       for (;;) {
 3040           /* grab next digit as required */
 3041           if (--bitcnt == 0) {
 3042               if (digidx == -1) {
 3043                   break;
 3044               }
 3045               buf    = mp_get_digit(k, digidx);
 3046               bitcnt = (int) DIGIT_BIT;
 3047               --digidx;
 3048           }
 3049
 3050           /* grab the next msb from the ltiplicand */
 3051           i = (int)(buf >> (DIGIT_BIT - 1)) & 1;
 3052           buf <<= 1;
 3053
 3054           /* skip leading zero bits */
 3055           if (mode == 0 && i == 0)
 3056               continue;
 3057
 3058           /* if the bit is zero and mode == 1 then we double */
 3059           if (mode == 1 && i == 0) {
 3060               err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
 3061               if (err != MP_OKAY) break;
 3062               continue;
 3063           }
 3064
 3065           /* else we add it to the window */
 3066           bitbuf |= (i << (WINSIZE - ++bitcpy));
 3067           mode = 2;
 3068
 3069           if (bitcpy == WINSIZE) {
 3070               /* if this is the first window we do a simple copy */
 3071               if (first == 1) {
 3072                   /* R = kG [k = first window] */
 3073                   err = mp_copy(M[bitbuf-M_POINTS]->x, R->x);
 3074                   if (err != MP_OKAY) break;
 3075
 3076                   err = mp_copy(M[bitbuf-M_POINTS]->y, R->y);
 3077                   if (err != MP_OKAY) break;
 3078
 3079                   err = mp_copy(M[bitbuf-M_POINTS]->z, R->z);
 3080                   first = 0;
 3081               } else {
 3082                   /* normal window */
 3083                   /* ok window is filled so double as required and add  */
 3084                   /* double first */
 3085                   for (j = 0; j < WINSIZE; j++) {
 3086                       err = ecc_projective_dbl_point_safe(R, R, a, modulus,
 3087                                                                            mp);
 3088                       if (err != MP_OKAY) break;
 3089                   }
 3090                   if (err != MP_OKAY) break;  /* out of first for(;;) */
 3091
 3092                   /* now add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
 3093                   err = ecc_projective_add_point_safe(R, M[bitbuf-M_POINTS], R,
 3094                                                     a, modulus, mp, &infinity);
 3095               }
 3096               if (err != MP_OKAY) break;
 3097               /* empty window and reset */
 3098               bitcpy = bitbuf = 0;
 3099               mode = 1;
 3100           }
 3101       }
 3102   }
 3103
 3104   /* if bits remain then double/add */
 3105   if (err == MP_OKAY) {
 3106       if (mode == 2 && bitcpy > 0) {
 3107           /* double then add */
 3108           for (j = 0; j < bitcpy; j++) {
 3109               /* only double if we have had at least one add first */
 3110               if (first == 0) {
 3111                   err = ecc_projective_dbl_point_safe(R, R, a, modulus, mp);
 3112                   if (err != MP_OKAY) break;
 3113               }
 3114
 3115               bitbuf <<= 1;
 3116               if ((bitbuf & (1 << WINSIZE)) != 0) {
 3117                   if (first == 1) {
 3118                       /* first add, so copy */
 3119                       err = mp_copy(tG->x, R->x);
 3120                       if (err != MP_OKAY) break;
 3121
 3122                       err = mp_copy(tG->y, R->y);
 3123                       if (err != MP_OKAY) break;
 3124
 3125                       err = mp_copy(tG->z, R->z);
 3126                       if (err != MP_OKAY) break;
 3127                       first = 0;
 3128                   } else {
 3129                       /* then add */
 3130                       err = ecc_projective_add_point_safe(R, tG, R, a, modulus,
 3131                                                                 mp, &infinity);
 3132                       if (err != MP_OKAY) break;
 3133                   }
 3134               }
 3135           }
 3136       }
 3137   }
 3138
 3139   #undef WINSIZE
 3140
 3141   return err;
 3142}
 3143
 3144#else
 3145
 3146static int wc_ecc_gen_z(WC_RNG* rng, int size, ecc_point* p, mp_int* modulus,
 3147    mp_digit mp, mp_int* tx, mp_int* ty, mp_int* mu)
 3148{
 3149    int err = MP_OKAY;
 3150
 3151    err = mp_montgomery_calc_normalization(mu, modulus);
 3152    /* Generate random value to multiply into p->z. */
 3153    if (err == MP_OKAY)
 3154        err = wc_ecc_gen_k(rng, size, ty, modulus);
 3155    /* Convert to montogmery form. */
 3156    if (err == MP_OKAY)
 3157        err = mp_mulmod(ty, mu, modulus, ty);
 3158    /* Multiply random value into p->z. */
 3159    if (err == MP_OKAY)
 3160        err = mp_mul(p->z, ty, p->z);
 3161    if (err == MP_OKAY)
 3162        err = mp_montgomery_reduce(p->z, modulus, mp);
 3163    /* Square random value for X (X' = X / Z^2). */
 3164    if (err == MP_OKAY)
 3165        err = mp_sqr(ty, tx);
 3166    if (err == MP_OKAY)
 3167        err = mp_montgomery_reduce(tx, modulus, mp);
 3168    /* Multiply square of random by random value for Y. */
 3169    if (err == MP_OKAY)
 3170        err = mp_mul(ty, tx, ty);
 3171    if (err == MP_OKAY)
 3172        err = mp_montgomery_reduce(ty, modulus, mp);
 3173    /* Multiply square into X. */
 3174    if (err == MP_OKAY)
 3175        err = mp_mul(p->x, tx, p->x);
 3176    if (err == MP_OKAY)
 3177        err = mp_montgomery_reduce(p->x, modulus, mp);
 3178    /* Multiply cube into Y (Y' = Y / Z^3). */
 3179    if (err == MP_OKAY)
 3180        err = mp_mul(p->y, ty, p->y);
 3181    if (err == MP_OKAY)
 3182        err = mp_montgomery_reduce(p->y, modulus, mp);
 3183
 3184    return err;
 3185}
 3186
 3187#ifndef WC_PROTECT_ENCRYPTED_MEM
 3188#define M_POINTS 3
 3189
 3190/* Joye double-add ladder.
 3191 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
 3192 * by Marc Joye (2007)
 3193 *
 3194 * Algorithm 1':
 3195 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
 3196 *   Output: Q = kP
 3197 *   1: R[0] = P; R[1] = P
 3198 *   2: for j = 1 to t-1 do
 3199 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
 3200 *   4: end for
 3201 *   5: b = k[0]; R[b] = R[b] - P
 3202 *   6: return R[0]
 3203 *
 3204 * Assumes: k < order.
 3205 */
 3206static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
 3207    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
 3208{
 3209    int      err = MP_OKAY;
 3210    int      bytes = (mp_count_bits(modulus) + 7) >> 3;
 3211    int      i;
 3212    int      j = 1;
 3213    int      cnt = DIGIT_BIT;
 3214    int      t = 0;
 3215    mp_digit b;
 3216    mp_digit v = 0;
 3217    mp_int*  kt = R[2]->x;
 3218#ifndef WC_NO_CACHE_RESISTANT
 3219    /* First bit always 1 (fix at end) and swap equals first bit */
 3220    int      swap = 1;
 3221    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
 3222#endif
 3223    int      infinity;
 3224
 3225#ifndef WC_NO_CACHE_RESISTANT
 3226    WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_ECC, err=MEMORY_E);
 3227    if (err == MP_OKAY)
 3228        err = mp_init(tmp);
 3229#endif
 3230
 3231    /* Step 1: R[0] = P; R[1] = P */
 3232    /* R[0] = P */
 3233    if (err == MP_OKAY)
 3234        err = mp_copy(P->x, R[0]->x);
 3235    if (err == MP_OKAY)
 3236        err = mp_copy(P->y, R[0]->y);
 3237    if (err == MP_OKAY)
 3238        err = mp_copy(P->z, R[0]->z);
 3239
 3240    /* R[1] = P */
 3241    if (err == MP_OKAY)
 3242        err = mp_copy(P->x, R[1]->x);
 3243    if (err == MP_OKAY)
 3244        err = mp_copy(P->y, R[1]->y);
 3245    if (err == MP_OKAY)
 3246        err = mp_copy(P->z, R[1]->z);
 3247
 3248    /* Randomize z ordinates to obfuscate timing. */
 3249    if ((err == MP_OKAY) && (rng != NULL))
 3250        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[2]->x, R[2]->y, kt);
 3251    if ((err == MP_OKAY) && (rng != NULL))
 3252        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[2]->x, R[2]->y, kt);
 3253
 3254    if (err == MP_OKAY) {
 3255        /* Order could be one greater than the size of the modulus. */
 3256        t = mp_count_bits(modulus) + 1;
 3257        v = k->dp[0] >> 1;
 3258        if (cnt > t) {
 3259            cnt = t;
 3260        }
 3261        err = mp_copy(k, kt);
 3262    }
 3263    if (err == MP_OKAY) {
 3264        err = mp_grow(kt, (int)modulus->used + 1);
 3265    }
 3266    /* Step 2: for j = 1 to t-1 do */
 3267    for (i = 1; (err == MP_OKAY) && (i < t); i++) {
 3268        if (--cnt == 0) {
 3269            v = kt->dp[j++];
 3270            cnt = DIGIT_BIT;
 3271        }
 3272
 3273        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
 3274        b = v & 1;
 3275        v >>= 1;
 3276#ifdef WC_NO_CACHE_RESISTANT
 3277        err = ecc_projective_dbl_point_safe(R[b^1], R[b^1], a, modulus, mp);
 3278        if (err == MP_OKAY) {
 3279            err = ecc_projective_add_point_safe(R[b^1], R[b], R[b^1], a,
 3280                                                        modulus, mp, &infinity);
 3281        }
 3282#else
 3283        /* Swap R[0] and R[1] if other index is needed. */
 3284        swap ^= (int)b;
 3285        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
 3286            tmp);
 3287        if (err == MP_OKAY) {
 3288            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
 3289                tmp);
 3290        }
 3291        if (err == MP_OKAY) {
 3292            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
 3293                tmp);
 3294        }
 3295        swap = (int)b;
 3296
 3297        if (err == MP_OKAY)
 3298            err = ecc_projective_dbl_point_safe(R[0], R[0], a, modulus, mp);
 3299        if (err == MP_OKAY) {
 3300            err = ecc_projective_add_point_safe(R[0], R[1], R[0], a, modulus,
 3301                                                                 mp, &infinity);
 3302        }
 3303#endif /* WC_NO_CACHE_RESISTANT */
 3304    }
 3305    /* Step 4: end for */
 3306#ifndef WC_NO_CACHE_RESISTANT
 3307    /* Swap back if last bit is 0. */
 3308    swap ^= 1;
 3309    if (err == MP_OKAY) {
 3310        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, swap,
 3311            tmp);
 3312    }
 3313    if (err == MP_OKAY) {
 3314        err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used, swap,
 3315            tmp);
 3316    }
 3317    if (err == MP_OKAY) {
 3318        err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used, swap,
 3319            tmp);
 3320    }
 3321#endif
 3322
 3323    /* Step 5: b = k[0]; R[b] = R[b] - P */
 3324    /* R[2] = -P */
 3325    if (err == MP_OKAY)
 3326        err = mp_copy(P->x, R[2]->x);
 3327    if (err == MP_OKAY)
 3328        err = mp_sub(modulus, P->y, R[2]->y);
 3329    if (err == MP_OKAY)
 3330        err = mp_copy(P->z, R[2]->z);
 3331    /* Subtract point by adding negative. */
 3332    if (err == MP_OKAY) {
 3333        b = k->dp[0] & 1;
 3334#ifdef WC_NO_CACHE_RESISTANT
 3335        err = ecc_projective_add_point_safe(R[b], R[2], R[b], a, modulus, mp,
 3336                                                                     &infinity);
 3337#else
 3338        /* Swap R[0] and R[1], if necessary, to operate on the one we want. */
 3339        err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used, (int)b,
 3340            tmp);
 3341        if (err == MP_OKAY) {
 3342            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
 3343                (int)b, tmp);
 3344        }
 3345        if (err == MP_OKAY) {
 3346            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
 3347                (int)b, tmp);
 3348        }
 3349        if (err == MP_OKAY)
 3350            err = ecc_projective_add_point_safe(R[0], R[2], R[0], a, modulus,
 3351                                                                 mp, &infinity);
 3352        /* Swap back if necessary. */
 3353        if (err == MP_OKAY) {
 3354            err = mp_cond_swap_ct_ex(R[0]->x, R[1]->x, (int)modulus->used,
 3355                (int)b, tmp);
 3356        }
 3357        if (err == MP_OKAY) {
 3358            err = mp_cond_swap_ct_ex(R[0]->y, R[1]->y, (int)modulus->used,
 3359                (int)b, tmp);
 3360        }
 3361        if (err == MP_OKAY) {
 3362            err = mp_cond_swap_ct_ex(R[0]->z, R[1]->z, (int)modulus->used,
 3363                (int)b, tmp);
 3364        }
 3365#endif
 3366    }
 3367
 3368    /* Step 6: return R[0] */
 3369    if (err == MP_OKAY)
 3370        err = mp_copy(R[0]->x, Q->x);
 3371    if (err == MP_OKAY)
 3372        err = mp_copy(R[0]->y, Q->y);
 3373    if (err == MP_OKAY)
 3374        err = mp_copy(R[0]->z, Q->z);
 3375
 3376#if defined(WOLFSSL_SMALL_STACK) && !defined(WC_NO_CACHE_RESISTANT)
 3377    XFREE(tmp, NULL, DYNAMIC_TYPE_ECC);
 3378#endif
 3379
 3380    return err;
 3381}
 3382
 3383#else
 3384/* Number of points to allocate for use during scalar multiplication. */
 3385#define M_POINTS        5
 3386/* Last of the points is used as a temporary during calculations. */
 3387#define TMP_IDX         M_POINTS - 1
 3388
 3389static void mp_cond_swap_into_ct(mp_int* ra, mp_int* rb, mp_int* a, mp_int* b,
 3390    int digits, int m)
 3391{
 3392    int i;
 3393
 3394#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
 3395    /* Only using positive numbers in ECC operations. */
 3396    ra->sign = 0;
 3397    rb->sign = 0;
 3398#endif
 3399    /* Don't store 0 when mask is 0, it will be in a register. */
 3400    ra->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ a->used);
 3401    rb->used = (int)(((a->used ^ b->used) & ((mp_digit)0 - (m & 1))) ^ b->used);
 3402    for (i = 0; i < digits; i++) {
 3403        ra->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
 3404                    a->dp[i];
 3405        rb->dp[i] = ((a->dp[i] ^ b->dp[i]) & ((mp_digit)0 - (m & 1))) ^
 3406                    b->dp[i];
 3407    }
 3408}
 3409
 3410static void ecc_cond_swap_into_ct(ecc_point* ra, ecc_point* rb, ecc_point* a,
 3411    ecc_point* b, int digits, int m)
 3412{
 3413    /* Conditionally swap each ordinate. */
 3414    mp_cond_swap_into_ct(ra->x, rb->x, a->x, b->x, digits, m);
 3415    mp_cond_swap_into_ct(ra->y, rb->y, a->y, b->y, digits, m);
 3416    mp_cond_swap_into_ct(ra->z, rb->z, a->z, b->z, digits, m);
 3417}
 3418
 3419/* Joye double-add ladder.
 3420 * "Highly Regular Right-to-Left Algorithms for Scalar Multiplication"
 3421 * by Marc Joye (2007)
 3422 *
 3423 * Algorithm 1':
 3424 *   Input: P element of curve, k = (k[t-1],..., k[0]) base 2
 3425 *   Output: Q = kP
 3426 *   1: R[0] = P; R[1] = P
 3427 *   2: for j = 1 to t-1 do
 3428 *   3:   b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]]
 3429 *   4: end for
 3430 *   5: b = k[0]; R[b] = R[b] - P
 3431 *   6: return R[0]
 3432 *
 3433 * Assumes: k < order.
 3434 */
 3435static int ecc_mulmod(const mp_int* k, ecc_point* P, ecc_point* Q,
 3436    ecc_point** R, mp_int* a, mp_int* modulus, mp_digit mp, WC_RNG* rng)
 3437{
 3438    int          err = MP_OKAY;
 3439    int          bytes = (mp_count_bits(modulus) + 7) >> 3;
 3440    int          i;
 3441    int          j = 1;
 3442    int          cnt;
 3443    int          t = 0;
 3444    mp_int*      kt = R[TMP_IDX]->x;
 3445    /* First bit always 1 (fix at end) and swap equals first bit */
 3446    register int swap = 1;
 3447    /* Which pair of points has current value. R[0,1] or R[2,3] */
 3448    int          set = 0;
 3449    int          infinity;
 3450
 3451    /* Step 1: R[0] = P; R[1] = P */
 3452    /* R[0] = P */
 3453    if (err == MP_OKAY)
 3454        err = mp_copy(P->x, R[0]->x);
 3455    if (err == MP_OKAY)
 3456        err = mp_copy(P->y, R[0]->y);
 3457    if (err == MP_OKAY)
 3458        err = mp_copy(P->z, R[0]->z);
 3459
 3460    /* R[1] = P */
 3461    if (err == MP_OKAY)
 3462        err = mp_copy(P->x, R[1]->x);
 3463    if (err == MP_OKAY)
 3464        err = mp_copy(P->y, R[1]->y);
 3465    if (err == MP_OKAY)
 3466        err = mp_copy(P->z, R[1]->z);
 3467
 3468    /* Randomize z ordinates to obfuscate timing. */
 3469    if ((err == MP_OKAY) && (rng != NULL))
 3470        err = wc_ecc_gen_z(rng, bytes, R[0], modulus, mp, R[TMP_IDX]->x,
 3471                           R[TMP_IDX]->y, kt);
 3472    if ((err == MP_OKAY) && (rng != NULL))
 3473        err = wc_ecc_gen_z(rng, bytes, R[1], modulus, mp, R[TMP_IDX]->x,
 3474                           R[TMP_IDX]->y, kt);
 3475
 3476    if (err == MP_OKAY) {
 3477        /* Order could be one greater than the size of the modulus. */
 3478        t = mp_count_bits(modulus) + 1;
 3479        err = mp_copy(k, kt);
 3480    }
 3481    if (err == MP_OKAY) {
 3482        err = mp_grow(kt, modulus->used + 1);
 3483    }
 3484    /* Step 2: for j = 1 to t-1 do */
 3485    for (i = 1, j = 0, cnt = 0; (err == MP_OKAY) && (i < t); i++) {
 3486        if (++cnt == DIGIT_BIT) {
 3487            j++;
 3488            cnt = 0;
 3489        }
 3490
 3491        /* Step 3: b = 1 - k[j]; R[b] = 2*R[b] + R[k[j]] */
 3492        /* Swap R[0] and R[1] if other index is needed. */
 3493        /* Ensure 'swap' changes when shifted word is 0. */
 3494        swap += (kt->dp[j] >> cnt) + 2;
 3495        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
 3496                              R[set + 0], R[set + 1], modulus->used, swap);
 3497        /* Change to operate on set copied into. */
 3498        set = 2 - set;
 3499        /* Ensure 'swap' changes to a previously unseen value. */
 3500        swap += (kt->dp[j] >> cnt) + swap;
 3501
 3502        /* R[0] = 2*R[0] */
 3503        err = ecc_projective_dbl_point_safe(R[set + 0], R[set + 0], a, modulus,
 3504                                            mp);
 3505        if (err == MP_OKAY) {
 3506            /* R[0] = R[1] + R[0] */
 3507            err = ecc_projective_add_point_safe(R[set + 0], R[set + 1],
 3508                                         R[set + 0], a, modulus, mp, &infinity);
 3509        }
 3510        /*  R[1]->z * 2 - same point. */
 3511        mp_addmod_ct(R[set + 1]->z, R[set + 1]->z, modulus, R[set + 1]->z);
 3512        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
 3513        mp_addmod_ct(R[set + 1]->x, R[set + 1]->x, modulus, R[set + 1]->x);
 3514        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
 3515        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
 3516        mp_addmod_ct(R[set + 1]->y, R[set + 1]->y, modulus, R[set + 1]->y);
 3517    }
 3518    /* Step 4: end for */
 3519    /* Swap back if last bit is 0. */
 3520    /* Ensure 'swap' changes. */
 3521    swap += 1;
 3522    if (err == MP_OKAY) {
 3523        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
 3524                              R[set + 0], R[set + 1], modulus->used, swap);
 3525        set = 2 - set;
 3526    }
 3527
 3528    /* Step 5: b = k[0]; R[b] = R[b] - P */
 3529    /* R[TMP_IDX] = -P */
 3530    if (err == MP_OKAY)
 3531        err = mp_copy(P->x, R[TMP_IDX]->x);
 3532    if (err == MP_OKAY)
 3533        err = mp_sub(modulus, P->y, R[TMP_IDX]->y);
 3534    if (err == MP_OKAY)
 3535        err = mp_copy(P->z, R[TMP_IDX]->z);
 3536    /* Subtract point by adding negative. */
 3537    if (err == MP_OKAY) {
 3538        /* Swap R[0] and R[1], if necessary, to operate on the one we want.
 3539         * Last bit of k->dp[0] is being used to make decision to swap.
 3540         */
 3541        ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
 3542                              R[set + 0], R[set + 1], modulus->used,
 3543                              (int)k->dp[0]);
 3544        set = 2 - set;
 3545        err = ecc_projective_add_point_safe(R[set + 0], R[TMP_IDX], R[set + 0],
 3546                                            a, modulus, mp, &infinity);
 3547        /* Swap back if necessary. */
 3548        if (err == MP_OKAY) {
 3549            ecc_cond_swap_into_ct(R[(2 - set) + 0], R[(2 - set) + 1],
 3550                                  R[set + 0], R[set + 1], modulus->used,
 3551                                  (int)k->dp[0]);
 3552            set = 2 - set;
 3553        }
 3554    }
 3555
 3556    /* Step 6: return R[0] */
 3557    if (err == MP_OKAY)
 3558        err = mp_copy(R[set + 0]->x, Q->x);
 3559    if (err == MP_OKAY)
 3560        err = mp_copy(R[set + 0]->y, Q->y);
 3561    if (err == MP_OKAY)
 3562        err = mp_copy(R[set + 0]->z, Q->z);
 3563
 3564    return err;
 3565}
 3566
 3567#endif
 3568
 3569#endif
 3570
 3571/* Convert the point to montgomery form.
 3572 *
 3573 * @param  [in]   p        Point to convert.
 3574 * @param  [out]  r        Point in montgomery form.
 3575 * @param  [in]   modulus  Modulus of ordinates.
 3576 * @return  0 on success.
 3577 * @return  -ve on failure.
 3578 */
 3579static int ecc_point_to_mont(ecc_point* p, ecc_point* r, mp_int* modulus,
 3580                             void* heap)
 3581{
 3582   int err = MP_OKAY;
 3583   DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 3584
 3585   (void)heap;
 3586
 3587   NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
 3588#ifdef MP_INT_SIZE_CHECK_NULL
 3589   if (mu == NULL)
 3590       err = MEMORY_E;
 3591#endif
 3592   if (err == MP_OKAY)
 3593       err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
 3594   if (err == MP_OKAY) {
 3595       err = mp_montgomery_calc_normalization(mu, modulus);
 3596
 3597       if (err == MP_OKAY) {
 3598           if (mp_cmp_d(mu, 1) == MP_EQ) {
 3599               err = mp_copy(p->x, r->x);
 3600               if (err == MP_OKAY)
 3601                   err = mp_copy(p->y, r->y);
 3602               if (err == MP_OKAY)
 3603                   err = mp_copy(p->z, r->z);
 3604           }
 3605           else {
 3606               err = mp_mulmod(p->x, mu, modulus, r->x);
 3607               if (err == MP_OKAY)
 3608                   err = mp_mulmod(p->y, mu, modulus, r->y);
 3609               if (err == MP_OKAY)
 3610                   err = mp_mulmod(p->z, mu, modulus, r->z);
 3611           }
 3612       }
 3613
 3614       mp_clear(mu);
 3615   }
 3616
 3617   FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
 3618   return err;
 3619}
 3620
 3621#ifdef WOLFSSL_SMALL_STACK_CACHE
 3622static int ecc_key_tmp_init(ecc_key* key, void* heap)
 3623{
 3624   int err = MP_OKAY;
 3625
 3626   (void)heap;
 3627
 3628   if (key == NULL) {
 3629       return ECC_BAD_ARG_E;
 3630   }
 3631
 3632   XMEMSET(key, 0, sizeof(*key));
 3633
 3634#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
 3635   NEW_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
 3636   NEW_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
 3637#ifdef ALT_ECC_SIZE
 3638   NEW_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
 3639   NEW_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
 3640   NEW_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key), heap, DYNAMIC_TYPE_ECC);
 3641#endif
 3642   if (key->t1 == NULL || key->t2 == NULL
 3643#ifdef ALT_ECC_SIZE
 3644      || key->x == NULL || key->y == NULL || key->z == NULL
 3645#endif
 3646   ) {
 3647       err = MEMORY_E;
 3648   }
 3649   if (err == 0) {
 3650       err = INIT_MP_INT_SIZE(key->t1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 3651   }
 3652   if (err == 0) {
 3653       err = INIT_MP_INT_SIZE(key->t2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 3654   }
 3655#ifdef ALT_ECC_SIZE
 3656   if (err == 0) {
 3657       err = INIT_MP_INT_SIZE(key->x, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 3658   }
 3659   if (err == 0) {
 3660       err = INIT_MP_INT_SIZE(key->y, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 3661   }
 3662   if (err == 0) {
 3663       err = INIT_MP_INT_SIZE(key->z, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 3664   }
 3665#endif
 3666#else
 3667   key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 3668   key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 3669#ifdef ALT_ECC_SIZE
 3670   key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 3671   key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 3672   key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 3673#endif
 3674   if (key->t1 == NULL || key->t2 == NULL
 3675#ifdef ALT_ECC_SIZE
 3676      || key->x == NULL || key->y == NULL || key->z == NULL
 3677#endif
 3678   ) {
 3679       err = MEMORY_E;
 3680   }
 3681#endif
 3682
 3683   return err;
 3684}
 3685
 3686static void ecc_key_tmp_final(ecc_key* key, void* heap)
 3687{
 3688    (void)heap;
 3689
 3690#if defined(WOLFSSL_SP_MATH_ALL) && defined(WOLFSSL_SMALL_STACK)
 3691#ifdef ALT_ECC_SIZE
 3692   FREE_MP_INT_SIZE(key->z, heap, DYNAMIC_TYPE_ECC);
 3693   FREE_MP_INT_SIZE(key->y, heap, DYNAMIC_TYPE_ECC);
 3694   FREE_MP_INT_SIZE(key->x, heap, DYNAMIC_TYPE_ECC);
 3695#endif
 3696   FREE_MP_INT_SIZE(key->t2, heap, DYNAMIC_TYPE_ECC);
 3697   FREE_MP_INT_SIZE(key->t1, heap, DYNAMIC_TYPE_ECC);
 3698#else
 3699#ifdef ALT_ECC_SIZE
 3700   XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
 3701   XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
 3702   XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
 3703#endif
 3704   XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
 3705   XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
 3706#endif
 3707}
 3708#endif /* WOLFSSL_SMALL_STACK_CACHE */
 3709#endif /* !WOLFSSL_SP_MATH */
 3710
 3711#if !defined(WOLFSSL_SP_MATH) || !defined(FP_ECC)
 3712/**
 3713   Perform a point multiplication
 3714   k    The scalar to multiply by
 3715   G    The base point
 3716   R    [out] Destination for kG
 3717   a    ECC curve parameter a
 3718   modulus  The modulus of the field the ECC curve is in
 3719   map      Boolean whether to map back to affine or not
 3720                (1==map, 0 == leave in projective)
 3721   return MP_OKAY on success
 3722*/
 3723#ifdef FP_ECC
 3724static int normal_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R,
 3725                             mp_int* a, mp_int* modulus, WC_RNG* rng, int map,
 3726                             void* heap)
 3727#else
 3728int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
 3729                     mp_int* modulus, int map, void* heap)
 3730#endif
 3731#if !defined(WOLFSSL_SP_MATH)
 3732{
 3733   ecc_point     *tG, *M[M_POINTS];
 3734#ifdef WOLFSSL_NO_MALLOC
 3735   ecc_point     lcl_tG, lcl_M[M_POINTS];
 3736#endif
 3737   int           i, err;
 3738#ifdef WOLFSSL_SMALL_STACK_CACHE
 3739   ecc_key       *key = NULL;
 3740#endif
 3741   mp_digit      mp;
 3742
 3743   /* init variables */
 3744   tG = NULL;
 3745   XMEMSET(M, 0, sizeof(M));
 3746
 3747   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
 3748       err = ECC_BAD_ARG_E;
 3749       goto exit;
 3750   }
 3751
 3752   /* k can't have more bits than modulus count plus 1 */
 3753   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
 3754       err = ECC_OUT_OF_RANGE_E;
 3755       goto exit;
 3756   }
 3757
 3758#ifdef WOLFSSL_SMALL_STACK_CACHE
 3759   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
 3760   if (key == NULL) {
 3761       err = MP_MEM;
 3762       goto exit;
 3763   }
 3764   err = ecc_key_tmp_init(key, heap);
 3765   if (err != MP_OKAY)
 3766      goto exit;
 3767   R->key = key;
 3768#endif /* WOLFSSL_SMALL_STACK_CACHE */
 3769
 3770  /* alloc ram for window temps */
 3771  for (i = 0; i < M_POINTS; i++) {
 3772  #ifdef WOLFSSL_NO_MALLOC
 3773      M[i] = &lcl_M[i];
 3774  #endif
 3775      err = wc_ecc_new_point_ex(&M[i], heap);
 3776      if (err != MP_OKAY) {
 3777         goto exit;
 3778      }
 3779#ifdef WOLFSSL_SMALL_STACK_CACHE
 3780      M[i]->key = key;
 3781#endif
 3782  }
 3783
 3784   /* make a copy of G in case R==G */
 3785#ifdef WOLFSSL_NO_MALLOC
 3786   tG = &lcl_tG;
 3787#endif
 3788   err = wc_ecc_new_point_ex(&tG, heap);
 3789   if (err != MP_OKAY) {
 3790       goto exit;
 3791   }
 3792   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
 3793       goto exit;
 3794   }
 3795
 3796   /* init montgomery reduction */
 3797   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
 3798       goto exit;
 3799   }
 3800
 3801#ifdef FP_ECC
 3802   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
 3803#else
 3804   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, NULL);
 3805#endif
 3806   /* map R back from projective space */
 3807   if (err == MP_OKAY && map)
 3808       err = ecc_map(R, modulus, mp);
 3809
 3810exit:
 3811
 3812   /* done */
 3813   wc_ecc_del_point_ex(tG, heap);
 3814   for (i = 0; i < M_POINTS; i++) {
 3815       wc_ecc_del_point_ex(M[i], heap);
 3816   }
 3817
 3818#ifdef WOLFSSL_SMALL_STACK_CACHE
 3819   if (key) {
 3820       if (R)
 3821           R->key = NULL;
 3822       ecc_key_tmp_final(key, heap);
 3823       XFREE(key, heap, DYNAMIC_TYPE_ECC);
 3824   }
 3825#endif /* WOLFSSL_SMALL_STACK_CACHE */
 3826
 3827   return err;
 3828}
 3829#else
 3830{
 3831   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
 3832       return ECC_BAD_ARG_E;
 3833   }
 3834
 3835   (void)a;
 3836
 3837   /* For supported curves the order is the same length in bits as the modulus.
 3838    * Can't have more than order bits for the scalar.
 3839    */
 3840   if (mp_count_bits(k) > mp_count_bits(modulus)) {
 3841       return ECC_OUT_OF_RANGE_E;
 3842   }
 3843   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
 3844       mp_count_bits(G->y) > mp_count_bits(modulus) ||
 3845       mp_count_bits(G->z) > mp_count_bits(modulus)) {
 3846       return IS_POINT_E;
 3847   }
 3848
 3849#ifdef WOLFSSL_HAVE_SP_ECC
 3850#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 3851   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
 3852       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
 3853   }
 3854#endif
 3855#ifndef WOLFSSL_SP_NO_256
 3856   if (mp_count_bits(modulus) == 256) {
 3857       return sp_ecc_mulmod_256(k, G, R, map, heap);
 3858   }
 3859#endif
 3860#ifdef WOLFSSL_SP_384
 3861   if (mp_count_bits(modulus) == 384) {
 3862       return sp_ecc_mulmod_384(k, G, R, map, heap);
 3863   }
 3864#endif
 3865#ifdef WOLFSSL_SP_521
 3866   if (mp_count_bits(modulus) == 521) {
 3867       return sp_ecc_mulmod_521(k, G, R, map, heap);
 3868   }
 3869#endif
 3870#else
 3871   (void)map;
 3872   (void)map;
 3873   (void)heap;
 3874#endif
 3875   return ECC_BAD_ARG_E;
 3876}
 3877#endif
 3878#endif /* !WOLFSSL_SP_MATH || !FP_ECC */
 3879
 3880#ifndef FP_ECC
 3881#if !defined(WOLFSSL_SP_MATH)
 3882#ifdef ECC_TIMING_RESISTANT
 3883static int ecc_check_order_minus_1(const mp_int* k, ecc_point* tG, ecc_point* R,
 3884   mp_int* modulus, mp_int* order)
 3885{
 3886    int err;
 3887    DECL_MP_INT_SIZE_DYN(t, mp_bitsused(order), MAX_ECC_BITS_USE);
 3888
 3889    NEW_MP_INT_SIZE(t, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
 3890#ifdef MP_INT_SIZE_CHECK_NULL
 3891    if (t == NULL) {
 3892        err = MEMORY_E;
 3893    }
 3894    else
 3895#endif
 3896    {
 3897        err = INIT_MP_INT_SIZE(t, mp_bitsused(modulus));
 3898    }
 3899    if (err == MP_OKAY) {
 3900        /* Check for k == order - 1. Result will be 0 point which is not correct
 3901         * Calculates order / 2 and adds order / 2 + 1 and gets infinity.
 3902         * (with constant time implementation)
 3903         */
 3904        err = mp_sub_d(order, 1, t);
 3905        if (err == MP_OKAY) {
 3906            int kIsMinusOne = (mp_cmp((const mp_int*)k, t) == MP_EQ);
 3907            err = mp_cond_copy(tG->x, kIsMinusOne, R->x);
 3908            if (err == MP_OKAY) {
 3909                err = mp_sub(modulus, tG->y, t);
 3910            }
 3911            if (err == MP_OKAY) {
 3912                err = mp_cond_copy(t, kIsMinusOne, R->y);
 3913            }
 3914            if (err == MP_OKAY) {
 3915                err = mp_cond_copy(tG->z, kIsMinusOne, R->z);
 3916            }
 3917        }
 3918
 3919        mp_free(t);
 3920    }
 3921
 3922    FREE_MP_INT_SIZE(t, NULL, DYNAMIC_TYPE_ECC);
 3923    return err;
 3924}
 3925#endif /* ECC_TIMING_RESISTANT */
 3926#endif
 3927
 3928/**
 3929   Perform a point multiplication
 3930   k    The scalar to multiply by
 3931   G    The base point
 3932   R    [out] Destination for kG
 3933   a    ECC curve parameter a
 3934   modulus  The modulus of the field the ECC curve is in
 3935   map      Boolean whether to map back to affine or not
 3936                (1==map, 0 == leave in projective)
 3937   return MP_OKAY on success
 3938*/
 3939int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point* G, ecc_point* R, mp_int* a,
 3940                      mp_int* modulus, mp_int* order, WC_RNG* rng, int map,
 3941                      void* heap)
 3942#if !defined(WOLFSSL_SP_MATH)
 3943{
 3944   ecc_point     *tG, *M[M_POINTS];
 3945#ifdef WOLFSSL_NO_MALLOC
 3946   ecc_point     lcl_tG, lcl_M[M_POINTS];
 3947#endif
 3948   int           i, err;
 3949#ifdef WOLFSSL_SMALL_STACK_CACHE
 3950   ecc_key       *key = NULL;
 3951#endif
 3952   mp_digit      mp;
 3953
 3954   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
 3955      return ECC_BAD_ARG_E;
 3956   }
 3957
 3958#ifdef HAVE_ECC_CDH
 3959   if (mp_count_bits(modulus) > mp_count_bits(order)) {
 3960      if (mp_count_bits(k) > mp_count_bits(modulus)) {
 3961          return ECC_OUT_OF_RANGE_E;
 3962      }
 3963   }
 3964   else
 3965#endif
 3966   /* k can't have more bits than order */
 3967   if (mp_count_bits(k) > mp_count_bits(order)) {
 3968      WOLFSSL_MSG("Private key length is greater than order in bits.");
 3969      return ECC_OUT_OF_RANGE_E;
 3970   }
 3971
 3972   /* init variables */
 3973   tG = NULL;
 3974   XMEMSET(M, 0, sizeof(M));
 3975
 3976#ifdef WOLFSSL_SMALL_STACK_CACHE
 3977   key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC);
 3978   if (key == NULL)
 3979       return MEMORY_E;
 3980   err = ecc_key_tmp_init(key, heap);
 3981   if (err != MP_OKAY)
 3982      goto exit;
 3983   R->key = key;
 3984#endif /* WOLFSSL_SMALL_STACK_CACHE */
 3985
 3986   /* alloc ram for window temps */
 3987   for (i = 0; i < M_POINTS; i++) {
 3988   #ifdef WOLFSSL_NO_MALLOC
 3989      M[i] = &lcl_M[i];
 3990   #endif
 3991      err = wc_ecc_new_point_ex(&M[i], heap);
 3992      if (err != MP_OKAY) {
 3993         goto exit;
 3994      }
 3995#ifdef WOLFSSL_SMALL_STACK_CACHE
 3996      M[i]->key = key;
 3997#endif
 3998  }
 3999
 4000   /* make a copy of G in case R==G */
 4001#ifdef WOLFSSL_NO_MALLOC
 4002   tG = &lcl_tG;
 4003#endif
 4004   err = wc_ecc_new_point_ex(&tG, heap);
 4005   if (err != MP_OKAY) {
 4006       goto exit;
 4007   }
 4008   if ((err = ecc_point_to_mont(G, tG, modulus, heap)) != MP_OKAY) {
 4009       goto exit;
 4010   }
 4011
 4012   /* init montgomery reduction */
 4013   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
 4014      goto exit;
 4015   }
 4016
 4017   err = ecc_mulmod(k, tG, R, M, a, modulus, mp, rng);
 4018#ifdef ECC_TIMING_RESISTANT
 4019   if (err == MP_OKAY) {
 4020       err = ecc_check_order_minus_1(k, tG, R, modulus, order);
 4021   }
 4022#else
 4023   (void)order;
 4024#endif
 4025   /* map R back from projective space */
 4026   if (err == MP_OKAY && map)
 4027      err = ecc_map(R, modulus, mp);
 4028
 4029exit:
 4030
 4031   /* done */
 4032   wc_ecc_del_point_ex(tG, heap);
 4033   for (i = 0; i < M_POINTS; i++) {
 4034      wc_ecc_del_point_ex(M[i], heap);
 4035   }
 4036#ifdef WOLFSSL_SMALL_STACK_CACHE
 4037   R->key = NULL;
 4038   ecc_key_tmp_final(key, heap);
 4039   XFREE(key, heap, DYNAMIC_TYPE_ECC);
 4040#endif /* WOLFSSL_SMALL_STACK_CACHE */
 4041
 4042   return err;
 4043}
 4044#else
 4045{
 4046   if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
 4047       return ECC_BAD_ARG_E;
 4048   }
 4049   if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
 4050       mp_count_bits(G->y) > mp_count_bits(modulus) ||
 4051       mp_count_bits(G->z) > mp_count_bits(modulus)) {
 4052       return IS_POINT_E;
 4053   }
 4054
 4055   (void)a;
 4056   (void)order;
 4057   (void)rng;
 4058
 4059#ifdef WOLFSSL_HAVE_SP_ECC
 4060#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 4061   if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
 4062       return sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
 4063   }
 4064#endif
 4065#ifndef WOLFSSL_SP_NO_256
 4066   if (mp_count_bits(modulus) == 256) {
 4067       return sp_ecc_mulmod_256(k, G, R, map, heap);
 4068   }
 4069#endif
 4070#ifdef WOLFSSL_SP_384
 4071   if (mp_count_bits(modulus) == 384) {
 4072       return sp_ecc_mulmod_384(k, G, R, map, heap);
 4073   }
 4074#endif
 4075#ifdef WOLFSSL_SP_521
 4076   if (mp_count_bits(modulus) == 521) {
 4077       return sp_ecc_mulmod_521(k, G, R, map, heap);
 4078   }
 4079#endif
 4080#else
 4081   (void)map;
 4082   (void)heap;
 4083#endif
 4084   return ECC_BAD_ARG_E;
 4085}
 4086#endif /* !WOLFSSL_SP_MATH */
 4087#endif /* !FP_ECC */
 4088
 4089#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
 4090
 4091/** ECC Fixed Point mulmod global
 4092    k        The multiplicand
 4093    G        Base point to multiply
 4094    R        [out] Destination of product
 4095    a        ECC curve parameter a
 4096    modulus  The modulus for the curve
 4097    map      [boolean] If non-zero maps the point back to affine coordinates,
 4098             otherwise it's left in jacobian-montgomery form
 4099    return MP_OKAY if successful
 4100*/
 4101int wc_ecc_mulmod(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
 4102                  mp_int* modulus, int map)
 4103{
 4104    if ((k != NULL) && (R != NULL) && (mp_iszero(k))) {
 4105        mp_zero(R->x);
 4106        mp_zero(R->y);
 4107        mp_set(R->z, 1);
 4108        return MP_OKAY;
 4109    }
 4110    return wc_ecc_mulmod_ex(k, G, R, a, modulus, map, NULL);
 4111}
 4112
 4113#endif
 4114
 4115/**
 4116 * Allocate a new ECC point (if one not provided)
 4117 * use a heap hint when creating new ecc_point
 4118 * @return 0 on success
 4119 * @return BAD_FUNC_ARG for invalid arguments
 4120 * @return MEMORY_E on failure to allocate memory
 4121*/
 4122static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
 4123{
 4124   int err = MP_OKAY;
 4125   ecc_point* p;
 4126
 4127   if (point == NULL) {
 4128       return BAD_FUNC_ARG;
 4129   }
 4130
 4131   p = *point;
 4132   if (p == NULL) {
 4133      p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
 4134   }
 4135   if (p == NULL) {
 4136      return MEMORY_E;
 4137   }
 4138   XMEMSET(p, 0, sizeof(ecc_point));
 4139
 4140   if (*point == NULL)
 4141       p->isAllocated = 1;
 4142
 4143#ifndef ALT_ECC_SIZE
 4144   err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
 4145   if (err != MP_OKAY) {
 4146      WOLFSSL_MSG("mp_init_multi failed.");
 4147      if (p->isAllocated)
 4148          XFREE(p, heap, DYNAMIC_TYPE_ECC);
 4149      p = NULL;
 4150   }
 4151#else
 4152   p->x = (mp_int*)&p->xyz[0];
 4153   p->y = (mp_int*)&p->xyz[1];
 4154   p->z = (mp_int*)&p->xyz[2];
 4155   alt_fp_init(p->x);
 4156   alt_fp_init(p->y);
 4157   alt_fp_init(p->z);
 4158#endif
 4159
 4160   *point = p;
 4161   (void)heap;
 4162   return err;
 4163} /* wc_ecc_new_point_ex */
 4164
 4165ecc_point* wc_ecc_new_point_h(void* heap)
 4166{
 4167    ecc_point* p = NULL;
 4168    (void)wc_ecc_new_point_ex(&p, heap);
 4169    return p;
 4170}
 4171
 4172ecc_point* wc_ecc_new_point(void)
 4173{
 4174   ecc_point* p = NULL;
 4175   (void)wc_ecc_new_point_ex(&p, NULL);
 4176   return p;
 4177}
 4178
 4179/** Free an ECC point from memory
 4180  p   The point to free
 4181*/
 4182static void wc_ecc_del_point_ex(ecc_point* p, void* heap)
 4183{
 4184   if (p != NULL) {
 4185      mp_clear(p->x);
 4186      mp_clear(p->y);
 4187      mp_clear(p->z);
 4188      if (p->isAllocated)
 4189          XFREE(p, heap, DYNAMIC_TYPE_ECC);
 4190   }
 4191   (void)heap;
 4192}
 4193void wc_ecc_del_point_h(ecc_point* p, void* heap)
 4194{
 4195   wc_ecc_del_point_ex(p, heap);
 4196}
 4197void wc_ecc_del_point(ecc_point* p)
 4198{
 4199    wc_ecc_del_point_ex(p, NULL);
 4200}
 4201
 4202void wc_ecc_forcezero_point(ecc_point* p)
 4203{
 4204    if (p != NULL) {
 4205        mp_forcezero(p->x);
 4206        mp_forcezero(p->y);
 4207        mp_forcezero(p->z);
 4208    }
 4209}
 4210
 4211
 4212/** Copy the value of a point to an other one
 4213  p    The point to copy
 4214  r    The created point
 4215*/
 4216int wc_ecc_copy_point(const ecc_point* p, ecc_point *r)
 4217{
 4218    int ret;
 4219
 4220    /* prevents null arguments */
 4221    if (p == NULL || r == NULL)
 4222        return ECC_BAD_ARG_E;
 4223
 4224    ret = mp_copy(p->x, r->x);
 4225    if (ret != MP_OKAY)
 4226        return ret;
 4227    ret = mp_copy(p->y, r->y);
 4228    if (ret != MP_OKAY)
 4229        return ret;
 4230    ret = mp_copy(p->z, r->z);
 4231    if (ret != MP_OKAY)
 4232        return ret;
 4233
 4234    return MP_OKAY;
 4235}
 4236
 4237/** Compare the value of a point with an other one
 4238 a    The point to compare
 4239 b    The other point to compare
 4240
 4241 return MP_EQ if equal, MP_LT/MP_GT if not, < 0 in case of error
 4242 */
 4243int wc_ecc_cmp_point(ecc_point* a, ecc_point *b)
 4244{
 4245    int ret;
 4246
 4247    /* prevents null arguments */
 4248    if (a == NULL || b == NULL)
 4249        return BAD_FUNC_ARG;
 4250
 4251    ret = mp_cmp(a->x, b->x);
 4252    if (ret != MP_EQ)
 4253        return ret;
 4254    ret = mp_cmp(a->y, b->y);
 4255    if (ret != MP_EQ)
 4256        return ret;
 4257    ret = mp_cmp(a->z, b->z);
 4258    if (ret != MP_EQ)
 4259        return ret;
 4260
 4261    return MP_EQ;
 4262}
 4263
 4264
 4265/** Returns whether an ECC idx is valid or not
 4266  n      The idx number to check
 4267  return 1 if valid, 0 if not
 4268*/
 4269int wc_ecc_is_valid_idx(int n)
 4270{
 4271   int x;
 4272
 4273   if (n >= (int)ECC_SET_COUNT)
 4274       return 0;
 4275
 4276   for (x = 0; ecc_sets[x].size != 0; x++)
 4277       ;
 4278   /* -1 is a valid index --- indicating that the domain params
 4279      were supplied by the user */
 4280   if ((n >= ECC_CUSTOM_IDX) && (n < x)) {
 4281      return 1;
 4282   }
 4283
 4284   return 0;
 4285}
 4286
 4287int wc_ecc_get_curve_idx(int curve_id)
 4288{
 4289    int curve_idx;
 4290    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
 4291        if (curve_id == ecc_sets[curve_idx].id)
 4292            break;
 4293    }
 4294    if (ecc_sets[curve_idx].size == 0) {
 4295        return ECC_CURVE_INVALID;
 4296    }
 4297    return curve_idx;
 4298}
 4299
 4300int wc_ecc_get_curve_id(int curve_idx)
 4301{
 4302    if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
 4303        return ecc_sets[curve_idx].id;
 4304    }
 4305    return ECC_CURVE_INVALID;
 4306}
 4307
 4308/* Returns the curve size that corresponds to a given ecc_curve_id identifier
 4309 *
 4310 * id      curve id, from ecc_curve_id enum in ecc.h
 4311 * return  curve size, from ecc_sets[] on success, negative on error
 4312 */
 4313int wc_ecc_get_curve_size_from_id(int curve_id)
 4314{
 4315    int curve_idx = wc_ecc_get_curve_idx(curve_id);
 4316    if (curve_idx == ECC_CURVE_INVALID)
 4317        return ECC_BAD_ARG_E;
 4318    return ecc_sets[curve_idx].size;
 4319}
 4320
 4321/* Returns the curve index that corresponds to a given curve name in
 4322 * ecc_sets[] of ecc.c
 4323 *
 4324 * name    curve name, from ecc_sets[].name in ecc.c
 4325 * return  curve index in ecc_sets[] on success, negative on error
 4326 */
 4327int wc_ecc_get_curve_idx_from_name(const char* curveName)
 4328{
 4329    int curve_idx;
 4330
 4331    if (curveName == NULL)
 4332        return BAD_FUNC_ARG;
 4333
 4334    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
 4335        if (
 4336        #ifndef WOLFSSL_ECC_CURVE_STATIC
 4337            ecc_sets[curve_idx].name &&
 4338        #endif
 4339                XSTRCASECMP(ecc_sets[curve_idx].name, curveName) == 0) {
 4340            break;
 4341        }
 4342    }
 4343    if (ecc_sets[curve_idx].size == 0) {
 4344        WOLFSSL_MSG("ecc_set curve name not found");
 4345        return ECC_CURVE_INVALID;
 4346    }
 4347    return curve_idx;
 4348}
 4349
 4350/* Returns the curve size that corresponds to a given curve name,
 4351 * as listed in ecc_sets[] of ecc.c.
 4352 *
 4353 * name    curve name, from ecc_sets[].name in ecc.c
 4354 * return  curve size, from ecc_sets[] on success, negative on error
 4355 */
 4356int wc_ecc_get_curve_size_from_name(const char* curveName)
 4357{
 4358    int curve_idx;
 4359
 4360    if (curveName == NULL)
 4361        return BAD_FUNC_ARG;
 4362
 4363    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
 4364    if (curve_idx < 0)
 4365        return curve_idx;
 4366
 4367    return ecc_sets[curve_idx].size;
 4368}
 4369
 4370/* Returns the curve id that corresponds to a given curve name,
 4371 * as listed in ecc_sets[] of ecc.c.
 4372 *
 4373 * name   curve name, from ecc_sets[].name in ecc.c
 4374 * return curve id, from ecc_sets[] on success, negative on error
 4375 */
 4376int wc_ecc_get_curve_id_from_name(const char* curveName)
 4377{
 4378    int curve_idx;
 4379
 4380    if (curveName == NULL)
 4381        return BAD_FUNC_ARG;
 4382
 4383    curve_idx = wc_ecc_get_curve_idx_from_name(curveName);
 4384    if (curve_idx < 0)
 4385        return curve_idx;
 4386
 4387    return ecc_sets[curve_idx].id;
 4388}
 4389
 4390/* Compares a curve parameter (hex, from ecc_sets[]) to given input
 4391 * parameter for equality.
 4392 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
 4393 * Returns MP_EQ on success, negative on error */
 4394static int wc_ecc_cmp_param(const char* curveParam,
 4395                            const byte* param, word32 paramSz, int encType)
 4396{
 4397    int err = MP_OKAY;
 4398#ifdef WOLFSSL_SMALL_STACK
 4399    mp_int* a = NULL;
 4400    mp_int* b = NULL;
 4401#else
 4402    mp_int  a[1], b[1];
 4403#endif
 4404
 4405    if (param == NULL || curveParam == NULL)
 4406        return BAD_FUNC_ARG;
 4407
 4408    if (encType == WC_TYPE_HEX_STR) {
 4409        if ((word32)XSTRLEN(curveParam) != paramSz)
 4410            return -1;
 4411        return (XSTRNCMP(curveParam, (const char*) param, paramSz) == 0)
 4412            ? 0 : -1;
 4413    }
 4414
 4415#ifdef WOLFSSL_SMALL_STACK
 4416    a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
 4417    if (a == NULL)
 4418        return MEMORY_E;
 4419    b = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
 4420    if (b == NULL) {
 4421        XFREE(a, NULL, DYNAMIC_TYPE_ECC);
 4422        return MEMORY_E;
 4423    }
 4424#endif
 4425
 4426    if ((err = mp_init_multi(a, b, NULL, NULL, NULL, NULL)) != MP_OKAY) {
 4427        WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
 4428        WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
 4429        return err;
 4430    }
 4431
 4432    if (err == MP_OKAY) {
 4433        err = mp_read_unsigned_bin(a, param, paramSz);
 4434    }
 4435    if (err == MP_OKAY)
 4436        err = mp_read_radix(b, curveParam, MP_RADIX_HEX);
 4437
 4438    if (err == MP_OKAY) {
 4439        if (mp_cmp(a, b) != MP_EQ) {
 4440            err = -1;
 4441        } else {
 4442            err = MP_EQ;
 4443        }
 4444    }
 4445
 4446    mp_clear(a);
 4447    mp_clear(b);
 4448    WC_FREE_VAR_EX(b, NULL, DYNAMIC_TYPE_ECC);
 4449    WC_FREE_VAR_EX(a, NULL, DYNAMIC_TYPE_ECC);
 4450
 4451    return err;
 4452}
 4453
 4454/* Returns the curve id in ecc_sets[] that corresponds to a given set of
 4455 * curve parameters.
 4456 *
 4457 * fieldSize  the field size in bits
 4458 * prime      prime of the finite field
 4459 * primeSz    size of prime in octets
 4460 * Af         first coefficient a of the curve
 4461 * AfSz       size of Af in octets
 4462 * Bf         second coefficient b of the curve
 4463 * BfSz       size of Bf in octets
 4464 * order      curve order
 4465 * orderSz    size of curve in octets
 4466 * Gx         affine x coordinate of base point
 4467 * GxSz       size of Gx in octets
 4468 * Gy         affine y coordinate of base point
 4469 * GySz       size of Gy in octets
 4470 * cofactor   curve cofactor
 4471 *
 4472 * return curve id, from ecc_sets[] on success, negative on error
 4473 */
 4474int wc_ecc_get_curve_id_from_params(int fieldSize,
 4475        const byte* prime, word32 primeSz, const byte* Af, word32 AfSz,
 4476        const byte* Bf, word32 BfSz, const byte* order, word32 orderSz,
 4477        const byte* Gx, word32 GxSz, const byte* Gy, word32 GySz, int cofactor)
 4478{
 4479    int idx;
 4480    int curveSz;
 4481
 4482    if (prime == NULL || Af == NULL || Bf == NULL || order == NULL ||
 4483        Gx == NULL || Gy == NULL)
 4484        return BAD_FUNC_ARG;
 4485
 4486    curveSz = (fieldSize + 1) >> 3;    /* round up */
 4487
 4488    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
 4489        if (curveSz == ecc_sets[idx].size) {
 4490            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, prime,
 4491                            primeSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
 4492                (wc_ecc_cmp_param(ecc_sets[idx].Af, Af, AfSz,
 4493                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
 4494                (wc_ecc_cmp_param(ecc_sets[idx].Bf, Bf, BfSz,
 4495                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
 4496                (wc_ecc_cmp_param(ecc_sets[idx].order, order,
 4497                                  orderSz, WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
 4498                (wc_ecc_cmp_param(ecc_sets[idx].Gx, Gx, GxSz,
 4499                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
 4500                (wc_ecc_cmp_param(ecc_sets[idx].Gy, Gy, GySz,
 4501                                  WC_TYPE_UNSIGNED_BIN) == MP_EQ) &&
 4502                (cofactor == ecc_sets[idx].cofactor)) {
 4503                    break;
 4504            }
 4505        }
 4506    }
 4507
 4508    if (ecc_sets[idx].size == 0)
 4509        return ECC_CURVE_INVALID;
 4510
 4511    return ecc_sets[idx].id;
 4512}
 4513
 4514/* Returns the curve id in ecc_sets[] that corresponds
 4515 * to a given domain parameters pointer.
 4516 *
 4517 * dp   domain parameters pointer
 4518 *
 4519 * return curve id, from ecc_sets[] on success, negative on error
 4520 */
 4521int wc_ecc_get_curve_id_from_dp_params(const ecc_set_type* dp)
 4522{
 4523    int idx;
 4524
 4525    if (dp == NULL
 4526    #ifndef WOLFSSL_ECC_CURVE_STATIC
 4527         || dp->prime == NULL ||  dp->Af == NULL ||
 4528        dp->Bf == NULL || dp->order == NULL || dp->Gx == NULL || dp->Gy == NULL
 4529    #endif
 4530    ) {
 4531        return BAD_FUNC_ARG;
 4532    }
 4533
 4534    for (idx = 0; ecc_sets[idx].size != 0; idx++) {
 4535        if (dp->size == ecc_sets[idx].size) {
 4536            if ((wc_ecc_cmp_param(ecc_sets[idx].prime, (const byte*)dp->prime,
 4537                    (word32)XSTRLEN(dp->prime), WC_TYPE_HEX_STR) == MP_EQ) &&
 4538                (wc_ecc_cmp_param(ecc_sets[idx].Af, (const byte*)dp->Af,
 4539                    (word32)XSTRLEN(dp->Af),WC_TYPE_HEX_STR) == MP_EQ) &&
 4540                (wc_ecc_cmp_param(ecc_sets[idx].Bf, (const byte*)dp->Bf,
 4541                    (word32)XSTRLEN(dp->Bf),WC_TYPE_HEX_STR) == MP_EQ) &&
 4542                (wc_ecc_cmp_param(ecc_sets[idx].order, (const byte*)dp->order,
 4543                    (word32)XSTRLEN(dp->order),WC_TYPE_HEX_STR) == MP_EQ) &&
 4544                (wc_ecc_cmp_param(ecc_sets[idx].Gx, (const byte*)dp->Gx,
 4545                    (word32)XSTRLEN(dp->Gx),WC_TYPE_HEX_STR) == MP_EQ) &&
 4546                (wc_ecc_cmp_param(ecc_sets[idx].Gy, (const byte*)dp->Gy,
 4547                    (word32)XSTRLEN(dp->Gy),WC_TYPE_HEX_STR) == MP_EQ) &&
 4548                (dp->cofactor == ecc_sets[idx].cofactor)) {
 4549                    break;
 4550            }
 4551        }
 4552    }
 4553
 4554    if (ecc_sets[idx].size == 0)
 4555        return ECC_CURVE_INVALID;
 4556
 4557    return ecc_sets[idx].id;
 4558}
 4559
 4560/* Returns the curve id that corresponds to a given OID,
 4561 * as listed in ecc_sets[] of ecc.c.
 4562 *
 4563 * oid   OID, from ecc_sets[].name in ecc.c
 4564 * len   OID len, from ecc_sets[].name in ecc.c
 4565 * return curve id, from ecc_sets[] on success, negative on error
 4566 */
 4567int wc_ecc_get_curve_id_from_oid(const byte* oid, word32 len)
 4568{
 4569    int curve_idx;
 4570#if defined(HAVE_OID_DECODING) || defined(HAVE_OID_ENCODING)
 4571    int ret;
 4572    #ifdef HAVE_OID_DECODING
 4573    word16 decOid[MAX_OID_SZ/sizeof(word16)];
 4574    #else
 4575    byte  decOid[MAX_OID_SZ];
 4576    #endif
 4577    word32 decOidSz;
 4578#endif
 4579
 4580    if (oid == NULL)
 4581        return BAD_FUNC_ARG;
 4582
 4583#ifdef HAVE_OID_DECODING
 4584    decOidSz = (word32)sizeof(decOid);
 4585    ret = DecodeObjectId(oid, len, decOid, &decOidSz);
 4586    if (ret != 0) {
 4587        return ret;
 4588    }
 4589#endif
 4590
 4591    if (len == 0) {
 4592        /* SAKKE has zero oidSz and will otherwise match with len==0. */
 4593        WOLFSSL_MSG("zero oidSz");
 4594        return ECC_CURVE_INVALID;
 4595    }
 4596
 4597    for (curve_idx = 0; ecc_sets[curve_idx].size != 0; curve_idx++) {
 4598    #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
 4599        decOidSz = (word32)sizeof(decOid);
 4600        ret = EncodeObjectId(ecc_sets[curve_idx].oid, ecc_sets[curve_idx].oidSz,
 4601            decOid, &decOidSz);
 4602        if (ret != 0) {
 4603            continue;
 4604        }
 4605    #endif
 4606
 4607        if (
 4608        #ifndef WOLFSSL_ECC_CURVE_STATIC
 4609            ecc_sets[curve_idx].oid &&
 4610        #endif
 4611        #if defined(HAVE_OID_ENCODING) && !defined(HAVE_OID_DECODING)
 4612            decOidSz == len &&
 4613                XMEMCMP(decOid, oid, len) == 0
 4614        #elif defined(HAVE_OID_ENCODING) && defined(HAVE_OID_DECODING)
 4615            /* We double because decOidSz is a count of word16 elements. */
 4616            ecc_sets[curve_idx].oidSz == decOidSz &&
 4617                XMEMCMP(ecc_sets[curve_idx].oid, decOid, decOidSz * 2) == 0
 4618        #else
 4619            ecc_sets[curve_idx].oidSz == len &&
 4620                XMEMCMP(ecc_sets[curve_idx].oid, oid, len) == 0
 4621        #endif
 4622        ) {
 4623            break;
 4624        }
 4625    }
 4626    if (ecc_sets[curve_idx].size == 0) {
 4627        WOLFSSL_MSG("ecc_set curve name not found");
 4628        return ECC_CURVE_INVALID;
 4629    }
 4630
 4631    return ecc_sets[curve_idx].id;
 4632}
 4633
 4634/* Get curve parameters using curve index */
 4635const ecc_set_type* wc_ecc_get_curve_params(int curve_idx)
 4636{
 4637    const ecc_set_type* ecc_set = NULL;
 4638
 4639    if (curve_idx >= 0 && curve_idx < (int)ECC_SET_COUNT) {
 4640        ecc_set = &ecc_sets[curve_idx];
 4641    }
 4642    return ecc_set;
 4643}
 4644
 4645
 4646#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 4647static WC_INLINE int wc_ecc_alloc_mpint(ecc_key* key, mp_int** mp)
 4648{
 4649   if (key == NULL || mp == NULL)
 4650      return BAD_FUNC_ARG;
 4651   if (*mp == NULL) {
 4652      *mp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_BIGINT);
 4653      if (*mp == NULL) {
 4654         return MEMORY_E;
 4655      }
 4656      XMEMSET(*mp, 0, sizeof(mp_int));
 4657   }
 4658   return 0;
 4659}
 4660static WC_INLINE void wc_ecc_free_mpint(ecc_key* key, mp_int** mp)
 4661{
 4662   if (key && mp && *mp) {
 4663      mp_clear(*mp);
 4664      XFREE(*mp, key->heap, DYNAMIC_TYPE_BIGINT);
 4665      *mp = NULL;
 4666   }
 4667}
 4668
 4669static int wc_ecc_alloc_async(ecc_key* key)
 4670{
 4671    int err = wc_ecc_alloc_mpint(key, &key->r);
 4672    if (err == 0)
 4673        err = wc_ecc_alloc_mpint(key, &key->s);
 4674    return err;
 4675}
 4676
 4677static void wc_ecc_free_async(ecc_key* key)
 4678{
 4679    wc_ecc_free_mpint(key, &key->r);
 4680    wc_ecc_free_mpint(key, &key->s);
 4681#ifdef HAVE_CAVIUM_V
 4682    wc_ecc_free_mpint(key, &key->e);
 4683    wc_ecc_free_mpint(key, &key->signK);
 4684#endif /* HAVE_CAVIUM_V */
 4685}
 4686#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
 4687
 4688
 4689#ifdef HAVE_ECC_DHE
 4690/**
 4691  Create an ECC shared secret between two keys
 4692  private_key      The private ECC key (heap hint based off of private key)
 4693  public_key       The public key
 4694  out              [out] Destination of the shared secret
 4695                         Conforms to EC-DH from ANSI X9.63
 4696  outlen           [in/out] The max size and resulting size of the shared secret
 4697  return           MP_OKAY if successful
 4698*/
 4699WOLFSSL_ABI
 4700int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
 4701                      word32* outlen)
 4702{
 4703   int err = 0;
 4704
 4705#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
 4706   !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100)
 4707   CRYS_ECDH_TempData_t tempBuff;
 4708#endif
 4709
 4710   (void)err;
 4711
 4712   if (private_key == NULL || public_key == NULL || out == NULL ||
 4713                                                            outlen == NULL) {
 4714       return BAD_FUNC_ARG;
 4715   }
 4716
 4717#ifdef WOLF_CRYPTO_CB
 4718    #ifndef WOLF_CRYPTO_CB_FIND
 4719    if (private_key->devId != INVALID_DEVID)
 4720    #endif
 4721    {
 4722        err = wc_CryptoCb_Ecdh(private_key, public_key, out, outlen);
 4723        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 4724            return err;
 4725        /* fall-through when unavailable */
 4726    }
 4727#endif
 4728
 4729#ifdef WOLF_CRYPTO_CB_ONLY_ECC
 4730    return NO_VALID_DEVID;
 4731#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
 4732   /* type valid? */
 4733   if (private_key->type != ECC_PRIVATEKEY &&
 4734           private_key->type != ECC_PRIVATEKEY_ONLY) {
 4735      return ECC_BAD_ARG_E;
 4736   }
 4737
 4738   /* Verify domain params supplied */
 4739   if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL ||
 4740       wc_ecc_is_valid_idx(public_key->idx)  == 0 || public_key->dp == NULL) {
 4741      return ECC_BAD_ARG_E;
 4742   }
 4743
 4744   /* Verify curve id matches */
 4745   if (private_key->dp->id != public_key->dp->id) {
 4746      return ECC_BAD_ARG_E;
 4747   }
 4748
 4749#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
 4750    defined(WOLFSSL_MICROCHIP_TA100)
 4751   /* For SECP256R1 use hardware */
 4752   if (private_key->dp->id == ECC_SECP256R1 &&
 4753       private_key->slot != ATECC_INVALID_SLOT) {
 4754       err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
 4755       *outlen = private_key->dp->size;
 4756   }
 4757   else {
 4758      err = NOT_COMPILED_IN;
 4759   }
 4760#elif defined(WOLFSSL_CRYPTOCELL)
 4761
 4762    /* generate a secret*/
 4763    err = CRYS_ECDH_SVDP_DH(&public_key->ctx.pubKey,
 4764                            &private_key->ctx.privKey,
 4765                            out,
 4766                            (uint32_t*)outlen,
 4767                            &tempBuff);
 4768
 4769    if (err != SA_SILIB_RET_OK){
 4770        WOLFSSL_MSG("CRYS_ECDH_SVDP_DH for secret failed");
 4771        return err;
 4772    }
 4773#elif defined(WOLFSSL_SILABS_SE_ACCEL)
 4774   err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
 4775#elif defined(WOLFSSL_KCAPI_ECC)
 4776   err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
 4777#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE)
 4778   err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
 4779#else
 4780   err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
 4781#endif /* WOLFSSL_ATECC508A */
 4782#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
 4783
 4784   return err;
 4785}
 4786
 4787
 4788#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
 4789    !defined(WOLFSSL_MICROCHIP_TA100) && \
 4790    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
 4791    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
 4792
 4793int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
 4794                               byte* out, word32* outlen)
 4795{
 4796    int err = MP_OKAY;
 4797    mp_int* k = ecc_get_k(private_key);
 4798#ifdef HAVE_ECC_CDH
 4799    WC_DECLARE_VAR(k_lcl, mp_int, 1, 0);
 4800#endif
 4801#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
 4802    defined(WC_ECC_NONBLOCK_ONLY)
 4803    ecc_nb_ctx_t nb_ctx;
 4804    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
 4805#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
 4806
 4807#ifdef HAVE_ECC_CDH
 4808    /* if cofactor flag has been set */
 4809    if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
 4810        mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
 4811        /* only perform cofactor calc if not equal to 1 */
 4812        if (cofactor != 1) {
 4813#ifdef WOLFSSL_SMALL_STACK
 4814            if ((k_lcl = (mp_int *)XMALLOC(sizeof(*k_lcl), private_key->heap, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
 4815                return MEMORY_E;
 4816#endif
 4817            k = k_lcl;
 4818            if (mp_init(k) != MP_OKAY) {
 4819                err = MEMORY_E;
 4820                goto errout;
 4821            }
 4822            /* multiply cofactor times private key "k" */
 4823            err = mp_mul_d(ecc_get_k(private_key), cofactor, k);
 4824            if (err != MP_OKAY)
 4825                goto errout;
 4826        }
 4827    }
 4828#endif
 4829
 4830#ifdef WOLFSSL_HAVE_SP_ECC
 4831
 4832#ifndef WOLFSSL_SP_NO_256
 4833    if (private_key->idx != ECC_CUSTOM_IDX &&
 4834        ecc_sets[private_key->idx].id == ECC_SECP256R1) {
 4835    #ifndef WC_ECC_NONBLOCK
 4836        err = sp_ecc_secret_gen_256(k, point, out, outlen, private_key->heap);
 4837    #else
 4838        if (private_key->nb_ctx) {
 4839            err = sp_ecc_secret_gen_256_nb(&private_key->nb_ctx->sp_ctx, k,
 4840                                           point, out, outlen,
 4841                                           private_key->heap);
 4842        }
 4843        else {
 4844        #ifdef WC_ECC_NONBLOCK_ONLY
 4845            do { /* perform blocking call to non-blocking function */
 4846                err = sp_ecc_secret_gen_256_nb(&nb_ctx.sp_ctx, k, point, out,
 4847                                               outlen, private_key->heap);
 4848            } while (err == FP_WOULDBLOCK);
 4849        #else
 4850            err = sp_ecc_secret_gen_256(k, point, out, outlen,
 4851                                        private_key->heap);
 4852        #endif /* WC_ECC_NONBLOCK_ONLY */
 4853        }
 4854    #endif /* !WC_ECC_NONBLOCK */
 4855    }
 4856    else
 4857#endif /* ! WOLFSSL_SP_NO_256 */
 4858#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 4859    if (private_key->idx != ECC_CUSTOM_IDX &&
 4860                               ecc_sets[private_key->idx].id == ECC_SM2P256V1) {
 4861        err = sp_ecc_secret_gen_sm2_256(k, point, out, outlen,
 4862                                                             private_key->heap);
 4863    }
 4864    else
 4865#endif
 4866#ifdef WOLFSSL_SP_384
 4867    if (private_key->idx != ECC_CUSTOM_IDX &&
 4868        ecc_sets[private_key->idx].id == ECC_SECP384R1) {
 4869    #ifndef WC_ECC_NONBLOCK
 4870        err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap);
 4871    #else
 4872        if (private_key->nb_ctx) {
 4873            err = sp_ecc_secret_gen_384_nb(&private_key->nb_ctx->sp_ctx, k,
 4874                                           point, out, outlen,
 4875                                           private_key->heap);
 4876        }
 4877        else {
 4878        #ifdef WC_ECC_NONBLOCK_ONLY
 4879            do { /* perform blocking call to non-blocking function */
 4880                err = sp_ecc_secret_gen_384_nb(&nb_ctx.sp_ctx, k, point, out,
 4881                                               outlen, private_key->heap);
 4882            } while (err == FP_WOULDBLOCK);
 4883        #else
 4884            err = sp_ecc_secret_gen_384(k, point, out, outlen,
 4885                                        private_key->heap);
 4886        #endif /* WC_ECC_NONBLOCK_ONLY */
 4887        }
 4888    #endif /* !WC_ECC_NONBLOCK */
 4889    }
 4890    else
 4891#endif /* WOLFSSL_SP_384 */
 4892#ifdef WOLFSSL_SP_521
 4893    if (private_key->idx != ECC_CUSTOM_IDX &&
 4894                               ecc_sets[private_key->idx].id == ECC_SECP521R1) {
 4895    #ifndef WC_ECC_NONBLOCK
 4896        err = sp_ecc_secret_gen_521(k, point, out, outlen, private_key->heap);
 4897    #else
 4898        if (private_key->nb_ctx) {
 4899            err = sp_ecc_secret_gen_521_nb(&private_key->nb_ctx->sp_ctx, k,
 4900                                           point, out, outlen,
 4901                                           private_key->heap);
 4902        }
 4903        else {
 4904        #ifdef WC_ECC_NONBLOCK_ONLY
 4905            do { /* perform blocking call to non-blocking function */
 4906                err = sp_ecc_secret_gen_521_nb(&nb_ctx.sp_ctx, k, point, out,
 4907                                               outlen, private_key->heap);
 4908            } while (err == FP_WOULDBLOCK);
 4909        #else
 4910            err = sp_ecc_secret_gen_521(k, point, out, outlen,
 4911                                        private_key->heap);
 4912        #endif /* WC_ECC_NONBLOCK_ONLY */
 4913        }
 4914    #endif /* !WC_ECC_NONBLOCK */
 4915    }
 4916    else
 4917#endif /* WOLFSSL_SP_521 */
 4918#else
 4919    (void)point;
 4920    (void)out;
 4921    (void)outlen;
 4922    (void)k;
 4923#endif
 4924#if defined(WOLFSSL_SP_MATH)
 4925    {
 4926        err = WC_KEY_SIZE_E;
 4927        goto errout;
 4928    }
 4929#else
 4930    {
 4931        ecc_point* result = NULL;
 4932        #ifdef WOLFSSL_NO_MALLOC
 4933        ecc_point  lcl_result;
 4934        #endif
 4935        int x = 0;
 4936        mp_digit mp = 0;
 4937        DECLARE_CURVE_SPECS(3);
 4938
 4939        /* load curve info */
 4940        ALLOC_CURVE_SPECS(3, err);
 4941        if (err == MP_OKAY) {
 4942            err = wc_ecc_curve_load(private_key->dp, &curve,
 4943                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
 4944                 ECC_CURVE_FIELD_ORDER));
 4945        }
 4946
 4947        if (err != MP_OKAY) {
 4948            FREE_CURVE_SPECS();
 4949            goto errout;
 4950        }
 4951
 4952        /* make new point */
 4953    #ifdef WOLFSSL_NO_MALLOC
 4954        result = &lcl_result;
 4955    #endif
 4956        err = wc_ecc_new_point_ex(&result, private_key->heap);
 4957        if (err != MP_OKAY) {
 4958            wc_ecc_curve_free(curve);
 4959            FREE_CURVE_SPECS();
 4960            goto errout;
 4961        }
 4962
 4963#ifdef ECC_TIMING_RESISTANT
 4964        if (private_key->rng == NULL) {
 4965            err = MISSING_RNG_E;
 4966        }
 4967#endif
 4968
 4969        if (err == MP_OKAY) {
 4970            /* Map in a separate call as this should be constant time */
 4971#ifdef ECC_TIMING_RESISTANT
 4972            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
 4973                                              curve->order, private_key->rng, 0,
 4974                                              private_key->heap);
 4975#else
 4976            err = wc_ecc_mulmod_ex2(k, point, result, curve->Af, curve->prime,
 4977                                      curve->order, NULL, 0, private_key->heap);
 4978#endif
 4979        }
 4980        if (err == MP_OKAY) {
 4981        #ifdef WOLFSSL_CHECK_MEM_ZERO
 4982            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->x",
 4983                result->x);
 4984            mp_memzero_add("wc_ecc_shared_secret_gen_sync result->y",
 4985                result->y);
 4986        #endif
 4987            err = mp_montgomery_setup(curve->prime, &mp);
 4988        }
 4989        if (err == MP_OKAY) {
 4990            /* Use constant time map if compiled in */
 4991            err = ecc_map_ex(result, curve->prime, mp, 1);
 4992        }
 4993        if (err == MP_OKAY) {
 4994            x = mp_unsigned_bin_size(curve->prime);
 4995            if (*outlen < (word32)x || x < mp_unsigned_bin_size(result->x)) {
 4996                err = BUFFER_E;
 4997            }
 4998        }
 4999
 5000        if (err == MP_OKAY) {
 5001            XMEMSET(out, 0, (size_t)x);
 5002            err = mp_to_unsigned_bin(result->x, out +
 5003                                     (x - mp_unsigned_bin_size(result->x)));
 5004        }
 5005        *outlen = (word32)x;
 5006
 5007        mp_forcezero(result->x);
 5008        mp_forcezero(result->y);
 5009        wc_ecc_del_point_ex(result, private_key->heap);
 5010
 5011        wc_ecc_curve_free(curve);
 5012        FREE_CURVE_SPECS();
 5013    }
 5014#endif
 5015
 5016  errout:
 5017
 5018#ifdef HAVE_ECC_CDH
 5019    if (k == k_lcl)
 5020        mp_forcezero(k);
 5021    WC_FREE_VAR_EX(k_lcl, private_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
 5022#endif
 5023
 5024    return err;
 5025}
 5026
 5027#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 5028static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
 5029            ecc_point* point, byte* out, word32 *outlen)
 5030{
 5031    int err = 0;
 5032
 5033#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
 5034    DECLARE_CURVE_SPECS(3);
 5035
 5036    /* load curve info */
 5037    ALLOC_CURVE_SPECS(3, err);
 5038    if (err == MP_OKAY) {
 5039        err = wc_ecc_curve_load(private_key->dp, &curve,
 5040            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
 5041             ECC_CURVE_FIELD_ORDER));
 5042    }
 5043
 5044    if (err != MP_OKAY) {
 5045        FREE_CURVE_SPECS();
 5046        return err;
 5047    }
 5048
 5049    if (private_key->dp
 5050    #ifdef WOLFSSL_CUSTOM_CURVES
 5051        && private_key->dp->id != ECC_CURVE_CUSTOM
 5052    #endif
 5053    #ifdef HAVE_CAVIUM_V
 5054        /* verify the curve is supported by hardware */
 5055        && NitroxEccIsCurveSupported(private_key)
 5056    #endif
 5057    ) {
 5058        word32 keySz = private_key->dp->size;
 5059
 5060        /* sync public key x/y */
 5061        err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
 5062            &ecc_get_k(private_key)->raw, keySz);
 5063        if (err == MP_OKAY)
 5064            err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
 5065        if (err == MP_OKAY)
 5066            err = wc_mp_to_bigint_sz(point->y, &point->y->raw, keySz);
 5067    #ifdef HAVE_CAVIUM_V
 5068        /* allocate buffer for output */
 5069        if (err == MP_OKAY)
 5070            err = wc_ecc_alloc_mpint(private_key, &private_key->e);
 5071        if (err == MP_OKAY)
 5072            err = wc_bigint_alloc(&private_key->e->raw,
 5073                NitroxEccGetSize(private_key)*2);
 5074        if (err == MP_OKAY)
 5075            err = NitroxEcdh(private_key,
 5076                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
 5077                private_key->e->raw.buf, &private_key->e->raw.len,
 5078                &curve->prime->raw);
 5079    #else
 5080        if (err == MP_OKAY)
 5081            err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
 5082        if (err == MP_OKAY)
 5083            err = IntelQaEcdh(&private_key->asyncDev,
 5084                &ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
 5085                out, outlen,
 5086                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
 5087                private_key->dp->cofactor);
 5088    #endif
 5089    }
 5090    else
 5091#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
 5092    if (wc_AsyncSwInit(&private_key->asyncDev, ASYNC_SW_ECC_SHARED_SEC)) {
 5093        WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
 5094        sw->eccSharedSec.private_key = private_key;
 5095        sw->eccSharedSec.public_point = point;
 5096        sw->eccSharedSec.out = out;
 5097        sw->eccSharedSec.outLen = outlen;
 5098        err = WC_PENDING_E;
 5099    }
 5100    else
 5101#endif
 5102    {
 5103        /* use sync in other cases */
 5104        err = wc_ecc_shared_secret_gen_sync(private_key, point, out, outlen);
 5105    }
 5106
 5107    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
 5108        private_key->state++;
 5109    }
 5110
 5111#if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
 5112    wc_ecc_curve_free(curve);
 5113    FREE_CURVE_SPECS();
 5114#endif
 5115
 5116    return err;
 5117}
 5118#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
 5119
 5120#ifndef WOLF_CRYPTO_CB_ONLY_ECC
 5121/**
 5122 Create an ECC shared secret between private key and public point
 5123 private_key      The private ECC key (heap hint based on private key)
 5124 point            The point to use (public key)
 5125 out              [out] Destination of the shared secret
 5126                        Conforms to EC-DH from ANSI X9.63
 5127 outlen           [in/out] The max size and resulting size of the shared secret
 5128 return           MP_OKAY if successful
 5129*/
 5130int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
 5131                            byte* out, word32 *outlen)
 5132{
 5133    int err;
 5134
 5135    if (private_key == NULL || point == NULL || out == NULL ||
 5136                                                            outlen == NULL) {
 5137        return BAD_FUNC_ARG;
 5138    }
 5139
 5140    /* type valid? */
 5141    if (private_key->type != ECC_PRIVATEKEY &&
 5142            private_key->type != ECC_PRIVATEKEY_ONLY) {
 5143        WOLFSSL_MSG("ECC_BAD_ARG_E");
 5144        return ECC_BAD_ARG_E;
 5145    }
 5146
 5147    /* Verify domain params supplied */
 5148    if (wc_ecc_is_valid_idx(private_key->idx) == 0 || private_key->dp == NULL) {
 5149        WOLFSSL_MSG("wc_ecc_is_valid_idx failed");
 5150        return ECC_BAD_ARG_E;
 5151    }
 5152
 5153    SAVE_VECTOR_REGISTERS(return _svr_ret;);
 5154
 5155    switch (private_key->state) {
 5156        case ECC_STATE_NONE:
 5157        case ECC_STATE_SHARED_SEC_GEN:
 5158            private_key->state = ECC_STATE_SHARED_SEC_GEN;
 5159
 5160        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 5161            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
 5162                err = wc_ecc_shared_secret_gen_async(private_key, point,
 5163                    out, outlen);
 5164            }
 5165            else
 5166        #endif
 5167            {
 5168                err = wc_ecc_shared_secret_gen_sync(private_key, point,
 5169                    out, outlen);
 5170            }
 5171            if (err < 0) {
 5172                break;
 5173            }
 5174            FALL_THROUGH;
 5175
 5176        case ECC_STATE_SHARED_SEC_RES:
 5177            private_key->state = ECC_STATE_SHARED_SEC_RES;
 5178        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 5179            if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
 5180            #ifdef HAVE_CAVIUM_V
 5181                /* verify the curve is supported by hardware */
 5182                if (NitroxEccIsCurveSupported(private_key)) {
 5183                    /* copy output */
 5184                    *outlen = private_key->dp->size;
 5185                    XMEMCPY(out, private_key->e->raw.buf, *outlen);
 5186                }
 5187            #endif /* HAVE_CAVIUM_V */
 5188            }
 5189        #endif /* WOLFSSL_ASYNC_CRYPT */
 5190            err = 0;
 5191            break;
 5192
 5193        default:
 5194            err = BAD_STATE_E;
 5195    } /* switch */
 5196
 5197    RESTORE_VECTOR_REGISTERS();
 5198
 5199    /* if async pending then return and skip done cleanup below */
 5200    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
 5201        return err;
 5202    }
 5203
 5204    /* cleanup */
 5205#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 5206    wc_ecc_free_async(private_key);
 5207#endif
 5208    private_key->state = ECC_STATE_NONE;
 5209
 5210    return err;
 5211}
 5212#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
 5213#elif defined(WOLFSSL_KCAPI_ECC)
 5214int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
 5215                            byte* out, word32 *outlen)
 5216{
 5217    int err;
 5218    WC_DECLARE_VAR(public_key, ecc_key, 1,
 5219                   private_key ? private_key->heap : NULL);
 5220
 5221    WC_ALLOC_VAR_EX(public_key, ecc_key, 1, private_key->heap, DYNAMIC_TYPE_ECC,
 5222                    return MEMORY_E);
 5223
 5224    err = wc_ecc_init_ex(public_key, private_key->heap, INVALID_DEVID);
 5225    if (err == MP_OKAY) {
 5226        #if FIPS_VERSION3_GE(6,0,0)
 5227        /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
 5228         * both keysize == 0 and curve_id == 0 ensure we select an appropriate
 5229         * keysize here when relying on default selection */
 5230        if (private_key->dp->size < WC_ECC_FIPS_GEN_MIN) {
 5231            if (private_key->dp->size == 0 &&
 5232                (private_key->dp->id == ECC_SECP256R1 ||
 5233                private_key->dp->id == ECC_SECP224R1 ||
 5234                private_key->dp->id == ECC_SECP384R1 ||
 5235                private_key->dp->id == ECC_SECP521R1)) {
 5236                WOLFSSL_MSG("ECC dp->size zero but dp->id sufficient for FIPS");
 5237                err = 0;
 5238            } else {
 5239                WOLFSSL_MSG("ECC curve too small for FIPS mode");
 5240                err = ECC_CURVE_OID_E;
 5241            }
 5242        }
 5243        if (err == 0) { /* FIPS specific check */
 5244        #endif
 5245        err = wc_ecc_set_curve(public_key, private_key->dp->size,
 5246                               private_key->dp->id);
 5247        if (err == MP_OKAY) {
 5248            err = mp_copy(point->x, public_key->pubkey.x);
 5249        }
 5250        #if FIPS_VERSION3_GE(6,0,0)
 5251        } /* end FIPS specific check */
 5252        #endif
 5253        if (err == MP_OKAY) {
 5254            err = mp_copy(point->y, public_key->pubkey.y);
 5255        }
 5256        if (err == MP_OKAY) {
 5257            err = wc_ecc_shared_secret(private_key, public_key, out, outlen);
 5258        }
 5259
 5260        wc_ecc_free(public_key);
 5261    }
 5262
 5263    WC_FREE_VAR_EX(public_key, private_key->heap, DYNAMIC_TYPE_ECC);
 5264    return err;
 5265}
 5266#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL && !WOLFSSL_KCAPI_ECC */
 5267#endif /* HAVE_ECC_DHE */
 5268
 5269/* Checks if a point p lies on the curve with index curve_idx */
 5270int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx)
 5271{
 5272    int err = MP_OKAY;
 5273    DECLARE_CURVE_SPECS(3);
 5274
 5275    if (p == NULL)
 5276        return BAD_FUNC_ARG;
 5277
 5278    /* is the IDX valid ?  */
 5279    if (wc_ecc_is_valid_idx(curve_idx) == 0) {
 5280       return ECC_BAD_ARG_E;
 5281    }
 5282
 5283    SAVE_VECTOR_REGISTERS(return _svr_ret;);
 5284
 5285    ALLOC_CURVE_SPECS(3, err);
 5286    if (err == MP_OKAY) {
 5287        err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve,
 5288                                ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
 5289                                ECC_CURVE_FIELD_BF);
 5290    }
 5291
 5292    if (err == MP_OKAY) {
 5293        err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime);
 5294    }
 5295
 5296    wc_ecc_curve_free(curve);
 5297    FREE_CURVE_SPECS();
 5298
 5299    RESTORE_VECTOR_REGISTERS();
 5300
 5301    return err;
 5302}
 5303
 5304#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
 5305    !defined(WOLFSSL_CRYPTOCELL) && \
 5306    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
 5307      defined(WOLFSSL_IMXRT1170_CAAM))
 5308/* return 1 if point is at infinity, 0 if not, < 0 on error */
 5309int wc_ecc_point_is_at_infinity(ecc_point* p)
 5310{
 5311    if (p == NULL)
 5312        return BAD_FUNC_ARG;
 5313    if (mp_iszero(p->x) && mp_iszero(p->y))
 5314        return 1;
 5315
 5316    return 0;
 5317}
 5318#endif
 5319
 5320/* generate random and ensure its greater than 0 and less than order */
 5321int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
 5322{
 5323#ifndef WC_NO_RNG
 5324#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
 5325    int err;
 5326    byte buf[ECC_MAXSIZE_GEN];
 5327
 5328    if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
 5329                                                                order == NULL) {
 5330        return BAD_FUNC_ARG;
 5331    }
 5332
 5333    /* generate 8 extra bytes to mitigate bias from the modulo operation below */
 5334    /* see section A.1.2 in 'Suite B Implementor's Guide to FIPS 186-3 (ECDSA)' */
 5335    size += 8;
 5336
 5337    /* make up random string */
 5338    err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
 5339#ifdef WOLFSSL_CHECK_MEM_ZERO
 5340    wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
 5341#endif
 5342
 5343    /* load random buffer data into k */
 5344    if (err == 0)
 5345        err = mp_read_unsigned_bin(k, buf, (word32)size);
 5346
 5347    /* the key should be smaller than the order of base point */
 5348    if (err == MP_OKAY) {
 5349        if (mp_cmp(k, order) != MP_LT) {
 5350            err = mp_mod(k, order, k);
 5351        }
 5352    }
 5353
 5354    /* quick sanity check to make sure we're not dealing with a 0 key */
 5355    if (err == MP_OKAY) {
 5356        if (mp_iszero(k) == MP_YES)
 5357          err = MP_ZERO_E;
 5358    }
 5359
 5360    ForceZero(buf, ECC_MAXSIZE_GEN);
 5361#ifdef WOLFSSL_CHECK_MEM_ZERO
 5362    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
 5363#endif
 5364
 5365    return err;
 5366#else
 5367    int err;
 5368    byte buf[ECC_MAXSIZE_GEN];
 5369    int bits;
 5370
 5371    if ((rng == NULL) || (size < 0) || (size + 8 > ECC_MAXSIZE_GEN) ||
 5372            (k == NULL) || (order == NULL)) {
 5373        return BAD_FUNC_ARG;
 5374    }
 5375
 5376    /* Get actual bit count of order. */
 5377    bits = mp_count_bits(order);
 5378    size = (bits + 7) >> 3;
 5379
 5380    /* generate number in range of order through rejection sampling. */
 5381    /* see section A.2.2 and A.4.2 in FIPS 186-5 */
 5382    do {
 5383        /* A.2.2 step 3: make up random string */
 5384        err = wc_RNG_GenerateBlock(rng, buf, (word32)size);
 5385    #ifdef WOLFSSL_CHECK_MEM_ZERO
 5386        wc_MemZero_Add("wc_ecc_gen_k buf", buf, size);
 5387    #endif
 5388        /* Generated multiple of 8 bits but now make it size of order. */
 5389        if ((bits & 0x7) > 0) {
 5390            buf[0] &= (1 << (bits & 0x7)) - 1;
 5391        }
 5392
 5393        /* A.2.2 step 4: convert to integer. */
 5394        /* A.4.2 step 3: Convert the bit string to integer x. */
 5395        if (err == 0) {
 5396            err = mp_read_unsigned_bin(k, buf, (word32)size);
 5397        }
 5398
 5399        /* A.4.2 step 4, 5: x must be in range [1, n-1] */
 5400        if ((err == MP_OKAY) && !mp_iszero(k) &&
 5401                (mp_cmp_ct(k, order, order->used) == MP_LT)) {
 5402            break;
 5403        }
 5404    }
 5405    while (err == MP_OKAY);
 5406
 5407    ForceZero(buf, ECC_MAXSIZE_GEN);
 5408#ifdef WOLFSSL_CHECK_MEM_ZERO
 5409    wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
 5410#endif
 5411
 5412    return err;
 5413#endif
 5414#else
 5415    (void)rng;
 5416    (void)size;
 5417    (void)k;
 5418    (void)order;
 5419    return NOT_COMPILED_IN;
 5420#endif /* !WC_NO_RNG */
 5421}
 5422
 5423static WC_INLINE void wc_ecc_reset(ecc_key* key)
 5424{
 5425    /* make sure required key variables are reset */
 5426    key->state = ECC_STATE_NONE;
 5427}
 5428
 5429
 5430/* create the public ECC key from a private key
 5431 *
 5432 * key     an initialized private key to generate public part from
 5433 * curve   [in]curve for key, cannot be NULL
 5434 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
 5435 *         is cached in key instead.
 5436 *
 5437 * Note this function is local to the file because of the argument type
 5438 *      ecc_curve_spec. Having this argument allows for not having to load the
 5439 *      curve type multiple times when generating a key with wc_ecc_make_key().
 5440 * For async the results are placed directly into pubOut, so this function
 5441 *      does not need to be called again
 5442 *
 5443 * returns MP_OKAY on success
 5444 */
 5445static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
 5446        ecc_point* pubOut, WC_RNG* rng)
 5447{
 5448    int err = MP_OKAY;
 5449#ifdef HAVE_ECC_MAKE_PUB
 5450    ecc_point* pub;
 5451#endif /* HAVE_ECC_MAKE_PUB */
 5452
 5453    (void)rng;
 5454
 5455    if (key == NULL) {
 5456        return BAD_FUNC_ARG;
 5457    }
 5458
 5459    SAVE_VECTOR_REGISTERS(return _svr_ret;);
 5460
 5461#ifdef HAVE_ECC_MAKE_PUB
 5462    /* if ecc_point passed in then use it as output for public key point */
 5463    if (pubOut != NULL) {
 5464        pub = pubOut;
 5465    }
 5466    else {
 5467        /* caching public key making it a ECC_PRIVATEKEY instead of
 5468           ECC_PRIVATEKEY_ONLY */
 5469        pub = &key->pubkey;
 5470        key->type = ECC_PRIVATEKEY_ONLY;
 5471    }
 5472
 5473    if ((err == MP_OKAY) && (mp_iszero(ecc_get_k(key)) ||
 5474            mp_isneg(ecc_get_k(key)) ||
 5475            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))) {
 5476        err = ECC_PRIV_KEY_E;
 5477    }
 5478
 5479    if (err == MP_OKAY) {
 5480    #ifndef ALT_ECC_SIZE
 5481        err = mp_init_multi(pub->x, pub->y, pub->z, NULL, NULL, NULL);
 5482    #else
 5483        pub->x = (mp_int*)&pub->xyz[0];
 5484        pub->y = (mp_int*)&pub->xyz[1];
 5485        pub->z = (mp_int*)&pub->xyz[2];
 5486        alt_fp_init(pub->x);
 5487        alt_fp_init(pub->y);
 5488        alt_fp_init(pub->z);
 5489    #endif
 5490    }
 5491
 5492#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC_KEYGEN) && \
 5493    defined(HAVE_INTEL_QA)
 5494    if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
 5495        word32 keySz = key->dp->size;
 5496        /* sync private key to raw */
 5497        err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw, keySz);
 5498        if (err == MP_OKAY) {
 5499            err = IntelQaEccPointMul(&key->asyncDev,
 5500                &ecc_get_k(key)->raw, pub->x, pub->y, pub->z,
 5501                &curve->Gx->raw, &curve->Gy->raw,
 5502                &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
 5503                key->dp->cofactor);
 5504        }
 5505    }
 5506    else
 5507#endif
 5508    { /* BEGIN: Software Crypto */
 5509#ifdef WOLFSSL_HAVE_SP_ECC
 5510    /* Single-Precision Math (optimized for specific curves) */
 5511    if (err != MP_OKAY) {
 5512    }
 5513    else
 5514#ifndef WOLFSSL_SP_NO_256
 5515    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
 5516        err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
 5517    }
 5518    else
 5519#endif /* WOLFSSL_SP_NO_256 */
 5520#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 5521    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
 5522        err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
 5523    }
 5524    else
 5525#endif
 5526#ifdef WOLFSSL_SP_384
 5527    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
 5528        err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
 5529    }
 5530    else
 5531#endif
 5532#ifdef WOLFSSL_SP_521
 5533    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
 5534        err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
 5535    }
 5536    else
 5537#endif
 5538#endif /* WOLFSSL_HAVE_SP_ECC */
 5539
 5540#if defined(WOLFSSL_SP_MATH)
 5541        err = WC_KEY_SIZE_E;
 5542#else
 5543    if (err == MP_OKAY) {
 5544        /* Multi-Precision Math: compute public curve */
 5545        mp_digit mp = 0;
 5546        ecc_point* base = NULL;
 5547    #ifdef WOLFSSL_NO_MALLOC
 5548        ecc_point  lcl_base;
 5549        base = &lcl_base;
 5550    #endif
 5551        err = wc_ecc_new_point_ex(&base, key->heap);
 5552
 5553        /* read in the x/y for this key */
 5554        if (err == MP_OKAY)
 5555            err = mp_copy(curve->Gx, base->x);
 5556        if (err == MP_OKAY)
 5557            err = mp_copy(curve->Gy, base->y);
 5558        if (err == MP_OKAY)
 5559            err = mp_montgomery_setup(curve->prime, &mp);
 5560        if (err == MP_OKAY)
 5561            err = mp_set(base->z, 1);
 5562
 5563        /* make the public key */
 5564        if (err == MP_OKAY) {
 5565            /* Map in a separate call as this should be constant time */
 5566            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
 5567                                 curve->prime, curve->order, rng, 0, key->heap);
 5568            if (err == WC_NO_ERR_TRACE(MP_MEM)) {
 5569               err = MEMORY_E;
 5570            }
 5571        }
 5572        if (err == MP_OKAY) {
 5573            /* Use constant time map if compiled in */
 5574            err = ecc_map_ex(pub, curve->prime, mp, 1);
 5575        }
 5576
 5577        wc_ecc_del_point_ex(base, key->heap);
 5578    }
 5579#endif /* WOLFSSL_SP_MATH */
 5580    } /* END: Software Crypto */
 5581
 5582    if (err != MP_OKAY
 5583    #ifdef WOLFSSL_ASYNC_CRYPT
 5584        && err != WC_NO_ERR_TRACE(WC_PENDING_E)
 5585    #endif
 5586    ) {
 5587        /* clean up if failed */
 5588    #ifndef ALT_ECC_SIZE
 5589        mp_clear(pub->x);
 5590        mp_clear(pub->y);
 5591        mp_clear(pub->z);
 5592    #endif
 5593    }
 5594
 5595#else
 5596    /* Using hardware crypto, that does not support ecc_make_pub_ex */
 5597    (void)curve;
 5598    err = NOT_COMPILED_IN;
 5599#endif /* HAVE_ECC_MAKE_PUB */
 5600
 5601    /* change key state if public part is cached */
 5602    if (key->type == ECC_PRIVATEKEY_ONLY && pubOut == NULL) {
 5603        key->type = ECC_PRIVATEKEY;
 5604    }
 5605
 5606    RESTORE_VECTOR_REGISTERS();
 5607
 5608    return err;
 5609}
 5610
 5611
 5612/* create the public ECC key from a private key
 5613 *
 5614 * key     an initialized private key to generate public part from
 5615 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
 5616 *         is cached in key instead.
 5617 *
 5618 *
 5619 * returns MP_OKAY on success
 5620 */
 5621int wc_ecc_make_pub(ecc_key* key, ecc_point* pubOut)
 5622{
 5623    WOLFSSL_ENTER("wc_ecc_make_pub");
 5624
 5625    return wc_ecc_make_pub_ex(key, pubOut, NULL);
 5626}
 5627
 5628/* create the public ECC key from a private key - mask timing use random z
 5629 *
 5630 * key     an initialized private key to generate public part from
 5631 * pubOut  [out]ecc_point holding the public key, if NULL then public key part
 5632 *         is cached in key instead.
 5633 *
 5634 *
 5635 * returns MP_OKAY on success
 5636 */
 5637int wc_ecc_make_pub_ex(ecc_key* key, ecc_point* pubOut, WC_RNG* rng)
 5638{
 5639    int err = MP_OKAY;
 5640    DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
 5641
 5642    WOLFSSL_ENTER("wc_ecc_make_pub_ex");
 5643
 5644    if (key == NULL) {
 5645        return BAD_FUNC_ARG;
 5646    }
 5647
 5648    /* load curve info */
 5649    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
 5650    if (err == MP_OKAY) {
 5651        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
 5652    }
 5653    if (err == MP_OKAY) {
 5654        err = ecc_make_pub_ex(key, curve, pubOut, rng);
 5655    }
 5656
 5657    wc_ecc_curve_free(curve);
 5658    FREE_CURVE_SPECS();
 5659
 5660    return err;
 5661}
 5662
 5663#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
 5664    defined(WOLFSSL_MICROCHIP_TA100)
 5665/* Resolve the curve id to pass to the Microchip backend. Keep the curve
 5666 * distinction by id (not size): SECP256R1, SECP256K1 and BRAINPOOLP256R1 are
 5667 * all 32 bytes and must NOT be collapsed onto SECP256R1. */
 5668static WC_INLINE int microchip_curve_id_for_key(const ecc_key* key)
 5669{
 5670    if (key != NULL && key->dp != NULL) {
 5671        return key->dp->id;
 5672    }
 5673    return ECC_CURVE_DEF;
 5674}
 5675#endif
 5676
 5677
 5678static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
 5679        int curve_id, int flags)
 5680{
 5681    int err = 0;
 5682#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
 5683    !defined(WOLFSSL_MICROCHIP_TA100) && \
 5684    !defined(WOLFSSL_ATECC608A)
 5685    const CRYS_ECPKI_Domain_t*  pDomain;
 5686    CRYS_ECPKI_KG_TempData_t    tempBuff;
 5687    CRYS_ECPKI_KG_FipsContext_t fipsCtx;
 5688    byte ucompressed_key[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
 5689    word32 raw_size = 0;
 5690#endif
 5691#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WC_ECC_NONBLOCK) && \
 5692    defined(WC_ECC_NONBLOCK_ONLY)
 5693    ecc_nb_ctx_t nb_ctx;
 5694    XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
 5695#endif /* WOLFSSL_HAVE_SP_ECC && WC_ECC_NONBLOCK && WC_ECC_NONBLOCK_ONLY */
 5696
 5697    if (key == NULL || rng == NULL) {
 5698        return BAD_FUNC_ARG;
 5699    }
 5700
 5701    /* make sure required variables are reset */
 5702    wc_ecc_reset(key);
 5703
 5704    #if FIPS_VERSION3_GE(6,0,0)
 5705    /* Since we are allowing a pass-through of ecc_make_key_ex_fips when
 5706     * both keysize == 0 and curve_id == 0 ensure we select an appropriate
 5707     * keysize here when relying on default selection */
 5708    if (keysize < WC_ECC_FIPS_GEN_MIN) {
 5709        if (keysize == 0 && (curve_id == ECC_SECP256R1 ||
 5710             curve_id == ECC_SECP224R1 || curve_id == ECC_SECP384R1 ||
 5711             curve_id == ECC_SECP521R1)) {
 5712            WOLFSSL_MSG("ECC keysize zero but curve_id sufficient for FIPS");
 5713            err = 0;
 5714        } else {
 5715            WOLFSSL_MSG("ECC curve too small for FIPS mode");
 5716            err = ECC_CURVE_OID_E;
 5717        }
 5718    }
 5719    if (err == 0) { /* FIPS specific check */
 5720    #endif
 5721    err = wc_ecc_set_curve(key, keysize, curve_id);
 5722    if (err != 0) {
 5723        return err;
 5724    }
 5725    #if FIPS_VERSION3_GE(6,0,0)
 5726    } /* end FIPS specific check */
 5727    #endif
 5728    key->flags = (byte)flags;
 5729
 5730#if defined(WOLF_CRYPTO_CB) && defined(HAVE_ECC_DHE)
 5731    #ifndef WOLF_CRYPTO_CB_FIND
 5732    if (key->devId != INVALID_DEVID)
 5733    #endif
 5734    {
 5735        err = wc_CryptoCb_MakeEccKey(rng, keysize, key, curve_id);
 5736        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 5737            return err;
 5738        /* fall-through when unavailable */
 5739    }
 5740#endif
 5741
 5742#ifdef WOLF_CRYPTO_CB_ONLY_ECC
 5743    return NO_VALID_DEVID;
 5744#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
 5745#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 5746    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
 5747    #ifdef HAVE_CAVIUM
 5748        /* TODO: Not implemented */
 5749    #elif defined(HAVE_INTEL_QA)
 5750        /* Implemented in ecc_make_pub_ex for the pub calc */
 5751    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
 5752        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_MAKE)) {
 5753            WC_ASYNC_SW* sw = &key->asyncDev.sw;
 5754            sw->eccMake.rng = rng;
 5755            sw->eccMake.key = key;
 5756            sw->eccMake.size = keysize;
 5757            sw->eccMake.curve_id = curve_id;
 5758            return WC_PENDING_E;
 5759        }
 5760    #endif
 5761    }
 5762#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
 5763
 5764#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
 5765    defined(WOLFSSL_MICROCHIP_TA100)
 5766#if defined(WOLFSSL_MICROCHIP_TA100)
 5767    /* TA100 supports multiple curves natively. */
 5768    if (key->dp->id == ECC_SECP256R1 ||
 5769        key->dp->id == ECC_SECP224R1 ||
 5770        key->dp->id == ECC_SECP384R1 ||
 5771        key->dp->id == ECC_SECP256K1 ||
 5772        key->dp->id == ECC_BRAINPOOLP256R1) {
 5773#else
 5774    /* ATECC508A/608A hardware only supports SECP256R1. */
 5775    if (key->dp->id == ECC_SECP256R1) {
 5776#endif
 5777       key->type = ECC_PRIVATEKEY;
 5778       if (key->slot == ATECC_INVALID_SLOT)
 5779           key->slot = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
 5780       err = atmel_ecc_create_key(key->slot, microchip_curve_id_for_key(key),
 5781           key->pubkey_raw);
 5782
 5783       /* populate key->pubkey */
 5784       if (err == 0
 5785       #ifdef ALT_ECC_SIZE
 5786          && key->pubkey.x
 5787       #endif
 5788       ) {
 5789           err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
 5790                                      (word32)key->dp->size);
 5791       }
 5792       if (err == 0
 5793       #ifdef ALT_ECC_SIZE
 5794          && key->pubkey.y
 5795       #endif
 5796       ) {
 5797           err = mp_read_unsigned_bin(key->pubkey.y,
 5798                                      key->pubkey_raw + key->dp->size,
 5799                                      (word32)key->dp->size);
 5800       }
 5801   }
 5802   else {
 5803      err = NOT_COMPILED_IN;
 5804   }
 5805#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDHE)
 5806    err = se050_ecc_create_key(key, key->dp->id, key->dp->size);
 5807    key->type = ECC_PRIVATEKEY;
 5808#elif defined(WOLFSSL_CRYPTOCELL)
 5809
 5810    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
 5811    raw_size = (word32)(key->dp->size)*2 + 1;
 5812
 5813    /* generate first key pair */
 5814    err = CRYS_ECPKI_GenKeyPair(&wc_rndState,
 5815                                wc_rndGenVectFunc,
 5816                                pDomain,
 5817                                &key->ctx.privKey,
 5818                                &key->ctx.pubKey,
 5819                                &tempBuff,
 5820                                &fipsCtx);
 5821
 5822    if (err != SA_SILIB_RET_OK){
 5823        WOLFSSL_MSG("CRYS_ECPKI_GenKeyPair for key pair failed");
 5824        return err;
 5825    }
 5826    key->type = ECC_PRIVATEKEY;
 5827
 5828    err = CRYS_ECPKI_ExportPublKey(&key->ctx.pubKey,
 5829                                   CRYS_EC_PointUncompressed,
 5830                                   &ucompressed_key[0],
 5831                                   (uint32_t*)&raw_size);
 5832
 5833    if (err == SA_SILIB_RET_OK && key->pubkey.x && key->pubkey.y) {
 5834        err = mp_read_unsigned_bin(key->pubkey.x,
 5835                                   &ucompressed_key[1], key->dp->size);
 5836        if (err == MP_OKAY) {
 5837            err = mp_read_unsigned_bin(key->pubkey.y,
 5838                            &ucompressed_key[1+key->dp->size],key->dp->size);
 5839        }
 5840    }
 5841    raw_size = key->dp->size;
 5842    if (err == MP_OKAY) {
 5843        err = CRYS_ECPKI_ExportPrivKey(&key->ctx.privKey,
 5844                                       ucompressed_key,
 5845                                       (uint32_t*)&raw_size);
 5846    }
 5847
 5848    if (err == SA_SILIB_RET_OK) {
 5849        err = mp_read_unsigned_bin(key->k, ucompressed_key, raw_size);
 5850#ifdef WOLFSSL_ECC_BLIND_K
 5851        if (err == MP_OKAY) {
 5852            err = ecc_blind_k_rng(key, rng);
 5853        }
 5854#endif
 5855    }
 5856
 5857#elif defined(WOLFSSL_SILABS_SE_ACCEL)
 5858    return silabs_ecc_make_key(key, keysize);
 5859#elif defined(WOLFSSL_KCAPI_ECC)
 5860
 5861    err = KcapiEcc_MakeKey(key, keysize, curve_id);
 5862    (void)rng;
 5863
 5864#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 5865    if (xil_curve_type[key->dp->id] == 0)
 5866        return ECC_CURVE_OID_E;
 5867
 5868    err = wc_RNG_GenerateBlock(rng, key->privKey, key->dp->size);
 5869    if (err)
 5870        return err;
 5871    /* Make sure that private key is max. 521 bits */
 5872    if (key->dp->size == 66)
 5873        key->privKey[65] &= 0x1U;
 5874
 5875    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), key->dp->size);
 5876
 5877    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
 5878                                        2 * key->dp->size);
 5879
 5880    err = XSecure_EllipticGenerateKey(&(key->xSec.cinst),
 5881                                      xil_curve_type[key->dp->id],
 5882                                      XIL_CAST_U64(key->privKey),
 5883                                      XIL_CAST_U64(key->keyRaw));
 5884    if (err != XST_SUCCESS) {
 5885        WOLFSSL_XIL_ERROR("Generate ECC key failed", err);
 5886        err = WC_HW_E;
 5887    }
 5888
 5889    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
 5890                                        2 * key->dp->size);
 5891
 5892#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
 5893    if (err == 0)
 5894        err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
 5895                                          xil_curve_type[key->dp->id],
 5896                                          XIL_CAST_U64(key->keyRaw));
 5897#endif
 5898
 5899    if (err == 0)
 5900        err = xil_mpi_import(key->pubkey.x, key->keyRaw, key->dp->size,
 5901                             key->heap);
 5902    if (err == 0)
 5903        err = xil_mpi_import(key->pubkey.y, key->keyRaw + key->dp->size,
 5904                             key->dp->size, key->heap);
 5905    if (err == 0)
 5906        err = xil_mpi_import(key->k, key->privKey, key->dp->size,
 5907                             key->heap);
 5908#ifdef WOLFSSL_ECC_BLIND_K
 5909    if (err == 0)
 5910        err = ecc_blind_k_rng(key, rng);
 5911#endif
 5912    if (err == 0)
 5913        err = mp_set(key->pubkey.z, 1);
 5914    if (err) {
 5915        key->privKey = NULL;
 5916        XMEMSET(key->keyRaw, 0, sizeof(key->keyRaw));
 5917        return err;
 5918    }
 5919
 5920    key->type = ECC_PRIVATEKEY;
 5921
 5922#else
 5923
 5924#ifdef WOLFSSL_HAVE_SP_ECC
 5925
 5926#ifndef WOLFSSL_SP_NO_256
 5927    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
 5928    #ifndef WC_ECC_NONBLOCK
 5929        err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
 5930    #else
 5931        if (key->nb_ctx) {
 5932            err = sp_ecc_make_key_256_nb(&key->nb_ctx->sp_ctx, rng, key->k,
 5933                                         &key->pubkey, key->heap);
 5934        }
 5935        else {
 5936        #ifdef WC_ECC_NONBLOCK_ONLY
 5937            do { /* perform blocking call to non-blocking function */
 5938                err = sp_ecc_make_key_256_nb(&nb_ctx.sp_ctx, rng, key->k,
 5939                                             &key->pubkey, key->heap);
 5940            } while (err == FP_WOULDBLOCK);
 5941        #else
 5942            err = sp_ecc_make_key_256(rng, key->k, &key->pubkey, key->heap);
 5943        #endif /* WC_ECC_NONBLOCK_ONLY */
 5944        }
 5945    #endif /* !WC_ECC_NONBLOCK */
 5946
 5947        if (err == MP_OKAY) {
 5948            key->type = ECC_PRIVATEKEY;
 5949        }
 5950    }
 5951    else
 5952#endif /* !WOLFSSL_SP_NO_256 */
 5953#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 5954    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
 5955        err = sp_ecc_make_key_sm2_256(rng, key->k, &key->pubkey, key->heap);
 5956        if (err == MP_OKAY) {
 5957            key->type = ECC_PRIVATEKEY;
 5958        }
 5959    }
 5960    else
 5961#endif
 5962#ifdef WOLFSSL_SP_384
 5963    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
 5964    #ifndef WC_ECC_NONBLOCK
 5965        err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
 5966    #else
 5967        if (key->nb_ctx) {
 5968            err = sp_ecc_make_key_384_nb(&key->nb_ctx->sp_ctx, rng, key->k,
 5969                                         &key->pubkey, key->heap);
 5970        }
 5971        else {
 5972        #ifdef WC_ECC_NONBLOCK_ONLY
 5973            do { /* perform blocking call to non-blocking function */
 5974                err = sp_ecc_make_key_384_nb(&nb_ctx.sp_ctx, rng, key->k,
 5975                                             &key->pubkey, key->heap);
 5976            } while (err == FP_WOULDBLOCK);
 5977        #else
 5978            err = sp_ecc_make_key_384(rng, key->k, &key->pubkey, key->heap);
 5979        #endif /* WC_ECC_NONBLOCK_ONLY */
 5980        }
 5981    #endif /* !WC_ECC_NONBLOCK */
 5982
 5983        if (err == MP_OKAY) {
 5984            key->type = ECC_PRIVATEKEY;
 5985        }
 5986    }
 5987    else
 5988#endif /* WOLFSSL_SP_384 */
 5989#ifdef WOLFSSL_SP_521
 5990    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
 5991    #ifndef WC_ECC_NONBLOCK
 5992        err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
 5993    #else
 5994        if (key->nb_ctx) {
 5995            err = sp_ecc_make_key_521_nb(&key->nb_ctx->sp_ctx, rng, key->k,
 5996                                         &key->pubkey, key->heap);
 5997        }
 5998        else {
 5999        #ifdef WC_ECC_NONBLOCK_ONLY
 6000            do { /* perform blocking call to non-blocking function */
 6001                err = sp_ecc_make_key_521_nb(&nb_ctx.sp_ctx, rng, key->k,
 6002                                             &key->pubkey, key->heap);
 6003            } while (err == FP_WOULDBLOCK);
 6004        #else
 6005            err = sp_ecc_make_key_521(rng, key->k, &key->pubkey, key->heap);
 6006        #endif /* WC_ECC_NONBLOCK_ONLY */
 6007        }
 6008    #endif /* !WC_ECC_NONBLOCK */
 6009
 6010        if (err == MP_OKAY) {
 6011            key->type = ECC_PRIVATEKEY;
 6012        }
 6013    }
 6014    else
 6015#endif /* WOLFSSL_SP_521 */
 6016#endif /* WOLFSSL_HAVE_SP_ECC */
 6017
 6018   { /* software key gen */
 6019#if defined(WOLFSSL_SP_MATH)
 6020        err = WC_KEY_SIZE_E;
 6021#else
 6022        DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
 6023
 6024        /* setup the key variables */
 6025#ifndef ALT_ECC_SIZE
 6026        err = mp_init(key->k);
 6027#else
 6028        err = 0;
 6029        key->k = (mp_int*)key->ka;
 6030        alt_fp_init(key->k);
 6031#endif
 6032
 6033        /* load curve info */
 6034        if (err == MP_OKAY) {
 6035            ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
 6036            if (err != MP_OKAY) {
 6037                WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
 6038            }
 6039        }
 6040
 6041        if (err == MP_OKAY) {
 6042            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
 6043            if (err != MP_OKAY) {
 6044                WOLFSSL_MSG("wc_ecc_curve_load failed");
 6045            }
 6046        }
 6047
 6048        /* generate k */
 6049        if (err == MP_OKAY) {
 6050            err = wc_ecc_gen_k(rng, key->dp->size, key->k, curve->order);
 6051            if (err != MP_OKAY) {
 6052                WOLFSSL_MSG("wc_ecc_gen_k failed");
 6053            }
 6054        }
 6055
 6056        /* generate public key from k */
 6057        if (err == MP_OKAY) {
 6058            err = ecc_make_pub_ex(key, curve, NULL, rng);
 6059            if (err != MP_OKAY) {
 6060                WOLFSSL_MSG("ecc_make_pub_ex failed");
 6061            }
 6062        }
 6063
 6064        if (err == MP_OKAY
 6065        #ifdef WOLFSSL_ASYNC_CRYPT
 6066            || err == WC_NO_ERR_TRACE(WC_PENDING_E)
 6067        #endif
 6068        ) {
 6069            key->type = ECC_PRIVATEKEY;
 6070        }
 6071        else {
 6072            /* cleanup these on failure case only */
 6073            mp_forcezero(key->k);
 6074        }
 6075
 6076        /* cleanup allocations */
 6077        wc_ecc_curve_free(curve);
 6078        FREE_CURVE_SPECS();
 6079#endif /* WOLFSSL_SP_MATH */
 6080    }
 6081
 6082#ifdef HAVE_WOLF_BIGINT
 6083    if (err == MP_OKAY)
 6084         err = wc_mp_to_bigint(key->k, &key->k->raw);
 6085    if (err == MP_OKAY)
 6086         err = wc_mp_to_bigint(key->pubkey.x, &key->pubkey.x->raw);
 6087    if (err == MP_OKAY)
 6088         err = wc_mp_to_bigint(key->pubkey.y, &key->pubkey.y->raw);
 6089    if (err == MP_OKAY)
 6090         err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
 6091#endif
 6092
 6093#ifdef WOLFSSL_ECC_BLIND_K
 6094    if (err == MP_OKAY)
 6095        err = ecc_blind_k_rng(key, rng);
 6096#endif
 6097
 6098#endif /* HAVE_ECC_MAKE_PUB */
 6099
 6100    return err;
 6101#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
 6102}
 6103
 6104
 6105int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
 6106                        int flags)
 6107{
 6108    int err;
 6109
 6110    SAVE_VECTOR_REGISTERS(return _svr_ret;);
 6111
 6112    err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
 6113
 6114#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
 6115    !defined(WOLFSSL_KCAPI_ECC)
 6116    if (err == MP_OKAY) {
 6117        err = _ecc_validate_public_key(key, 0, 0);
 6118    }
 6119    if (err == MP_OKAY
 6120#if defined(WOLF_CRYPTO_CB)
 6121        /* even if WOLF_CRYPTO_CB we generate the key if the devId is invalid */
 6122        && key->devId == INVALID_DEVID
 6123#endif
 6124        ) {
 6125        err = _ecc_pairwise_consistency_test(key, rng);
 6126    }
 6127    /* FIPS 140-3 IG 10.3.A (TE10.35.02): a key pair that fails post-
 6128     * generation validation or PCT must be rendered unusable so a caller
 6129     * that ignores the return value cannot use it. */
 6130    if (err != MP_OKAY) {
 6131        wc_ecc_free(key);
 6132    }
 6133#endif
 6134
 6135    RESTORE_VECTOR_REGISTERS();
 6136
 6137    return err;
 6138}
 6139
 6140WOLFSSL_ABI
 6141int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
 6142{
 6143    return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
 6144}
 6145
 6146#ifdef ECC_DUMP_OID
 6147/* Optional dump of encoded OID for adding new curves */
 6148static int mOidDumpDone;
 6149static void wc_ecc_dump_oids(void)
 6150{
 6151    int x;
 6152
 6153    if (mOidDumpDone) {
 6154        return;
 6155    }
 6156
 6157    /* find matching OID sum (based on encoded value) */
 6158    for (x = 0; ecc_sets[x].size != 0; x++) {
 6159        int i;
 6160        byte* oid;
 6161        word32 oidSz, sum = 0;
 6162
 6163        printf("ECC %s (%d):\n", ecc_sets[x].name, x);
 6164
 6165    #ifdef HAVE_OID_ENCODING
 6166        byte oidEnc[ECC_MAX_OID_LEN];
 6167
 6168        oid = oidEnc;
 6169        oidSz = ECC_MAX_OID_LEN;
 6170
 6171        printf("OID: ");
 6172        for (i = 0; i < (int)ecc_sets[x].oidSz; i++) {
 6173            printf("%d.", ecc_sets[x].oid[i]);
 6174        }
 6175        printf("\n");
 6176
 6177        EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz, oidEnc, &oidSz);
 6178    #else
 6179        oid = (byte*)ecc_sets[x].oid;
 6180        oidSz = ecc_sets[x].oidSz;
 6181    #endif
 6182
 6183        printf("OID Encoded: ");
 6184        for (i = 0; i < (int)oidSz; i++) {
 6185            printf("0x%02X,", oid[i]);
 6186        }
 6187        printf("\n");
 6188
 6189        for (i = 0; i < (int)oidSz; i++) {
 6190            sum += oid[i];
 6191        }
 6192        printf("Sum: %u\n", sum);
 6193
 6194        /* validate sum */
 6195        if (ecc_sets[x].oidSum != sum) {
 6196            fprintf(stderr, "  Sum %u Not Valid!\n", ecc_sets[x].oidSum);
 6197        }
 6198    }
 6199    mOidDumpDone = 1;
 6200}
 6201#endif /* ECC_DUMP_OID */
 6202
 6203
 6204WOLFSSL_ABI
 6205ecc_key* wc_ecc_key_new(void* heap)
 6206{
 6207    int devId = INVALID_DEVID;
 6208    ecc_key* key;
 6209
 6210#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
 6211    /* assume all keys are using CAAM for ECC unless explicitly set otherwise */
 6212    devId = WOLFSSL_CAAM_DEVID;
 6213#endif
 6214    key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
 6215    if (key) {
 6216        if (wc_ecc_init_ex(key, heap, devId) != 0) {
 6217            XFREE(key, heap, DYNAMIC_TYPE_ECC);
 6218            key = NULL;
 6219        }
 6220    }
 6221
 6222    return key;
 6223}
 6224
 6225
 6226WOLFSSL_ABI
 6227void wc_ecc_key_free(ecc_key* key)
 6228{
 6229    if (key) {
 6230        void* heap = key->heap;
 6231
 6232        wc_ecc_free(key);
 6233        ForceZero(key, sizeof(ecc_key));
 6234        XFREE(key, heap, DYNAMIC_TYPE_ECC);
 6235        (void)heap;
 6236    }
 6237}
 6238
 6239
 6240/**
 6241 Make a new ECC key
 6242 rng          An active RNG state
 6243 keysize      The keysize for the new key (in octets from 20 to 65 bytes)
 6244 key          [out] Destination of the newly created key
 6245 return       MP_OKAY if successful,
 6246 upon error all allocated memory will be freed
 6247 */
 6248WOLFSSL_ABI
 6249int wc_ecc_make_key(WC_RNG* rng, int keysize, ecc_key* key)
 6250{
 6251    return wc_ecc_make_key_ex(rng, keysize, key, ECC_CURVE_DEF);
 6252}
 6253
 6254/* Setup dynamic pointers if using normal math for proper freeing */
 6255WOLFSSL_ABI
 6256int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
 6257{
 6258    int ret      = 0;
 6259
 6260    if (key == NULL) {
 6261        return BAD_FUNC_ARG;
 6262    }
 6263
 6264#ifdef ECC_DUMP_OID
 6265    wc_ecc_dump_oids();
 6266#endif
 6267
 6268    XMEMSET(key, 0, sizeof(ecc_key));
 6269    key->state = ECC_STATE_NONE;
 6270
 6271#if defined(PLUTON_CRYPTO_ECC) || defined(WOLF_CRYPTO_CB)
 6272    key->devId = devId;
 6273#else
 6274    (void)devId;
 6275#endif
 6276
 6277#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
 6278    defined(WOLFSSL_MICROCHIP_TA100)
 6279    key->slot = ATECC_INVALID_SLOT;
 6280#ifdef WOLFSSL_MICROCHIP_TA100
 6281    /* TA100 needs pubkey initialized to populate after genkey. With
 6282     * ALT_ECC_SIZE the x/y/z pointers must first be aimed at the inline
 6283     * xyz[] storage; mp_init_multi otherwise dereferences NULL. */
 6284#ifdef ALT_ECC_SIZE
 6285    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
 6286    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
 6287    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
 6288    alt_fp_init(key->pubkey.x);
 6289    alt_fp_init(key->pubkey.y);
 6290    alt_fp_init(key->pubkey.z);
 6291#else
 6292    ret = mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z,
 6293                        NULL, NULL, NULL);
 6294    if (ret != MP_OKAY) {
 6295        return MEMORY_E;
 6296    }
 6297#endif
 6298#endif
 6299#else
 6300#if defined(WOLFSSL_KCAPI_ECC)
 6301    key->handle = NULL;
 6302#endif
 6303#ifdef ALT_ECC_SIZE
 6304    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
 6305    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
 6306    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
 6307    alt_fp_init(key->pubkey.x);
 6308    alt_fp_init(key->pubkey.y);
 6309    alt_fp_init(key->pubkey.z);
 6310    key->k = (mp_int*)key->ka;
 6311    alt_fp_init(key->k);
 6312#ifdef WOLFSSL_ECC_BLIND_K
 6313    key->kb = (mp_int*)key->kba;
 6314    key->ku = (mp_int*)key->kia;
 6315    alt_fp_init(key->kb);
 6316    alt_fp_init(key->ku);
 6317#endif
 6318#else
 6319    ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
 6320#ifndef WOLFSSL_ECC_BLIND_K
 6321                                                                      NULL, NULL
 6322#else
 6323                                                                key->kb, key->ku
 6324#endif
 6325                        );
 6326    if (ret != MP_OKAY) {
 6327        return MEMORY_E;
 6328    }
 6329#endif /* ALT_ECC_SIZE */
 6330#ifdef WOLFSSL_ECC_BLIND_K
 6331    mp_forcezero(key->kb);
 6332#endif
 6333#endif /* WOLFSSL_ATECC508A */
 6334#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
 6335     defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 6336     defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)) && \
 6337     defined(WOLFSSL_NO_MALLOC)
 6338    ret = mp_init(key->sign_k);
 6339    if (ret != MP_OKAY) {
 6340        return MEMORY_E;
 6341    }
 6342#endif
 6343
 6344#ifdef WOLFSSL_HEAP_TEST
 6345    (void)heap;
 6346    key->heap = (void*)WOLFSSL_HEAP_TEST;
 6347#else
 6348    key->heap = heap;
 6349#endif
 6350
 6351#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 6352    #ifdef WOLF_CRYPTO_CB
 6353    /* prefer crypto callback */
 6354    if (key->devId != INVALID_DEVID)
 6355    #endif
 6356    {
 6357        /* handle as async */
 6358        ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC,
 6359                                                        key->heap, devId);
 6360    }
 6361    if (ret != 0)
 6362        return ret;
 6363#endif
 6364
 6365#if defined(WOLFSSL_DSP)
 6366    key->handle = -1;
 6367#endif
 6368
 6369#ifdef WOLFSSL_SE050
 6370    key->keyId = 0;
 6371    key->keyIdSet = 0;
 6372#endif
 6373
 6374#ifdef WOLFSSL_CHECK_MEM_ZERO
 6375    mp_memzero_add("ECC k", key->k);
 6376#ifdef WOLFSSL_ECC_BLIND_K
 6377    mp_memzero_add("ECC kb", key->kb);
 6378    mp_memzero_add("ECC ku", key->ku);
 6379#endif
 6380#endif
 6381
 6382#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 6383    key->privKey = key->keyRaw + (2 * ECC_MAX_CRYPTO_HW_SIZE);
 6384
 6385    if (wc_InitXsecure(&(key->xSec))) {
 6386        WOLFSSL_MSG("Can't initialize Xsecure");
 6387        return WC_HW_E;
 6388    }
 6389#endif
 6390
 6391    return ret;
 6392}
 6393
 6394WOLFSSL_ABI
 6395int wc_ecc_init(ecc_key* key)
 6396{
 6397#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
 6398    return wc_ecc_init_ex(key, NULL, WOLFSSL_CAAM_DEVID);
 6399#else
 6400    return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
 6401#endif
 6402}
 6403
 6404#ifdef WOLF_PRIVATE_KEY_ID
 6405int wc_ecc_init_id(ecc_key* key, unsigned char* id, int len, void* heap,
 6406                   int devId)
 6407{
 6408    int ret = 0;
 6409#ifdef WOLFSSL_SE050
 6410    /* SE050 TLS users store a word32 at id, need to cast back */
 6411    word32* keyPtr = NULL;
 6412#endif
 6413
 6414    if (key == NULL)
 6415        ret = BAD_FUNC_ARG;
 6416    if (ret == 0 && (len < 0 || len > ECC_MAX_ID_LEN))
 6417        ret = BUFFER_E;
 6418    if (ret == 0)
 6419        ret = wc_ecc_init_ex(key, heap, devId);
 6420    if (ret == 0 && id != NULL && len != 0) {
 6421        XMEMCPY(key->id, id, (size_t)len);
 6422        key->idLen = len;
 6423    #ifdef WOLFSSL_SE050
 6424        /* Set SE050 ID from word32, populate ecc_key with public from SE050 */
 6425        if (len == (int)sizeof(word32)) {
 6426            keyPtr = (word32*)key->id;
 6427            ret = wc_ecc_use_key_id(key, *keyPtr, 0);
 6428        }
 6429    #endif
 6430    }
 6431
 6432    return ret;
 6433}
 6434
 6435int wc_ecc_init_label(ecc_key* key, const char* label, void* heap, int devId)
 6436{
 6437    int ret = 0;
 6438    int labelLen = 0;
 6439
 6440    if (key == NULL || label == NULL)
 6441        ret = BAD_FUNC_ARG;
 6442    if (ret == 0) {
 6443        labelLen = (int)XSTRLEN(label);
 6444        if (labelLen == 0 || labelLen > ECC_MAX_LABEL_LEN)
 6445            ret = BUFFER_E;
 6446    }
 6447    if (ret == 0)
 6448        ret = wc_ecc_init_ex(key, heap, devId);
 6449    if (ret == 0) {
 6450        XMEMCPY(key->label, label, (size_t)labelLen);
 6451        key->labelLen = labelLen;
 6452    }
 6453
 6454    return ret;
 6455}
 6456#endif /* WOLF_PRIVATE_KEY_ID */
 6457
 6458int wc_ecc_set_flags(ecc_key* key, word32 flags)
 6459{
 6460    if (key == NULL) {
 6461        return BAD_FUNC_ARG;
 6462    }
 6463    key->flags |= flags;
 6464    return 0;
 6465}
 6466
 6467
 6468static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
 6469{
 6470    int err = MP_OKAY;
 6471    int orderBits;
 6472    DECLARE_CURVE_SPECS(1);
 6473
 6474    ALLOC_CURVE_SPECS(1, err);
 6475    if (err == MP_OKAY) {
 6476        err = wc_ecc_curve_load(dp, &curve, ECC_CURVE_FIELD_ORDER);
 6477    }
 6478
 6479    if (err != 0) {
 6480       FREE_CURVE_SPECS();
 6481       return err;
 6482    }
 6483    orderBits = mp_count_bits(curve->order);
 6484
 6485    wc_ecc_curve_free(curve);
 6486    FREE_CURVE_SPECS();
 6487    return orderBits;
 6488}
 6489
 6490#ifdef HAVE_ECC_SIGN
 6491
 6492#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) ||  \
 6493    defined(WOLFSSL_MICROCHIP_TA100) || \
 6494    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
 6495    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
 6496    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 6497static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
 6498    mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
 6499    ecc_key* key)
 6500{
 6501    int err;
 6502#ifdef PLUTON_CRYPTO_ECC
 6503    if (key->devId != INVALID_DEVID) /* use hardware */
 6504#endif
 6505    {
 6506    #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
 6507        !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100)
 6508        CRYS_ECDSA_SignUserContext_t sigCtxTemp;
 6509        word32 raw_sig_size = *outlen;
 6510        word32 msgLenInBytes = inlen;
 6511        CRYS_ECPKI_HASH_OpMode_t hash_mode;
 6512    #endif
 6513#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 6514#ifdef WOLFSSL_SMALL_STACK
 6515        byte* K = NULL;
 6516        byte* incopy = NULL;
 6517#else
 6518        byte K[MAX_ECC_BYTES] = {0};
 6519        byte incopy[MAX_ECC_BYTES] = {0};
 6520#endif
 6521#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 6522    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 6523        word32 Ksize;
 6524#endif
 6525#endif
 6526        word32 keysize = (word32)key->dp->size;
 6527    #ifdef PLUTON_CRYPTO_ECC
 6528        word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
 6529    #endif
 6530
 6531    #ifndef WOLFSSL_KCAPI_ECC
 6532        /* Check args */
 6533        if (keysize > ECC_MAX_CRYPTO_HW_SIZE || *outlen < keysize*2) {
 6534            return ECC_BAD_ARG_E;
 6535        }
 6536    #endif
 6537
 6538    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
 6539         defined(WOLFSSL_MICROCHIP_TA100)
 6540#if defined(WOLFSSL_MICROCHIP_TA100)
 6541        if (microchip_curve_id_for_key(key) == ECC_SECP256R1) {
 6542            (void)inlen;
 6543            /* Sign: Result is 32-bytes of R then 32-bytes of S */
 6544            err = atmel_ecc_sign(key->slot, in, out);
 6545        }
 6546        else {
 6547            /* Sign: Result is raw R||S */
 6548            err = atmel_ecc_sign_ex(key->slot, microchip_curve_id_for_key(key),
 6549                in, inlen, out);
 6550        }
 6551#else
 6552        (void)inlen;
 6553        /* Sign: Result is 32-bytes of R then 32-bytes of S */
 6554        err = atmel_ecc_sign(key->slot, in, out);
 6555#endif
 6556
 6557        if (err != 0) {
 6558           return err;
 6559        }
 6560    #elif defined(PLUTON_CRYPTO_ECC)
 6561        {
 6562            /* if the input is larger than curve order, we must truncate */
 6563            if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) {
 6564               inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
 6565            }
 6566
 6567            /* perform ECC sign */
 6568            word32 raw_sig_size = *outlen;
 6569            err = Crypto_EccSign(in, inlen, out, &raw_sig_size);
 6570            if (err != CRYPTO_RES_SUCCESS || raw_sig_size != keysize*2){
 6571               return BAD_COND_E;
 6572            }
 6573        }
 6574    #elif defined(WOLFSSL_SILABS_SE_ACCEL)
 6575        err = silabs_ecc_sign_hash(in, inlen, out, outlen, key);
 6576        if (err != 0) {
 6577               return WC_HW_E;
 6578        }
 6579    #elif defined(WOLFSSL_CRYPTOCELL)
 6580        /* truncate if hash is longer than key size */
 6581        if (msgLenInBytes > keysize) {
 6582            msgLenInBytes = keysize;
 6583        }
 6584        hash_mode = cc310_hashModeECC(msgLenInBytes);
 6585        if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
 6586            (void)cc310_hashModeECC(keysize);
 6587            /* Ignoring returned value */
 6588            hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
 6589
 6590        }
 6591
 6592        /* create signature from an input buffer using a private key*/
 6593        err = CRYS_ECDSA_Sign(&wc_rndState,
 6594                               wc_rndGenVectFunc,
 6595                               &sigCtxTemp,
 6596                               &key->ctx.privKey,
 6597                               hash_mode,
 6598                               (byte*)in,
 6599                               msgLenInBytes,
 6600                               out,
 6601                               (uint32_t*)&raw_sig_size);
 6602
 6603        if (err != SA_SILIB_RET_OK){
 6604            WOLFSSL_MSG("CRYS_ECDSA_Sign failed");
 6605            return err;
 6606        }
 6607    #elif defined(WOLFSSL_KCAPI_ECC)
 6608        err = KcapiEcc_Sign(key, in, inlen, out, *outlen);
 6609        if (err != MP_OKAY) {
 6610            return err;
 6611        }
 6612        (void)rng;
 6613    #elif defined(WOLFSSL_SE050)
 6614        err = se050_ecc_sign_hash_ex(in, inlen, r, s, out, outlen, key);
 6615        if (err != MP_OKAY) {
 6616            return err;
 6617        }
 6618        (void)rng;
 6619    #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 6620
 6621#ifdef WOLFSSL_SMALL_STACK
 6622        K = (byte*)XMALLOC(keysize, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
 6623        incopy = (byte*)XMALLOC(inlen, key->heap, DYNAMIC_TYPE_HASH_TMP);
 6624        if (K == NULL || incopy == NULL) {
 6625            XFREE(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
 6626            XFREE(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
 6627            return MEMORY_E;
 6628        }
 6629#else
 6630        if (inlen > sizeof(incopy))
 6631            return ECC_BAD_ARG_E;
 6632#endif
 6633
 6634#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 6635    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 6636        err = deterministic_sign_helper(in, inlen, key);
 6637        if (err)
 6638            return err;
 6639        Ksize = mp_unsigned_bin_size(key->sign_k);
 6640        if (Ksize > keysize) {
 6641            err = BUFFER_E;
 6642            goto error_out;
 6643        }
 6644        err = mp_to_unsigned_bin(key->sign_k, K);
 6645        if (err)
 6646            goto error_out;
 6647        mp_reverse(K, Ksize);
 6648#else
 6649        err = wc_RNG_GenerateBlock(rng, K, keysize);
 6650        if (err)
 6651            goto error_out;
 6652        /* Make sure that K is max. 521 bits */
 6653        if (keysize == 66)
 6654            K[65] &= 0x1;
 6655#endif
 6656        buf_reverse(incopy, in, inlen < keysize ? inlen : keysize);
 6657        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(incopy), keysize);
 6658        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->privKey), keysize);
 6659        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(K), keysize);
 6660
 6661        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
 6662
 6663        err = XSecure_EllipticGenerateSign(&(key->xSec.cinst),
 6664                                           xil_curve_type[key->dp->id],
 6665                                           XIL_CAST_U64(incopy), keysize,
 6666                                           XIL_CAST_U64(key->privKey),
 6667                                           XIL_CAST_U64(K),
 6668                                           XIL_CAST_U64(out));
 6669        if (err) {
 6670            WOLFSSL_XIL_ERROR("Generate ECC signature failed", err);
 6671            err = WC_HW_E;
 6672        }
 6673
 6674        WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(out), keysize * 2);
 6675        mp_reverse(&out[0], keysize);
 6676        mp_reverse(&out[keysize], keysize);
 6677
 6678error_out:
 6679        ForceZero(K, MAX_ECC_BYTES);
 6680        WC_FREE_VAR_EX(incopy, key->heap, DYNAMIC_TYPE_HASH_TMP);
 6681        WC_FREE_VAR_EX(K, key->heap, DYNAMIC_TYPE_PRIVATE_KEY);
 6682        if (err) {
 6683            ForceZero(out, keysize * 2);
 6684            return err;
 6685        }
 6686    #endif /* HW-specific #if-#elif chain */
 6687
 6688    #ifndef WOLFSSL_SE050
 6689        /* Load R and S, SE050 does this in port layer */
 6690        err = mp_read_unsigned_bin(r, &out[0], keysize);
 6691        if (err != MP_OKAY) {
 6692            return err;
 6693        }
 6694        err = mp_read_unsigned_bin(s, &out[keysize], keysize);
 6695        if (err != MP_OKAY) {
 6696            return err;
 6697        }
 6698    #endif
 6699
 6700        /* Check for zeros */
 6701        if (mp_iszero(r) || mp_iszero(s)) {
 6702            return MP_ZERO_E;
 6703        }
 6704    }
 6705#ifdef PLUTON_CRYPTO_ECC
 6706    else {
 6707        err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
 6708    }
 6709#endif
 6710    (void)rng;
 6711
 6712    return err;
 6713}
 6714#endif /* WOLFSSL_ATECC508A || PLUTON_CRYPTO_ECC || WOLFSSL_CRYPTOCELL */
 6715
 6716#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 6717static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out,
 6718    word32 *outlen, WC_RNG* rng, ecc_key* key)
 6719{
 6720    int err;
 6721    mp_int *r = NULL, *s = NULL;
 6722
 6723    if (in == NULL || out == NULL || outlen == NULL || key == NULL ||
 6724                                                                rng == NULL) {
 6725        return ECC_BAD_ARG_E;
 6726    }
 6727
 6728    err = wc_ecc_alloc_async(key);
 6729    if (err != 0) {
 6730        return err;
 6731    }
 6732    r = key->r;
 6733    s = key->s;
 6734
 6735    switch (key->state) {
 6736        case ECC_STATE_NONE:
 6737        case ECC_STATE_SIGN_DO:
 6738            key->state = ECC_STATE_SIGN_DO;
 6739
 6740            if ((err = mp_init_multi(r, s, NULL, NULL, NULL, NULL)) != MP_OKAY){
 6741                break;
 6742            }
 6743
 6744            err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
 6745            if (err < 0) {
 6746                break;
 6747            }
 6748
 6749            FALL_THROUGH;
 6750
 6751        case ECC_STATE_SIGN_ENCODE:
 6752            key->state = ECC_STATE_SIGN_ENCODE;
 6753
 6754            if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
 6755                #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH)
 6756                    DECLARE_CURVE_SPECS(1);
 6757                    ALLOC_CURVE_SPECS(1, err);
 6758                    if (err != MP_OKAY) {
 6759                        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
 6760                        break;
 6761                    }
 6762
 6763                    /* get curve order */
 6764                    err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
 6765                #endif
 6766
 6767                #ifdef HAVE_CAVIUM_V
 6768                    /* Nitrox requires r and s in sep buffer, so split it */
 6769                    NitroxEccRsSplit(key, &r->raw, &s->raw);
 6770                #endif
 6771                #ifndef WOLFSSL_ASYNC_CRYPT_SW
 6772                    /* only do this if not software, since it overwrites result */
 6773                    wc_bigint_to_mp(&r->raw, r);
 6774                    wc_bigint_to_mp(&s->raw, s);
 6775
 6776                /* if using a curve with cofactor != 1 then reduce by mod order */
 6777                #ifdef HAVE_ECC_CDH
 6778                    /* if r is not less than order than reduce */
 6779                    if (err == 0 && mp_count_bits(r) > mp_count_bits(curve->order)) {
 6780                        err = mp_mod(r, curve->order, r);
 6781                    }
 6782                    wc_ecc_curve_free(curve);
 6783                    FREE_CURVE_SPECS();
 6784                #endif
 6785                #endif /* !WOLFSSL_ASYNC_CRYPT_SW */
 6786            }
 6787
 6788            /* encoded with DSA header */
 6789            if (err == 0) {
 6790                err = StoreECC_DSA_Sig(out, outlen, r, s);
 6791            }
 6792
 6793            /* done with R/S */
 6794            mp_clear(r);
 6795            mp_clear(s);
 6796            break;
 6797
 6798        default:
 6799            err = BAD_STATE_E;
 6800            break;
 6801    }
 6802
 6803    /* if async pending then return and skip done cleanup below */
 6804    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
 6805        key->state++;
 6806        return err;
 6807    }
 6808
 6809    /* cleanup */
 6810    wc_ecc_free_async(key);
 6811    key->state = ECC_STATE_NONE;
 6812
 6813    return err;
 6814}
 6815#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
 6816
 6817/**
 6818 Sign a message digest
 6819 in        The message digest to sign
 6820 inlen     The length of the digest
 6821 out       [out] The destination for the signature
 6822 outlen    [in/out] The max size and resulting size of the signature
 6823 key       A private ECC key
 6824 return    MP_OKAY if successful
 6825 */
 6826WOLFSSL_ABI
 6827int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
 6828                     WC_RNG* rng, ecc_key* key)
 6829{
 6830    int err;
 6831#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(WC_ASYNC_ENABLE_ECC)
 6832    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
 6833    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
 6834#endif
 6835#ifdef NO_ASN
 6836    word32 keySz;
 6837#endif
 6838
 6839    if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
 6840        return ECC_BAD_ARG_E;
 6841    }
 6842    if ((inlen > WC_MAX_DIGEST_SIZE) ||
 6843        (inlen < WC_MIN_DIGEST_SIZE))
 6844    {
 6845        return BAD_LENGTH_E;
 6846    }
 6847
 6848#ifdef WOLF_CRYPTO_CB
 6849    #ifndef WOLF_CRYPTO_CB_FIND
 6850    if (key->devId != INVALID_DEVID)
 6851    #endif
 6852    {
 6853        err = wc_CryptoCb_EccSign(in, inlen, out, outlen, rng, key);
 6854        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 6855            return err;
 6856        /* fall-through when unavailable */
 6857    }
 6858#endif
 6859
 6860#ifdef WOLF_CRYPTO_CB_ONLY_ECC
 6861    (void)rng;
 6862    (void)inlen;
 6863    (void)s;
 6864    (void)r;
 6865    (void)err;
 6866    return NO_VALID_DEVID;
 6867#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
 6868    if (rng == NULL) {
 6869        WOLFSSL_MSG("ECC sign RNG missing");
 6870        return ECC_BAD_ARG_E;
 6871    }
 6872
 6873#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 6874    /* handle async cases */
 6875    err = wc_ecc_sign_hash_async(in, inlen, out, outlen, rng, key);
 6876#else
 6877
 6878    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
 6879    #ifdef MP_INT_SIZE_CHECK_NULL
 6880    if (r == NULL)
 6881        return MEMORY_E;
 6882    #endif
 6883    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
 6884    #ifdef MP_INT_SIZE_CHECK_NULL
 6885    if (s == NULL) {
 6886        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 6887        return MEMORY_E;
 6888    }
 6889    #endif
 6890
 6891    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 6892    if (err != 0) {
 6893        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
 6894        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 6895        return err;
 6896    }
 6897    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 6898    if (err != 0) {
 6899        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
 6900        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 6901        return err;
 6902    }
 6903
 6904/* hardware crypto */
 6905#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
 6906    defined(WOLFSSL_MICROCHIP_TA100) || \
 6907    defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
 6908    defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
 6909    defined(WOLFSSL_SE050) || defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 6910    err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
 6911#else
 6912    err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
 6913#endif
 6914    if (err < 0) {
 6915        mp_clear(r);
 6916        mp_clear(s);
 6917        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
 6918        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 6919        return err;
 6920    }
 6921
 6922#ifndef NO_ASN
 6923    /* encoded with DSA header */
 6924    err = StoreECC_DSA_Sig(out, outlen, r, s);
 6925#else
 6926    /* No support for DSA ASN.1 header.
 6927     * Signature will be r+s directly. */
 6928    keySz = 0;
 6929    if (key->dp != NULL) {
 6930        keySz = (word32)key->dp->size;
 6931    }
 6932    if (keySz <= 0) {
 6933        WOLFSSL_MSG("Error: ECDSA sign raw signature size");
 6934        return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
 6935    }
 6936    *outlen = keySz * 2;
 6937
 6938    /* Export signature into r,s */
 6939    mp_to_unsigned_bin_len(r, out, keySz);
 6940    mp_to_unsigned_bin_len(s, out + keySz, keySz);
 6941#endif /* !NO_ASN */
 6942
 6943    /* cleanup */
 6944    mp_clear(r);
 6945    mp_clear(s);
 6946
 6947    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
 6948    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 6949#endif /* WOLFSSL_ASYNC_CRYPT */
 6950    return err;
 6951#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
 6952}
 6953
 6954#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 6955    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 6956/* returns MP_OKAY on success */
 6957static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
 6958{
 6959    int err = MP_OKAY;
 6960    DECLARE_CURVE_SPECS(1);
 6961    ALLOC_CURVE_SPECS(1, err);
 6962
 6963    /* get curve order */
 6964    if (err == MP_OKAY) {
 6965        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
 6966    }
 6967
 6968    if (err == MP_OKAY) {
 6969    #ifndef WOLFSSL_NO_MALLOC
 6970        /* if key->sign_k is NULL then create a buffer for the mp_int
 6971         * if not NULL then assume the user correctly set deterministic flag and
 6972         *    that the key->sign_k holds a previously malloc'd mp_int buffer */
 6973        if (key->sign_k == NULL) {
 6974            key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
 6975                                                            DYNAMIC_TYPE_ECC);
 6976            if (key->sign_k != NULL) {
 6977                err = mp_init(key->sign_k);
 6978                if (err != MP_OKAY) {
 6979                    XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
 6980                    key->sign_k = NULL;
 6981                }
 6982            }
 6983        }
 6984        if (key->sign_k != NULL) {
 6985            if (wc_ecc_gen_deterministic_k(in, inlen,
 6986                        key->hashType, ecc_get_k(key), key->sign_k,
 6987                        curve->order, key->heap) != 0) {
 6988                mp_free(key->sign_k);
 6989                XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
 6990                key->sign_k = NULL;
 6991                err = ECC_PRIV_KEY_E;
 6992            }
 6993        #ifdef WOLFSSL_CHECK_MEM_ZERO
 6994            else {
 6995                mp_memzero_add("deterministic_sign_helper sign_k", key->sign_k);
 6996            }
 6997        #endif
 6998        }
 6999        else {
 7000            err = MEMORY_E;
 7001        }
 7002    #else
 7003        key->sign_k_set = 0;
 7004        if (wc_ecc_gen_deterministic_k(in, inlen, key->hashType,
 7005                ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
 7006            err = ECC_PRIV_KEY_E;
 7007        }
 7008        else {
 7009            key->sign_k_set = 1;
 7010        }
 7011    #endif
 7012    }
 7013
 7014    wc_ecc_curve_free(curve);
 7015    FREE_CURVE_SPECS();
 7016    return err;
 7017}
 7018#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K ||
 7019          WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */
 7020
 7021#if defined(WOLFSSL_STM32_PKA)
 7022int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
 7023                     ecc_key* key, mp_int *r, mp_int *s)
 7024{
 7025    return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
 7026}
 7027#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
 7028      !defined(WOLFSSL_MICROCHIP_TA100) && \
 7029      !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
 7030#ifndef WOLFSSL_SP_MATH
 7031static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
 7032                            ecc_curve_spec* curve, mp_int* e, mp_int* r,
 7033                            mp_int* s)
 7034{
 7035    int err = MP_OKAY;
 7036    int loop_check = 0;
 7037    DECL_MP_INT_SIZE_DYN(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
 7038
 7039    NEW_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
 7040#ifdef MP_INT_SIZE_CHECK_NULL
 7041    if (b == NULL)
 7042        err = MEMORY_E;
 7043#endif
 7044
 7045    if (err == MP_OKAY) {
 7046        err = INIT_MP_INT_SIZE(b, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 7047    }
 7048
 7049#ifdef WOLFSSL_CUSTOM_CURVES
 7050    /* if custom curve, apply params to pubkey */
 7051    if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
 7052        err = wc_ecc_set_custom_curve(pubkey, key->dp);
 7053    }
 7054#endif
 7055
 7056    if (err == MP_OKAY) {
 7057        /* Generate blinding value - non-zero value. */
 7058        do {
 7059            if (++loop_check > 64) {
 7060                 err = RNG_FAILURE_E;
 7061                 break;
 7062            }
 7063
 7064            err = wc_ecc_gen_k(rng, key->dp->size, b, curve->order);
 7065        }
 7066        while (err == WC_NO_ERR_TRACE(MP_ZERO_E));
 7067        loop_check = 0;
 7068    }
 7069#ifdef WOLFSSL_CHECK_MEM_ZERO
 7070    if (err == MP_OKAY) {
 7071        mp_memzero_add("ecc_sign_hash_sw b", b);
 7072    }
 7073#endif
 7074
 7075    for (; err == MP_OKAY;) {
 7076        if (++loop_check > 64) {
 7077             err = RNG_FAILURE_E;
 7078             break;
 7079        }
 7080#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
 7081           defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 7082           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 7083#ifndef WOLFSSL_NO_MALLOC
 7084        if (key->sign_k != NULL)
 7085#else
 7086        if (key->sign_k_set)
 7087#endif
 7088        {
 7089            if (loop_check > 1) {
 7090               err = RNG_FAILURE_E;
 7091               break;
 7092            }
 7093
 7094            /* use provided sign_k */
 7095            err = mp_copy(key->sign_k, pubkey->k);
 7096            if (err != MP_OKAY) break;
 7097
 7098            /* free sign_k, so only used once */
 7099            mp_forcezero(key->sign_k);
 7100#ifndef WOLFSSL_NO_MALLOC
 7101            mp_free(key->sign_k);
 7102            XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
 7103            key->sign_k = NULL;
 7104#else
 7105            key->sign_k_set = 0;
 7106#endif
 7107    #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP
 7108            loop_check = 64;
 7109    #endif
 7110    #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 7111        defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 7112            if (key->deterministic == 1) {
 7113                /* sign_k generated earlier in function for SP calls.
 7114                 * Only go through the loop once and fail if error */
 7115                loop_check = 64;
 7116            }
 7117    #endif
 7118
 7119            /* compute public key based on provided "k" */
 7120            err = ecc_make_pub_ex(pubkey, curve, NULL, rng);
 7121        }
 7122        else
 7123#endif
 7124        {
 7125            err = _ecc_make_key_ex(rng, key->dp->size, pubkey, key->dp->id,
 7126                    WC_ECC_FLAG_NONE);
 7127        }
 7128    #ifdef WOLFSSL_CHECK_MEM_ZERO
 7129        if (err == MP_OKAY) {
 7130            mp_memzero_add("ecc_sign_hash_sw k", pubkey->k);
 7131        }
 7132    #endif
 7133    #ifdef WOLFSSL_ASYNC_CRYPT
 7134        /* for async do blocking wait here */
 7135        err = wc_AsyncWait(err, &pubkey->asyncDev, WC_ASYNC_FLAG_NONE);
 7136    #endif
 7137        if (err != MP_OKAY) break;
 7138
 7139        /* find r = x1 mod n */
 7140        err = mp_mod(pubkey->pubkey.x, curve->order, r);
 7141        if (err != MP_OKAY) break;
 7142
 7143        if (mp_iszero(r) == MP_NO) {
 7144            mp_int* kp = ecc_get_k(pubkey);
 7145            mp_int* ep = kp;
 7146            mp_int* x  = ecc_get_k(key);
 7147
 7148            /* Blind after getting. */
 7149            ecc_blind_k(key, b);
 7150
 7151            /* find s = (e + xr)/k
 7152                      = b.(e/k.b + x.r/k.b) */
 7153
 7154            /* k' = k.b */
 7155            err = mp_mulmod(kp, b, curve->order, kp);
 7156            if (err != MP_OKAY) break;
 7157
 7158            /* k' = 1/k.b
 7159                  = 1/k' */
 7160            err = mp_invmod(kp, curve->order, kp);
 7161            if (err != MP_OKAY) break;
 7162
 7163            /* s = x.r */
 7164            err = mp_mulmod(x, r, curve->order, s);
 7165            if (err != MP_OKAY) break;
 7166
 7167            /* s = x.r/k.b
 7168                 = k'.s */
 7169            err = mp_mulmod(kp, s, curve->order, s);
 7170            if (err != MP_OKAY) break;
 7171
 7172            /* e' = e/k.b
 7173                  = e.k' */
 7174            err = mp_mulmod(kp, e, curve->order, ep);
 7175            if (err != MP_OKAY) break;
 7176
 7177            /* s = e/k.b + x.r/k.b = (e + x.r)/k.b
 7178                 = e' + s */
 7179            err = mp_addmod_ct(ep, s, curve->order, s);
 7180            if (err != MP_OKAY) break;
 7181
 7182            /* s = b.(e + x.r)/k.b = (e + x.r)/k
 7183                 = b.s */
 7184            err = mp_mulmod(s, b, curve->order, s);
 7185            if (err != MP_OKAY) break;
 7186
 7187            if (mp_iszero(s) == MP_NO) {
 7188                /* sign successful */
 7189                break;
 7190            }
 7191         }
 7192     #ifndef ALT_ECC_SIZE
 7193         mp_clear(pubkey->pubkey.x);
 7194         mp_clear(pubkey->pubkey.y);
 7195         mp_clear(pubkey->pubkey.z);
 7196     #endif
 7197         mp_forcezero(pubkey->k);
 7198    }
 7199    mp_forcezero(b);
 7200    FREE_MP_INT_SIZE(b, key->heap, DYNAMIC_TYPE_ECC);
 7201#if !defined(WOLFSSL_SMALL_STACK) && defined(WOLFSSL_CHECK_MEM_ZERO)
 7202    mp_memzero_check(b);
 7203#endif
 7204
 7205    return err;
 7206}
 7207#endif
 7208
 7209#ifdef WOLFSSL_HAVE_SP_ECC
 7210static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
 7211    ecc_key* key, mp_int *r, mp_int *s)
 7212{
 7213    if (key->idx != ECC_CUSTOM_IDX) {
 7214    #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \
 7215        || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 7216           defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 7217        mp_int* sign_k = key->sign_k;
 7218    #else
 7219        mp_int* sign_k = NULL;
 7220    #endif
 7221    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
 7222        /* perform blocking call to non-blocking function */
 7223        ecc_nb_ctx_t nb_ctx;
 7224        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
 7225    #endif
 7226    #ifndef WOLFSSL_SP_NO_256
 7227        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
 7228        #ifdef WC_ECC_NONBLOCK
 7229            #ifdef WC_ECC_NONBLOCK_ONLY
 7230            int err;
 7231            #endif
 7232            if (key->nb_ctx) {
 7233                return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
 7234                    ecc_get_k(key), r, s, sign_k, key->heap);
 7235            }
 7236            #ifdef WC_ECC_NONBLOCK_ONLY
 7237            do { /* perform blocking call to non-blocking function */
 7238                err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
 7239                    ecc_get_k(key), r, s, sign_k, key->heap);
 7240            } while (err == FP_WOULDBLOCK);
 7241            return err;
 7242            #endif
 7243        #endif /* WC_ECC_NONBLOCK */
 7244        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
 7245            {
 7246                int ret;
 7247                SAVE_VECTOR_REGISTERS(return _svr_ret;);
 7248                ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
 7249                                      sign_k, key->heap);
 7250                RESTORE_VECTOR_REGISTERS();
 7251                return ret;
 7252            }
 7253        #endif
 7254        }
 7255    #endif
 7256    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 7257        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
 7258            int ret;
 7259            SAVE_VECTOR_REGISTERS(return _svr_ret;);
 7260            ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
 7261                                      sign_k, key->heap);
 7262            RESTORE_VECTOR_REGISTERS();
 7263            return ret;
 7264        }
 7265    #endif
 7266    #ifdef WOLFSSL_SP_384
 7267        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
 7268        #ifdef WC_ECC_NONBLOCK
 7269            #ifdef WC_ECC_NONBLOCK_ONLY
 7270            int err;
 7271            #endif
 7272            if (key->nb_ctx) {
 7273                return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
 7274                    ecc_get_k(key), r, s, sign_k, key->heap);
 7275            }
 7276            #ifdef WC_ECC_NONBLOCK_ONLY
 7277            do { /* perform blocking call to non-blocking function */
 7278                err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
 7279                    ecc_get_k(key), r, s, sign_k, key->heap);
 7280            } while (err == FP_WOULDBLOCK);
 7281            return err;
 7282            #endif
 7283        #endif /* WC_ECC_NONBLOCK */
 7284        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
 7285            {
 7286                int ret;
 7287                SAVE_VECTOR_REGISTERS(return _svr_ret;);
 7288                ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
 7289                                      sign_k, key->heap);
 7290                RESTORE_VECTOR_REGISTERS();
 7291                return ret;
 7292            }
 7293        #endif
 7294        }
 7295    #endif
 7296    #ifdef WOLFSSL_SP_521
 7297        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
 7298        #ifdef WC_ECC_NONBLOCK
 7299            #ifdef WC_ECC_NONBLOCK_ONLY
 7300            int err;
 7301            #endif
 7302            if (key->nb_ctx) {
 7303                return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
 7304                    ecc_get_k(key), r, s, sign_k, key->heap);
 7305            }
 7306            #ifdef WC_ECC_NONBLOCK_ONLY
 7307            do { /* perform blocking call to non-blocking function */
 7308                err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
 7309                    ecc_get_k(key), r, s, sign_k, key->heap);
 7310            } while (err == FP_WOULDBLOCK);
 7311            return err;
 7312            #endif
 7313        #endif /* WC_ECC_NONBLOCK */
 7314        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
 7315            {
 7316                int ret;
 7317                SAVE_VECTOR_REGISTERS(return _svr_ret;);
 7318                ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
 7319                                      sign_k, key->heap);
 7320                RESTORE_VECTOR_REGISTERS();
 7321                return ret;
 7322            }
 7323        #endif
 7324        }
 7325    #endif
 7326        (void)sign_k;
 7327    }
 7328
 7329    /* SP doesn't support curve. */
 7330    return WC_KEY_SIZE_E;
 7331}
 7332#endif
 7333
 7334/**
 7335  Sign a message digest
 7336  in        The message digest to sign
 7337  inlen     The length of the digest
 7338  key       A private ECC key
 7339  r         [out] The destination for r component of the signature
 7340  s         [out] The destination for s component of the signature
 7341  return    MP_OKAY if successful
 7342*/
 7343int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
 7344                     ecc_key* key, mp_int *r, mp_int *s)
 7345{
 7346   int    err = 0;
 7347#ifndef WC_ALLOW_ECC_ZERO_HASH
 7348   byte hashIsZero = 0;
 7349   word32 zIdx;
 7350#endif
 7351#if !defined(WOLFSSL_SP_MATH)
 7352   mp_int* e;
 7353#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
 7354   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
 7355#endif
 7356
 7357#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
 7358    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 7359    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \
 7360    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
 7361    (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)))
 7362   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
 7363#else
 7364   DECLARE_CURVE_SPECS(1);
 7365#endif
 7366#endif /* !WOLFSSL_SP_MATH */
 7367
 7368   if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
 7369       return ECC_BAD_ARG_E;
 7370   }
 7371   if ((inlen > WC_MAX_DIGEST_SIZE) ||
 7372       (inlen < WC_MIN_DIGEST_SIZE))
 7373   {
 7374       return BAD_LENGTH_E;
 7375   }
 7376
 7377#ifndef WC_ALLOW_ECC_ZERO_HASH
 7378   /* reject all 0's hash */
 7379   for (zIdx = 0; zIdx < inlen; zIdx++)
 7380       hashIsZero |= in[zIdx];
 7381   if (hashIsZero == 0)
 7382       return ECC_BAD_ARG_E;
 7383#endif
 7384
 7385   /* is this a private key? */
 7386   if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
 7387      return ECC_BAD_ARG_E;
 7388   }
 7389
 7390   /* is the IDX valid ?  */
 7391   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
 7392      return ECC_BAD_ARG_E;
 7393   }
 7394
 7395#if defined(WOLFSSL_SP_MATH)
 7396    if (key->idx == ECC_CUSTOM_IDX || (1
 7397    #ifndef WOLFSSL_SP_NO_256
 7398         && ecc_sets[key->idx].id != ECC_SECP256R1
 7399    #endif
 7400    #ifdef WOLFSSL_SP_SM2
 7401         && ecc_sets[key->idx].id != ECC_SM2P256V1
 7402    #endif
 7403    #ifdef WOLFSSL_SP_384
 7404         && ecc_sets[key->idx].id != ECC_SECP384R1
 7405    #endif
 7406    #ifdef WOLFSSL_SP_521
 7407         && ecc_sets[key->idx].id != ECC_SECP521R1
 7408    #endif
 7409        )) {
 7410        return WC_KEY_SIZE_E;
 7411    }
 7412#endif
 7413
 7414#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 7415    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 7416    /* generate deterministic 'k' value to be used either with SP or normal */
 7417    if (key->deterministic == 1) {
 7418        if (deterministic_sign_helper(in, inlen, key)) {
 7419            WOLFSSL_MSG("Error generating deterministic k to sign");
 7420            return ECC_PRIV_KEY_E;
 7421        }
 7422    }
 7423#endif
 7424
 7425
 7426#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
 7427    defined(WOLFSSL_ASYNC_CRYPT_SW)
 7428    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
 7429        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_SIGN)) {
 7430            WC_ASYNC_SW* sw = &key->asyncDev.sw;
 7431            sw->eccSign.in = in;
 7432            sw->eccSign.inSz = inlen;
 7433            sw->eccSign.rng = rng;
 7434            sw->eccSign.key = key;
 7435            sw->eccSign.r = r;
 7436            sw->eccSign.s = s;
 7437            return WC_PENDING_E;
 7438        }
 7439    }
 7440#endif
 7441
 7442#if defined(WOLFSSL_HAVE_SP_ECC)
 7443   err = ecc_sign_hash_sp(in, inlen, rng, key, r, s);
 7444   if (err != WC_NO_ERR_TRACE(WC_KEY_SIZE_E)) {
 7445       return err;
 7446   }
 7447#else
 7448   (void)inlen;
 7449#endif
 7450
 7451#if !defined(WOLFSSL_SP_MATH)
 7452
 7453#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
 7454   err = wc_ecc_alloc_mpint(key, &key->e);
 7455   if (err != 0) {
 7456      return err;
 7457   }
 7458   e = key->e;
 7459#else
 7460   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
 7461#ifdef MP_INT_SIZE_CHECK_NULL
 7462   if (e_lcl == NULL) {
 7463      return MEMORY_E;
 7464   }
 7465#endif
 7466   e = e_lcl;
 7467#endif
 7468
 7469   /* get the hash and load it as a bignum into 'e' */
 7470   /* init the bignums */
 7471   if ((err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key))) != MP_OKAY) {
 7472      FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
 7473      return err;
 7474   }
 7475
 7476   /* load curve info */
 7477#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
 7478    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 7479    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 7480    ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
 7481    if (err == MP_OKAY)
 7482        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
 7483#else
 7484    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
 7485      (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))
 7486    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
 7487        ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
 7488        if (err == MP_OKAY)
 7489            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
 7490    }
 7491    else
 7492    #endif
 7493    {
 7494        ALLOC_CURVE_SPECS(1, err);
 7495        if (err == MP_OKAY)
 7496            err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
 7497    }
 7498#endif
 7499
 7500   /* load digest into e */
 7501   if (err == MP_OKAY) {
 7502       /* we may need to truncate if hash is longer than key size */
 7503       word32 orderBits = (word32)mp_count_bits(curve->order);
 7504
 7505       /* truncate down to byte size, may be all that's needed */
 7506       if ((WOLFSSL_BIT_SIZE * inlen) > orderBits)
 7507           inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
 7508       err = mp_read_unsigned_bin(e, in, inlen);
 7509
 7510       /* may still need bit truncation too */
 7511       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * inlen) > orderBits)
 7512           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
 7513   }
 7514
 7515   /* make up a key and export the public copy */
 7516#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 7517   if ((err == MP_OKAY) && (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC)) {
 7518   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
 7519   #ifdef HAVE_CAVIUM_V
 7520       if (NitroxEccIsCurveSupported(key))
 7521   #endif
 7522       {
 7523           word32 keySz = key->dp->size;
 7524           mp_int* k;
 7525       #ifdef HAVE_CAVIUM_V
 7526           err = wc_ecc_alloc_mpint(key, &key->signK);
 7527           if (err != 0)
 7528              return err;
 7529           k = key->signK;
 7530       #else
 7531           mp_int k_lcl;
 7532           k = &k_lcl;
 7533       #endif
 7534
 7535           err = mp_init(k);
 7536
 7537            /* make sure r and s are allocated */
 7538       #ifdef HAVE_CAVIUM_V
 7539           /* Nitrox V needs single buffer for R and S */
 7540           if (err == MP_OKAY)
 7541               err = wc_bigint_alloc(&key->r->raw, NitroxEccGetSize(key)*2);
 7542           /* Nitrox V only needs Prime and Order */
 7543           if (err == MP_OKAY)
 7544               err = wc_ecc_curve_load(key->dp, &curve,
 7545                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_ORDER));
 7546       #else
 7547           if (err == MP_OKAY)
 7548               err = wc_bigint_alloc(&key->r->raw, key->dp->size);
 7549           if (err == MP_OKAY)
 7550               err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
 7551       #endif
 7552           if (err == MP_OKAY)
 7553               err = wc_bigint_alloc(&key->s->raw, key->dp->size);
 7554
 7555           /* load e and k */
 7556           if (err == MP_OKAY)
 7557               err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
 7558           if (err == MP_OKAY)
 7559               err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw,
 7560                  keySz);
 7561           if (err == MP_OKAY)
 7562               err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
 7563           if (err == MP_OKAY)
 7564               err = wc_mp_to_bigint_sz(k, &k->raw, keySz);
 7565
 7566       #ifdef HAVE_CAVIUM_V
 7567           if (err == MP_OKAY)
 7568               err = NitroxEcdsaSign(key, &e->raw, &ecc_get_k(key)->raw,
 7569                  &k->raw, &r->raw, &s->raw, &curve->prime->raw,
 7570                  &curve->order->raw);
 7571       #else
 7572           if (err == MP_OKAY)
 7573               err = IntelQaEcdsaSign(&key->asyncDev, &e->raw,
 7574                  &ecc_get_k(key)->raw, &k->raw, &r->raw, &s->raw,
 7575                  &curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
 7576                  &curve->order->raw, &curve->Gx->raw, &curve->Gy->raw);
 7577       #endif
 7578
 7579       #ifndef HAVE_CAVIUM_V
 7580           mp_clear(e);
 7581           mp_forcezero(k);
 7582       #endif
 7583           wc_ecc_curve_free(curve);
 7584           FREE_CURVE_SPECS();
 7585
 7586           return err;
 7587       }
 7588   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
 7589   }
 7590#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
 7591
 7592   if (err == MP_OKAY) {
 7593       WC_DECLARE_VAR(pubkey, ecc_key, 1, 0);
 7594
 7595       WC_ALLOC_VAR_EX(pubkey, ecc_key, 1, key->heap, DYNAMIC_TYPE_ECC,
 7596           err=MEMORY_E);
 7597       if (WC_VAR_OK(pubkey))
 7598       {
 7599       /* don't use async for key, since we don't support async return here */
 7600           err = wc_ecc_init_ex(pubkey, key->heap, INVALID_DEVID);
 7601           if (err == MP_OKAY) {
 7602              err = ecc_sign_hash_sw(key, pubkey, rng, curve, e, r, s);
 7603              wc_ecc_free(pubkey);
 7604              WC_FREE_VAR_EX(pubkey, key->heap, DYNAMIC_TYPE_ECC);
 7605           }
 7606       }
 7607   }
 7608
 7609   mp_clear(e);
 7610   wc_ecc_curve_free(curve);
 7611   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
 7612   FREE_CURVE_SPECS();
 7613#endif /* !WOLFSSL_SP_MATH */
 7614
 7615   return err;
 7616}
 7617
 7618#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 7619    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 7620/* helper function to do HMAC operations
 7621 * returns 0 on success and updates "out" buffer
 7622 */
 7623static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz,
 7624        const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct,
 7625        byte* out, enum wc_HashType hashType, void* heap)
 7626{
 7627    WC_DECLARE_VAR(hmac, Hmac, 1, heap);
 7628    int  ret, init;
 7629
 7630    WC_ALLOC_VAR_EX(hmac, Hmac, 1, heap, DYNAMIC_TYPE_HMAC,
 7631                    return MEMORY_E);
 7632
 7633    ret = init = wc_HmacInit(hmac, heap, INVALID_DEVID);
 7634    if (ret == 0)
 7635        ret = wc_HmacSetKey(hmac, (int)hashType, K, KSz);
 7636
 7637    if (ret == 0)
 7638        ret = wc_HmacUpdate(hmac, V, VSz);
 7639
 7640    if (ret == 0 && oct != NULL)
 7641        ret = wc_HmacUpdate(hmac, oct, 1);
 7642
 7643    if (ret == 0)
 7644        ret = wc_HmacUpdate(hmac, x, xSz);
 7645
 7646    if (ret == 0)
 7647        ret = wc_HmacUpdate(hmac, h1, h1Sz);
 7648
 7649    if (ret == 0)
 7650        ret = wc_HmacFinal(hmac, out);
 7651
 7652    if (init == 0)
 7653        wc_HmacFree(hmac);
 7654
 7655    WC_FREE_VAR_EX(hmac, heap, DYNAMIC_TYPE_HMAC);
 7656    return ret;
 7657}
 7658
 7659
 7660/* Generates a deterministic key based of the message using RFC6979
 7661 * @param  [in]   hash     Hash value to sign
 7662 * @param  [in]   hashSz   Size of 'hash' buffer passed in
 7663 * @param  [in]   hashType Type of hash to use with deterministic k gen, i.e.
 7664 *                WC_HASH_TYPE_SHA256
 7665 * @param  [in]   priv     Current ECC private key set
 7666 * @param  [out]  k        An initialized mp_int to set the k value generated in
 7667 * @param  [in]   order    ECC order parameter to use with generation
 7668 * @return  0 on success.
 7669 */
 7670int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz,
 7671        enum wc_HashType hashType, mp_int* priv, mp_int* k, mp_int* order,
 7672        void* heap)
 7673{
 7674    int ret = 0;
 7675#ifndef WOLFSSL_SMALL_STACK
 7676    byte h1[MAX_ECC_BYTES];
 7677    byte V[WC_MAX_DIGEST_SIZE];
 7678    byte K[WC_MAX_DIGEST_SIZE];
 7679    byte x[MAX_ECC_BYTES];
 7680    mp_int z1[1];
 7681#else
 7682    byte *h1 = NULL;
 7683    byte *V  = NULL;
 7684    byte *K  = NULL;
 7685    byte *x  = NULL;
 7686    mp_int *z1 = NULL;
 7687#endif
 7688    word32 xSz, VSz, KSz, h1len, qLen;
 7689    byte intOct;
 7690    int qbits = 0;
 7691
 7692    if (hash == NULL || k == NULL || order == NULL) {
 7693        return BAD_FUNC_ARG;
 7694    }
 7695
 7696    if (hashSz > WC_MAX_DIGEST_SIZE) {
 7697        WOLFSSL_MSG("hash size was too large!");
 7698        return BAD_FUNC_ARG;
 7699    }
 7700
 7701    /* if none is provided then detect has type based on hash size */
 7702    if (hashType == WC_HASH_TYPE_NONE) {
 7703        if (hashSz == 64) {
 7704            hashType = WC_HASH_TYPE_SHA512;
 7705        }
 7706        else if (hashSz == 48) {
 7707            hashType = WC_HASH_TYPE_SHA384;
 7708        }
 7709        else if (hashSz == 32) {
 7710            hashType = WC_HASH_TYPE_SHA256;
 7711        }
 7712        else {
 7713            return BAD_FUNC_ARG;
 7714        }
 7715    }
 7716
 7717    if (mp_unsigned_bin_size(priv) > MAX_ECC_BYTES) {
 7718        WOLFSSL_MSG("private key larger than max expected!");
 7719        return BAD_FUNC_ARG;
 7720    }
 7721
 7722#ifdef WOLFSSL_SMALL_STACK
 7723    h1 = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_DIGEST);
 7724    if (h1 == NULL) {
 7725        ret = MEMORY_E;
 7726    }
 7727
 7728    if (ret == 0) {
 7729        V = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
 7730        if (V == NULL)
 7731            ret = MEMORY_E;
 7732    }
 7733
 7734    if (ret == 0) {
 7735        K = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
 7736        if (K == NULL)
 7737            ret = MEMORY_E;
 7738    }
 7739
 7740    if (ret == 0) {
 7741        x = (byte*)XMALLOC(MAX_ECC_BYTES, heap, DYNAMIC_TYPE_PRIVATE_KEY);
 7742        if (x == NULL)
 7743            ret = MEMORY_E;
 7744    }
 7745
 7746    if (ret == 0) {
 7747        z1 = (mp_int *)XMALLOC(sizeof(*z1), heap, DYNAMIC_TYPE_ECC_BUFFER);
 7748        if (z1 == NULL)
 7749            ret = MEMORY_E;
 7750    }
 7751
 7752    /* bail out if any error has been hit at this point */
 7753    if (ret != 0) {
 7754        XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
 7755        XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
 7756        XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
 7757        XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
 7758        return ret;
 7759    }
 7760#endif
 7761
 7762    VSz = KSz = hashSz;
 7763    qLen = xSz = h1len = (word32)mp_unsigned_bin_size(order);
 7764
 7765    /* 3.2 b. Set V = 0x01 0x01 ... */
 7766    XMEMSET(V, 0x01, VSz);
 7767
 7768    /* 3.2 c. Set K = 0x00 0x00 ... */
 7769    XMEMSET(K, 0x00, KSz);
 7770
 7771#ifdef WOLFSSL_CHECK_MEM_ZERO
 7772    wc_MemZero_Add("wc_ecc_gen_deterministic_k K", K, KSz);
 7773    wc_MemZero_Add("wc_ecc_gen_deterministic_k V", V, VSz);
 7774#endif
 7775
 7776    if (ret == 0) {
 7777        ret = mp_init(z1); /* always init z1 and free z1 */
 7778    }
 7779    if (ret == 0) {
 7780        ret = mp_to_unsigned_bin_len(priv, x, (int)qLen);
 7781    }
 7782    if (ret == 0) {
 7783    #ifdef WOLFSSL_CHECK_MEM_ZERO
 7784        wc_MemZero_Add("wc_ecc_gen_deterministic_k x", x, qLen);
 7785    #endif
 7786        qbits = mp_count_bits(order);
 7787        if (qbits < 0)
 7788            ret = MP_VAL;
 7789    }
 7790
 7791    if (ret == 0) {
 7792         /* hash truncate if too long */
 7793        if (((WOLFSSL_BIT_SIZE) * hashSz) > (word32)qbits) {
 7794            /* calculate truncated hash size using bits rounded up byte */
 7795            hashSz = ((word32)qbits + (WOLFSSL_BIT_SIZE - 1)) / WOLFSSL_BIT_SIZE;
 7796        }
 7797        ret = mp_read_unsigned_bin(z1, hash, hashSz);
 7798    }
 7799
 7800    /* bits2octets on h1 */
 7801    if (ret == 0) {
 7802        XMEMSET(h1, 0, MAX_ECC_BYTES);
 7803
 7804    #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 7805        /* mod reduce by order using conditional subtract
 7806         * RFC6979 lists a variant that uses the hash directly instead of
 7807         * doing bits2octets(H(m)), when variant macro is used avoid this
 7808         * bits2octets operation */
 7809        if (mp_cmp(z1, order) == MP_GT) {
 7810            int z1Sz;
 7811
 7812            mp_sub(z1, order, z1);
 7813            z1Sz = mp_unsigned_bin_size(z1);
 7814            if (z1Sz < 0 || z1Sz > MAX_ECC_BYTES) {
 7815                ret = BUFFER_E;
 7816            }
 7817            else {
 7818                ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
 7819            }
 7820        }
 7821        else
 7822    #endif
 7823        {
 7824            /* use original hash and keep leading 0's */
 7825            ret = mp_to_unsigned_bin_len(z1, h1, (int)h1len);
 7826        }
 7827    }
 7828    mp_free(z1);
 7829
 7830    /* 3.2 step d. K = HMAC_K(V || 0x00 || int2octests(x) || bits2octests(h1) */
 7831    if (ret == 0) {
 7832        intOct = 0x00;
 7833        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K,
 7834                hashType, heap);
 7835    }
 7836
 7837    /* 3.2 step e. V = HMAC_K(V) */
 7838    if (ret == 0) {
 7839        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
 7840                heap);
 7841    }
 7842
 7843
 7844    /* 3.2 step f. K = HMAC_K(V || 0x01 || int2octests(x) || bits2octests(h1) */
 7845    if (ret == 0) {
 7846        intOct = 0x01;
 7847        ret = _HMAC_K(K, KSz, V, VSz, h1, h1len, x, xSz, &intOct, K, hashType,
 7848                heap);
 7849    }
 7850
 7851    /* 3.2 step g. V = HMAC_K(V) */
 7852    if (ret == 0) {
 7853        ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V, hashType,
 7854                heap);
 7855    }
 7856
 7857    /* 3.2 step h. loop through the next steps until a valid value is found */
 7858    if (ret == 0 ) {
 7859        int err;
 7860
 7861        intOct = 0x00;
 7862        do {
 7863            xSz = 0; /* used as tLen */
 7864            err = 0; /* start as good until generated k is tested */
 7865
 7866            /* 3.2 step h.2 when tlen < qlen do V = HMAC_K(V); T = T || V */
 7867            while (xSz < qLen) {
 7868                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
 7869                        hashType, heap);
 7870                if (ret == 0) {
 7871                    int sz;
 7872
 7873                    sz = (int)MIN(qLen - xSz, (size_t)VSz);
 7874                    XMEMCPY(x + xSz, V, (size_t)sz);
 7875                    xSz += (word32)sz;
 7876                }
 7877                else {
 7878                    break; /* error case */
 7879                }
 7880            }
 7881
 7882            if (ret == 0) {
 7883                mp_clear(k); /* 3.2 step h.1 clear T */
 7884                ret = mp_read_unsigned_bin(k, x, xSz);
 7885            }
 7886
 7887            if ((ret == 0) && ((xSz * WOLFSSL_BIT_SIZE) != (word32)qbits)) {
 7888                /* handle odd case where shift of 'k' is needed with RFC 6979
 7889                 *  k = bits2int(T) in section 3.2 h.3 */
 7890                mp_rshb(k, ((int)xSz * WOLFSSL_BIT_SIZE) - qbits);
 7891            }
 7892
 7893            /* 3.2 step h.3 the key should be smaller than the order of base
 7894             * point */
 7895            if (ret == 0) {
 7896                if (mp_cmp(k, order) != MP_LT) {
 7897                    err = MP_VAL;
 7898                } else if (mp_iszero(k) == MP_YES) {
 7899                    /* no 0 key's */
 7900                    err = MP_ZERO_E;
 7901                }
 7902            }
 7903
 7904            /* 3.2 step h.3 if there was a problem with 'k' generated then try
 7905             * again K = HMAC_K(V || 0x00) and V = HMAC_K(V) */
 7906            if (ret == 0 && err != 0) {
 7907                ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, &intOct, K,
 7908                    hashType, heap);
 7909                if (ret == 0) {
 7910                    ret = _HMAC_K(K, KSz, V, VSz, NULL, 0, NULL, 0, NULL, V,
 7911                    hashType, heap);
 7912                }
 7913            }
 7914        } while (ret == 0 && err != 0);
 7915    }
 7916
 7917    ForceZero(x, MAX_ECC_BYTES);
 7918    ForceZero(K, WC_MAX_DIGEST_SIZE);
 7919    ForceZero(V, WC_MAX_DIGEST_SIZE);
 7920#ifdef WOLFSSL_SMALL_STACK
 7921    XFREE(z1, heap, DYNAMIC_TYPE_ECC_BUFFER);
 7922    XFREE(x, heap, DYNAMIC_TYPE_PRIVATE_KEY);
 7923    XFREE(K, heap, DYNAMIC_TYPE_ECC_BUFFER);
 7924    XFREE(V, heap, DYNAMIC_TYPE_ECC_BUFFER);
 7925    XFREE(h1, heap, DYNAMIC_TYPE_DIGEST);
 7926#elif defined(WOLFSSL_CHECK_MEM_ZERO)
 7927    wc_MemZero_Check(x, MAX_ECC_BYTES);
 7928    wc_MemZero_Check(K, WC_MAX_DIGEST_SIZE);
 7929    wc_MemZero_Check(V, WC_MAX_DIGEST_SIZE);
 7930#endif
 7931
 7932    return ret;
 7933}
 7934
 7935
 7936/* Sets the deterministic flag for 'k' generation with sign.
 7937 * returns 0 on success
 7938 */
 7939int wc_ecc_set_deterministic_ex(ecc_key* key, byte flag,
 7940                                enum wc_HashType hashType)
 7941{
 7942    if (key == NULL) {
 7943        return BAD_FUNC_ARG;
 7944    }
 7945
 7946    key->deterministic = flag ? 1 : 0;
 7947    key->hashType = hashType;
 7948    return 0;
 7949}
 7950
 7951int wc_ecc_set_deterministic(ecc_key* key, byte flag)
 7952{
 7953    return wc_ecc_set_deterministic_ex(key, flag, WC_HASH_TYPE_NONE);
 7954}
 7955
 7956#endif /* end sign_ex and deterministic sign */
 7957
 7958
 7959#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP)
 7960int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
 7961{
 7962    int ret = MP_OKAY;
 7963    DECLARE_CURVE_SPECS(1);
 7964
 7965    if (k == NULL || klen == 0 || key == NULL) {
 7966        return BAD_FUNC_ARG;
 7967    }
 7968
 7969    ALLOC_CURVE_SPECS(1, ret);
 7970    if (ret == MP_OKAY) {
 7971        ret = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
 7972    }
 7973
 7974    if (ret != 0) {
 7975        FREE_CURVE_SPECS();
 7976        return ret;
 7977    }
 7978
 7979#ifndef WOLFSSL_NO_MALLOC
 7980    if (key->sign_k == NULL) {
 7981        key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
 7982                                                            DYNAMIC_TYPE_ECC);
 7983        if (key->sign_k) {
 7984            ret = mp_init(key->sign_k);
 7985        }
 7986        else {
 7987            ret = MEMORY_E;
 7988        }
 7989    }
 7990#endif
 7991
 7992    if (ret == 0) {
 7993        ret = mp_read_unsigned_bin(key->sign_k, k, klen);
 7994    }
 7995    if (ret == 0 && mp_cmp(key->sign_k, curve->order) != MP_LT) {
 7996        ret = MP_VAL;
 7997    }
 7998#ifdef WOLFSSL_NO_MALLOC
 7999    if (ret == 0) {
 8000        key->sign_k_set = 1;
 8001    }
 8002#endif
 8003
 8004    wc_ecc_curve_free(curve);
 8005    FREE_CURVE_SPECS();
 8006    return ret;
 8007}
 8008#endif /* WOLFSSL_ECDSA_SET_K || WOLFSSL_ECDSA_SET_K_ONE_LOOP */
 8009#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL */
 8010
 8011#endif /* !HAVE_ECC_SIGN */
 8012
 8013#ifdef WOLFSSL_CUSTOM_CURVES
 8014void wc_ecc_free_curve(ecc_set_type* curve, void* heap)
 8015{
 8016#ifndef WOLFSSL_ECC_CURVE_STATIC
 8017    if (curve->prime != NULL)
 8018        XFREE((void*)(wc_ptr_t)curve->prime, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8019    if (curve->Af != NULL)
 8020        XFREE((void*)(wc_ptr_t)curve->Af, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8021    if (curve->Bf != NULL)
 8022        XFREE((void*)(wc_ptr_t)curve->Bf, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8023    if (curve->order != NULL)
 8024        XFREE((void*)(wc_ptr_t)curve->order, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8025    if (curve->Gx != NULL)
 8026        XFREE((void*)(wc_ptr_t)curve->Gx, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8027    if (curve->Gy != NULL)
 8028        XFREE((void*)(wc_ptr_t)curve->Gy, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8029#endif
 8030
 8031    XFREE((void*)curve, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8032
 8033    (void)heap;
 8034}
 8035#endif /* WOLFSSL_CUSTOM_CURVES */
 8036
 8037/**
 8038  Free an ECC key from memory
 8039  key   The key you wish to free
 8040*/
 8041WOLFSSL_ABI
 8042int wc_ecc_free(ecc_key* key)
 8043{
 8044    if (key == NULL) {
 8045        return 0;
 8046    }
 8047
 8048#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
 8049    if (key->devId != INVALID_DEVID) {
 8050        /* Best-effort HSM resource release; errors are intentionally discarded
 8051         * so that software cleanup always runs and wc_ecc_free() retains its
 8052         * ABI guarantee of returning 0 on success. */
 8053        (void)wc_CryptoCb_Free(key->devId, WC_ALGO_TYPE_PK,
 8054                         WC_PK_TYPE_EC_KEYGEN, 0, key);
 8055        /* always continue to software cleanup */
 8056    }
 8057#endif
 8058
 8059#if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
 8060    defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
 8061    defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT)
 8062#ifndef WOLFSSL_NO_MALLOC
 8063    if (key->sign_k != NULL)
 8064#endif
 8065    {
 8066        mp_forcezero(key->sign_k);
 8067        mp_free(key->sign_k);
 8068#ifndef WOLFSSL_NO_MALLOC
 8069        XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
 8070        key->sign_k = NULL;
 8071#endif
 8072    }
 8073#endif
 8074
 8075#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 8076    #ifdef WC_ASYNC_ENABLE_ECC
 8077    wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
 8078    #endif
 8079    wc_ecc_free_async(key);
 8080#endif
 8081
 8082#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
 8083    /* free secure memory */
 8084    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
 8085         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
 8086       caamFreePart(key->partNum);
 8087    }
 8088#endif
 8089
 8090#ifdef WOLFSSL_SE050
 8091#ifdef WOLFSSL_SE050_AUTO_ERASE
 8092    wc_se050_erase_object(key->keyId);
 8093#endif
 8094    se050_ecc_free_key(key);
 8095#endif
 8096
 8097#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
 8098    defined(WOLFSSL_MICROCHIP_TA100)
 8099    atmel_ecc_free(key->slot);
 8100    key->slot = ATECC_INVALID_SLOT;
 8101#endif /* WOLFSSL_ATECC508A */
 8102
 8103#ifdef WOLFSSL_KCAPI_ECC
 8104    KcapiEcc_Free(key);
 8105#endif
 8106
 8107#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 8108    key->privKey = NULL;
 8109    ForceZero(key->keyRaw, sizeof(key->keyRaw));
 8110    ForceZero(&key->xSec, sizeof(key->xSec));
 8111#endif
 8112
 8113#ifdef WOLFSSL_MAXQ10XX_CRYPTO
 8114    wc_MAXQ10XX_EccFree(key);
 8115#endif
 8116
 8117    mp_clear(key->pubkey.x);
 8118    mp_clear(key->pubkey.y);
 8119    mp_clear(key->pubkey.z);
 8120
 8121#ifdef ALT_ECC_SIZE
 8122    if (key->k)
 8123#endif
 8124        mp_forcezero(key->k);
 8125#ifdef WOLFSSL_ECC_BLIND_K
 8126#ifdef ALT_ECC_SIZE
 8127    if (key->kb)
 8128#endif
 8129        mp_forcezero(key->kb);
 8130#ifdef ALT_ECC_SIZE
 8131    if (key->ku)
 8132#endif
 8133        mp_forcezero(key->ku);
 8134#endif
 8135
 8136#ifdef WOLFSSL_CUSTOM_CURVES
 8137    if (key->deallocSet && key->dp != NULL) {
 8138        wc_ecc_free_curve((ecc_set_type *)(wc_ptr_t)key->dp, key->heap);
 8139        key->dp = NULL;
 8140    }
 8141#endif
 8142
 8143#ifdef WOLFSSL_CHECK_MEM_ZERO
 8144    wc_MemZero_Check(key, sizeof(ecc_key));
 8145#endif
 8146
 8147    return 0;
 8148}
 8149
 8150#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
 8151    !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SP_MATH) && \
 8152    (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
 8153      defined(WOLFSSL_IMXRT1170_CAAM))
 8154/* Handles add failure cases:
 8155 *
 8156 * Before add:
 8157 *   Case 1: A is infinity
 8158 *        -> Copy B into result.
 8159 *   Case 2: B is infinity
 8160 *        -> Copy A into result.
 8161 *   Case 3: x and z are the same in A and B (same x value in affine)
 8162 *     Case 3a: y values the same - same point
 8163 *           -> Double instead of add.
 8164 *     Case 3b: y values different - negative of the other when points on curve
 8165 *           -> Need to set result to infinity.
 8166 *
 8167 * After add:
 8168 *   Case 1: A and B are the same point (maybe different z)
 8169 *           (Result was: x == y == z == 0)
 8170 *        -> Need to double instead.
 8171 *
 8172 *   Case 2: A + B = <infinity> = 0.
 8173 *           (Result was: z == 0, x and/or y not 0)
 8174 *        -> Need to set result to infinity.
 8175 */
 8176int ecc_projective_add_point_safe(ecc_point* A, ecc_point* B, ecc_point* R,
 8177    mp_int* a, mp_int* modulus, mp_digit mp, int* infinity)
 8178{
 8179    int err;
 8180
 8181    if (mp_iszero(A->x) && mp_iszero(A->y)) {
 8182        /* A is infinity. */
 8183        err = wc_ecc_copy_point(B, R);
 8184    }
 8185    else if (mp_iszero(B->x) && mp_iszero(B->y)) {
 8186        /* B is infinity. */
 8187        err = wc_ecc_copy_point(A, R);
 8188    }
 8189    else if ((mp_cmp(A->x, B->x) == MP_EQ) && (mp_cmp(A->z, B->z) == MP_EQ)) {
 8190        /* x ordinattes the same. */
 8191        if (mp_cmp(A->y, B->y) == MP_EQ) {
 8192            /* A = B */
 8193            err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
 8194        }
 8195        else {
 8196            /* A = -B */
 8197            err = mp_set(R->x, 0);
 8198            if (err == MP_OKAY)
 8199                err = mp_set(R->y, 0);
 8200            if (err == MP_OKAY)
 8201                err = mp_set(R->z, 1);
 8202            if ((err == MP_OKAY) && (infinity != NULL))
 8203                *infinity = 1;
 8204        }
 8205    }
 8206    else {
 8207        err = _ecc_projective_add_point(A, B, R, a, modulus, mp);
 8208        if ((err == MP_OKAY) && mp_iszero(R->z)) {
 8209            /* When all zero then should have done a double */
 8210            if (mp_iszero(R->x) && mp_iszero(R->y)) {
 8211                if (mp_iszero(B->z)) {
 8212                    err = wc_ecc_copy_point(B, R);
 8213                    if (err == MP_OKAY) {
 8214                        err = mp_montgomery_calc_normalization(R->z, modulus);
 8215                    }
 8216                    if (err == MP_OKAY) {
 8217                        err = _ecc_projective_dbl_point(R, R, a, modulus, mp);
 8218                    }
 8219                }
 8220                else {
 8221                    err = _ecc_projective_dbl_point(B, R, a, modulus, mp);
 8222                }
 8223            }
 8224            /* When only Z zero then result is infinity */
 8225            else {
 8226                err = mp_set(R->x, 0);
 8227                if (err == MP_OKAY)
 8228                    err = mp_set(R->y, 0);
 8229                if (err == MP_OKAY)
 8230                    err = mp_set(R->z, 1);
 8231                if ((err == MP_OKAY) && (infinity != NULL))
 8232                    *infinity = 1;
 8233            }
 8234        }
 8235    }
 8236
 8237    return err;
 8238}
 8239
 8240/* Handles when P is the infinity point.
 8241 *
 8242 * Double infinity -> infinity.
 8243 * Otherwise do normal double - which can't lead to infinity as odd order.
 8244 */
 8245int ecc_projective_dbl_point_safe(ecc_point *P, ecc_point *R, mp_int* a,
 8246                                  mp_int* modulus, mp_digit mp)
 8247{
 8248    int err;
 8249
 8250    if (mp_iszero(P->x) && mp_iszero(P->y)) {
 8251        /* P is infinity. */
 8252        err = wc_ecc_copy_point(P, R);
 8253    }
 8254    else {
 8255        err = _ecc_projective_dbl_point(P, R, a, modulus, mp);
 8256        if ((err == MP_OKAY) && mp_iszero(R->z)) {
 8257           err = mp_set(R->x, 0);
 8258           if (err == MP_OKAY)
 8259               err = mp_set(R->y, 0);
 8260           if (err == MP_OKAY)
 8261               err = mp_set(R->z, 1);
 8262        }
 8263    }
 8264
 8265    return err;
 8266}
 8267#endif /* !(WOLFSSL_ATECC508A) && !(WOLFSSL_ATECC608A) && \
 8268          !(WOLFSSL_CRYPTOCELL) && !(WOLFSSL_SP_MATH) && \
 8269          (!(WOLF_CRYPTO_CB_ONLY_ECC) || (WOLFSSL_QNX_CAAM) || \
 8270            (WOLFSSL_IMXRT1170_CAAM))
 8271        */
 8272
 8273#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_ATECC508A) && \
 8274    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100) && \
 8275    !defined(WOLFSSL_CRYPTOCELL) && \
 8276    !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_ECC)
 8277#ifdef ECC_SHAMIR
 8278
 8279static int ecc_mont_norm_points(ecc_point* A, ecc_point* Am, ecc_point* B,
 8280    ecc_point* Bm, mp_int* modulus, void* heap)
 8281{
 8282    int err = MP_OKAY;
 8283    DECL_MP_INT_SIZE_DYN(mu, mp_bitsused(modulus), MAX_ECC_BITS_USE);
 8284
 8285    (void)heap;
 8286
 8287    NEW_MP_INT_SIZE(mu, mp_bitsused(modulus), heap, DYNAMIC_TYPE_ECC);
 8288#ifdef MP_INT_SIZE_CHECK_NULL
 8289    if (mu == NULL)
 8290       err = MEMORY_E;
 8291#endif
 8292    if (err == MP_OKAY) {
 8293        err = INIT_MP_INT_SIZE(mu, mp_bitsused(modulus));
 8294    }
 8295    if (err == MP_OKAY) {
 8296        err = mp_montgomery_calc_normalization(mu, modulus);
 8297
 8298        if (err == MP_OKAY) {
 8299            /* copy ones ... */
 8300            err = mp_mulmod(A->x, mu, modulus, Am->x);
 8301        }
 8302
 8303        if (err == MP_OKAY)
 8304            err = mp_mulmod(A->y, mu, modulus, Am->y);
 8305        if (err == MP_OKAY)
 8306            err = mp_mulmod(A->z, mu, modulus, Am->z);
 8307
 8308        if (err == MP_OKAY)
 8309            err = mp_mulmod(B->x, mu, modulus, Bm->x);
 8310        if (err == MP_OKAY)
 8311            err = mp_mulmod(B->y, mu, modulus, Bm->y);
 8312        if (err == MP_OKAY)
 8313            err = mp_mulmod(B->z, mu, modulus, Bm->z);
 8314
 8315        /* done with mu */
 8316        mp_clear(mu);
 8317    }
 8318
 8319    FREE_MP_INT_SIZE(mu, heap, DYNAMIC_TYPE_ECC);
 8320
 8321    return err;
 8322}
 8323
 8324/** Computes kA*A + kB*B = C using Shamir's Trick
 8325  A        First point to multiply
 8326  kA       What to multiple A by
 8327  B        Second point to multiply
 8328  kB       What to multiple B by
 8329  C        [out] Destination point (can overlap with A or B)
 8330  a        ECC curve parameter a
 8331  modulus  Modulus for curve
 8332  return MP_OKAY on success
 8333*/
 8334#ifdef FP_ECC
 8335static int normal_ecc_mul2add(ecc_point* A, mp_int* kA,
 8336                             ecc_point* B, mp_int* kB,
 8337                             ecc_point* C, mp_int* a, mp_int* modulus,
 8338                             void* heap)
 8339#else
 8340int ecc_mul2add(ecc_point* A, mp_int* kA,
 8341                    ecc_point* B, mp_int* kB,
 8342                    ecc_point* C, mp_int* a, mp_int* modulus,
 8343                    void* heap)
 8344#endif
 8345{
 8346#ifdef WOLFSSL_SMALL_STACK_CACHE
 8347  ecc_key        *key = NULL;
 8348#endif
 8349#ifdef WOLFSSL_SMALL_STACK
 8350  ecc_point**    precomp = NULL;
 8351#else
 8352  ecc_point*     precomp[SHAMIR_PRECOMP_SZ];
 8353  #ifdef WOLFSSL_NO_MALLOC
 8354  ecc_point      lcl_precomp[SHAMIR_PRECOMP_SZ];
 8355  #endif
 8356#endif
 8357  unsigned int  bitbufA, bitbufB, lenA, lenB, len, nA, nB, nibble;
 8358#ifdef WOLFSSL_NO_MALLOC
 8359  unsigned char tA[ECC_BUFSIZE];
 8360  unsigned char tB[ECC_BUFSIZE];
 8361#else
 8362  unsigned char* tA = NULL;
 8363  unsigned char* tB = NULL;
 8364#endif
 8365  int            err = MP_OKAY, first, x, y;
 8366  mp_digit       mp = 0;
 8367
 8368  /* argchks */
 8369  if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL ||
 8370                                                         modulus == NULL) {
 8371     return ECC_BAD_ARG_E;
 8372  }
 8373
 8374#ifndef WOLFSSL_NO_MALLOC
 8375  /* allocate memory */
 8376  tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8377  if (tA == NULL) {
 8378     return MP_MEM;
 8379  }
 8380  tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8381  if (tB == NULL) {
 8382     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8383     return MP_MEM;
 8384  }
 8385#endif
 8386
 8387#ifdef WOLFSSL_SMALL_STACK_CACHE
 8388  key = (ecc_key *)XMALLOC(sizeof(*key), heap, DYNAMIC_TYPE_ECC_BUFFER);
 8389  if (key == NULL) {
 8390     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8391     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8392     return MP_MEM;
 8393  }
 8394#endif
 8395#ifdef WOLFSSL_SMALL_STACK
 8396  precomp = (ecc_point**)XMALLOC(sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ, heap,
 8397                                                       DYNAMIC_TYPE_ECC_BUFFER);
 8398  if (precomp == NULL) {
 8399     XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8400     XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8401  #ifdef WOLFSSL_SMALL_STACK_CACHE
 8402     XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8403  #endif
 8404     return MP_MEM;
 8405  }
 8406#endif
 8407#ifdef WOLFSSL_SMALL_STACK_CACHE
 8408  key->t1 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 8409  key->t2 = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 8410#ifdef ALT_ECC_SIZE
 8411  key->x = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 8412  key->y = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 8413  key->z = (mp_int*)XMALLOC(sizeof(mp_int), heap, DYNAMIC_TYPE_ECC);
 8414#endif
 8415
 8416  if (key->t1 == NULL || key->t2 == NULL
 8417#ifdef ALT_ECC_SIZE
 8418     || key->x == NULL || key->y == NULL || key->z == NULL
 8419#endif
 8420  ) {
 8421#ifdef ALT_ECC_SIZE
 8422      XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
 8423      XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
 8424      XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
 8425#endif
 8426      XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
 8427      XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
 8428      XFREE(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8429      XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8430      XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8431      XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8432      return MEMORY_E;
 8433  }
 8434  C->key = key;
 8435#endif /* WOLFSSL_SMALL_STACK_CACHE */
 8436
 8437  /* init variables */
 8438  XMEMSET(tA, 0, ECC_BUFSIZE);
 8439  XMEMSET(tB, 0, ECC_BUFSIZE);
 8440#ifndef WOLFSSL_SMALL_STACK
 8441  XMEMSET(precomp, 0, sizeof(precomp));
 8442#else
 8443  XMEMSET(precomp, 0, sizeof(ecc_point*) * SHAMIR_PRECOMP_SZ);
 8444#endif
 8445#ifdef WOLFSSL_CHECK_MEM_ZERO
 8446  wc_MemZero_Add("ecc_mul2add tA", tA, ECC_BUFSIZE);
 8447  wc_MemZero_Add("ecc_mul2add tB", tB, ECC_BUFSIZE);
 8448#endif
 8449
 8450  /* get sizes */
 8451  lenA = (unsigned int)mp_unsigned_bin_size(kA);
 8452  lenB = (unsigned int)mp_unsigned_bin_size(kB);
 8453  len  = MAX(lenA, lenB);
 8454
 8455  /* sanity check */
 8456  if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) {
 8457    err = BAD_FUNC_ARG;
 8458  }
 8459
 8460  if (err == MP_OKAY) {
 8461    /* extract and justify kA */
 8462    err = mp_to_unsigned_bin(kA, (len - lenA) + tA);
 8463
 8464    /* extract and justify kB */
 8465    if (err == MP_OKAY)
 8466        err = mp_to_unsigned_bin(kB, (len - lenB) + tB);
 8467
 8468    /* allocate the table */
 8469    if (err == MP_OKAY) {
 8470        for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
 8471        #ifdef WOLFSSL_NO_MALLOC
 8472            precomp[x] = &lcl_precomp[x];
 8473        #endif
 8474            err = wc_ecc_new_point_ex(&precomp[x], heap);
 8475            if (err != MP_OKAY)
 8476                break;
 8477        #ifdef WOLFSSL_SMALL_STACK_CACHE
 8478            precomp[x]->key = key;
 8479        #endif
 8480        }
 8481    }
 8482  }
 8483
 8484  if (err == MP_OKAY)
 8485    /* init montgomery reduction */
 8486    err = mp_montgomery_setup(modulus, &mp);
 8487
 8488  if (err == MP_OKAY) {
 8489    err = ecc_mont_norm_points(A, precomp[1], B, precomp[1<<2], modulus, heap);
 8490  }
 8491
 8492  if (err == MP_OKAY) {
 8493    /* precomp [i,0](A + B) table */
 8494    err = ecc_projective_dbl_point_safe(precomp[1], precomp[2], a, modulus, mp);
 8495  }
 8496  if (err == MP_OKAY) {
 8497    err = ecc_projective_add_point_safe(precomp[1], precomp[2], precomp[3],
 8498                                                          a, modulus, mp, NULL);
 8499  }
 8500
 8501  if (err == MP_OKAY) {
 8502    /* precomp [0,i](A + B) table */
 8503    err = ecc_projective_dbl_point_safe(precomp[4], precomp[8], a, modulus, mp);
 8504  }
 8505  if (err == MP_OKAY) {
 8506    err = ecc_projective_add_point_safe(precomp[4], precomp[8], precomp[12], a,
 8507                                                             modulus, mp, NULL);
 8508  }
 8509
 8510  if (err == MP_OKAY) {
 8511    /* precomp [i,j](A + B) table (i != 0, j != 0) */
 8512    for (x = 1; x < 4; x++) {
 8513      for (y = 1; y < 4; y++) {
 8514        if (err == MP_OKAY) {
 8515          err = ecc_projective_add_point_safe(precomp[x], precomp[(y<<2)],
 8516                                                  precomp[x+(y<<2)], a, modulus,
 8517                                                  mp, NULL);
 8518        }
 8519      }
 8520    }
 8521  }
 8522
 8523  if (err == MP_OKAY) {
 8524    nibble  = 3;
 8525    first   = 1;
 8526    bitbufA = tA[0];
 8527    bitbufB = tB[0];
 8528
 8529    /* for every byte of the multiplicands */
 8530    for (x = 0; x < (int)len || nibble != 3; ) {
 8531        /* grab a nibble */
 8532        if (++nibble == 4) {
 8533            if (x == (int)len) break;
 8534            bitbufA = tA[x];
 8535            bitbufB = tB[x];
 8536            nibble  = 0;
 8537            x++;
 8538        }
 8539
 8540        /* extract two bits from both, shift/update */
 8541        nA = (bitbufA >> 6) & 0x03;
 8542        nB = (bitbufB >> 6) & 0x03;
 8543        bitbufA = (bitbufA << 2) & 0xFF;
 8544        bitbufB = (bitbufB << 2) & 0xFF;
 8545
 8546        /* if both zero, if first, continue */
 8547        if ((nA == 0) && (nB == 0) && (first == 1)) {
 8548            continue;
 8549        }
 8550
 8551        /* double twice, only if this isn't the first */
 8552        if (first == 0) {
 8553            /* double twice */
 8554            if (err == MP_OKAY)
 8555                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
 8556            if (err == MP_OKAY)
 8557                err = ecc_projective_dbl_point_safe(C, C, a, modulus, mp);
 8558            else
 8559                break;
 8560        }
 8561
 8562        /* if not both zero */
 8563        if ((nA != 0) || (nB != 0)) {
 8564            unsigned int i = nA + (nB<<2);
 8565            if (first == 1) {
 8566                /* if first, copy from table */
 8567                first = 0;
 8568                if (err == MP_OKAY)
 8569                    err = mp_copy(precomp[i]->x, C->x);
 8570
 8571                if (err == MP_OKAY)
 8572                    err = mp_copy(precomp[i]->y, C->y);
 8573
 8574                if (err == MP_OKAY)
 8575                    err = mp_copy(precomp[i]->z, C->z);
 8576                else
 8577                    break;
 8578            } else {
 8579                /* if not first, add from table */
 8580                if (err == MP_OKAY)
 8581                    err = ecc_projective_add_point_safe(C, precomp[i],
 8582                                                        C, a, modulus, mp,
 8583                                                        &first);
 8584                if (err != MP_OKAY)
 8585                    break;
 8586            }
 8587        }
 8588    }
 8589  }
 8590
 8591  /* reduce to affine */
 8592  if (err == MP_OKAY)
 8593    err = ecc_map(C, modulus, mp);
 8594
 8595  /* clean up */
 8596  for (x = 0; x < SHAMIR_PRECOMP_SZ; x++) {
 8597     wc_ecc_del_point_ex(precomp[x], heap);
 8598  }
 8599
 8600  ForceZero(tA, ECC_BUFSIZE);
 8601  ForceZero(tB, ECC_BUFSIZE);
 8602#ifdef WOLFSSL_SMALL_STACK_CACHE
 8603#ifdef ALT_ECC_SIZE
 8604  XFREE(key->z, heap, DYNAMIC_TYPE_ECC);
 8605  XFREE(key->y, heap, DYNAMIC_TYPE_ECC);
 8606  XFREE(key->x, heap, DYNAMIC_TYPE_ECC);
 8607#endif
 8608  XFREE(key->t2, heap, DYNAMIC_TYPE_ECC);
 8609  XFREE(key->t1, heap, DYNAMIC_TYPE_ECC);
 8610  XFREE(key, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8611  C->key = NULL;
 8612#endif
 8613  WC_FREE_VAR_EX(precomp, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8614#ifndef WOLFSSL_NO_MALLOC
 8615  XFREE(tB, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8616  XFREE(tA, heap, DYNAMIC_TYPE_ECC_BUFFER);
 8617#elif defined(WOLFSSL_CHECK_MEM_ZERO)
 8618  wc_MemZero_Check(tB, ECC_BUFSIZE);
 8619  wc_MemZero_Check(tA, ECC_BUFSIZE);
 8620#endif
 8621  return err;
 8622}
 8623
 8624#endif /* ECC_SHAMIR */
 8625#endif /* (!WOLFSSL_SP_MATH && !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A &&
 8626        * !WOLFSSL_CRYPTOCEL */
 8627
 8628
 8629#ifdef HAVE_ECC_VERIFY
 8630/* verify
 8631 *
 8632 * w  = s^-1 mod n
 8633 * u1 = xw
 8634 * u2 = rw
 8635 * X = u1*G + u2*Q
 8636 * v = X_x1 mod n
 8637 * accept if v == r
 8638 */
 8639
 8640/**
 8641 Verify an ECC signature
 8642 sig         The signature to verify
 8643 siglen      The length of the signature (octets)
 8644 hash        The hash (message digest) that was signed
 8645 hashlen     The length of the hash (octets)
 8646 res         Result of signature, 1==valid, 0==invalid
 8647 key         The corresponding public ECC key
 8648 return      MP_OKAY if successful (even if the signature is not valid)
 8649             Caller should check the *res value to determine if the signature
 8650             is valid or invalid. Other negative values are returned on error.
 8651 */
 8652WOLFSSL_ABI
 8653int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
 8654                       word32 hashlen, int* res, ecc_key* key)
 8655{
 8656    int err;
 8657
 8658#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 8659    mp_int *r = NULL, *s = NULL;
 8660#else
 8661    DECL_MP_INT_SIZE_DYN(r, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
 8662    DECL_MP_INT_SIZE_DYN(s, ECC_KEY_MAX_BITS(key), MAX_ECC_BITS_USE);
 8663#endif
 8664#ifdef WOLFSSL_ASYNC_CRYPT
 8665    int isPrivateKeyOnly = 0;
 8666#endif
 8667#ifdef NO_ASN
 8668    word32 keySz;
 8669#endif
 8670
 8671    if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
 8672        return ECC_BAD_ARG_E;
 8673    }
 8674
 8675    /* Check hash length */
 8676    if ((hashlen > WC_MAX_DIGEST_SIZE) ||
 8677        (hashlen < WC_MIN_DIGEST_SIZE)) {
 8678        return BAD_LENGTH_E;
 8679    }
 8680
 8681#ifdef WOLF_CRYPTO_CB
 8682    #ifndef WOLF_CRYPTO_CB_FIND
 8683    if (key->devId != INVALID_DEVID)
 8684    #endif
 8685    {
 8686        err = wc_CryptoCb_EccVerify(sig, siglen, hash, hashlen, res, key);
 8687        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 8688            return err;
 8689        /* fall-through when unavailable */
 8690    }
 8691#endif
 8692
 8693#ifdef WOLF_CRYPTO_CB_ONLY_ECC
 8694    (void)siglen;
 8695    (void)hashlen;
 8696    (void)s;
 8697    (void)r;
 8698    (void)err;
 8699    return NO_VALID_DEVID;
 8700#else /* !WOLF_CRYPTO_CB_ONLY_ECC */
 8701#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 8702    err = wc_ecc_alloc_async(key);
 8703    if (err != 0)
 8704        return err;
 8705    r = key->r;
 8706    s = key->s;
 8707#else
 8708    NEW_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
 8709        DYNAMIC_TYPE_ECC);
 8710    #ifdef MP_INT_SIZE_CHECK_NULL
 8711    if (r == NULL)
 8712        return MEMORY_E;
 8713    #endif
 8714    NEW_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap,
 8715        DYNAMIC_TYPE_ECC);
 8716    #ifdef MP_INT_SIZE_CHECK_NULL
 8717    if (s == NULL) {
 8718        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 8719        return MEMORY_E;
 8720    }
 8721    #endif
 8722    err = INIT_MP_INT_SIZE(r, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 8723    if (err != 0) {
 8724        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
 8725        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 8726        return err;
 8727    }
 8728    err = INIT_MP_INT_SIZE(s, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 8729    if (err != 0) {
 8730        FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
 8731        FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 8732        return err;
 8733    }
 8734#endif /* WOLFSSL_ASYNC_CRYPT */
 8735
 8736    switch (key->state) {
 8737        case ECC_STATE_NONE:
 8738        case ECC_STATE_VERIFY_DECODE:
 8739            key->state = ECC_STATE_VERIFY_DECODE;
 8740
 8741            /* default to invalid signature */
 8742            *res = 0;
 8743
 8744    #ifndef NO_ASN
 8745            /* Decode ASN.1 ECDSA signature. */
 8746        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 8747            /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s.
 8748             * If either of those don't allocate correctly, none of
 8749             * the rest of this function will execute, and everything
 8750             * gets cleaned up at the end. */
 8751            err = DecodeECC_DSA_Sig(sig, siglen, r, s);
 8752        #else
 8753            /* r and s are initialized. */
 8754            err = DecodeECC_DSA_Sig_Ex(sig, siglen, r, s, 0);
 8755        #endif
 8756            if (err < 0) {
 8757                break;
 8758            }
 8759    #else
 8760            /* No support for DSA ASN.1 header.
 8761             * Signature must be r+s directly. */
 8762            keySz = 0;
 8763            if (key->dp != NULL) {
 8764                keySz = (word32)key->dp->size;
 8765            }
 8766            if (siglen != keySz * 2) {
 8767                WOLFSSL_MSG("Error: ECDSA Verify raw signature size");
 8768                return WC_NO_ERR_TRACE(ECC_BAD_ARG_E);
 8769            }
 8770
 8771            /* Import signature into r,s */
 8772            mp_init(r);
 8773            mp_init(s);
 8774            mp_read_unsigned_bin(r, sig, keySz);
 8775            mp_read_unsigned_bin(s, sig + keySz, keySz);
 8776    #endif /* !NO_ASN */
 8777            FALL_THROUGH;
 8778
 8779        case ECC_STATE_VERIFY_DO:
 8780            key->state = ECC_STATE_VERIFY_DO;
 8781        #ifdef WOLFSSL_ASYNC_CRYPT
 8782            if (key->type == ECC_PRIVATEKEY_ONLY) {
 8783                isPrivateKeyOnly = 1;
 8784            }
 8785        #endif
 8786            err = wc_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
 8787
 8788        #ifndef WOLFSSL_ASYNC_CRYPT
 8789            /* done with R/S */
 8790            mp_clear(r);
 8791            mp_clear(s);
 8792            FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
 8793            FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 8794        #ifdef MP_INT_SIZE_CHECK_NULL
 8795            r = NULL;
 8796            s = NULL;
 8797        #endif
 8798        #endif
 8799
 8800            if (err < 0) {
 8801                break;
 8802            }
 8803            FALL_THROUGH;
 8804
 8805        case ECC_STATE_VERIFY_RES:
 8806            key->state = ECC_STATE_VERIFY_RES;
 8807            err = 0;
 8808            break;
 8809
 8810        default:
 8811            err = BAD_STATE_E;
 8812    }
 8813
 8814#ifdef WOLFSSL_ASYNC_CRYPT
 8815    /* if async pending then return and skip done cleanup below */
 8816    if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
 8817        if (!isPrivateKeyOnly) /* do not advance state if doing make pub key */
 8818            key->state++;
 8819        return err;
 8820    }
 8821#endif
 8822
 8823    /* cleanup */
 8824#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 8825    wc_ecc_free_async(key);
 8826#else
 8827    FREE_MP_INT_SIZE(s, key->heap, DYNAMIC_TYPE_ECC);
 8828    FREE_MP_INT_SIZE(r, key->heap, DYNAMIC_TYPE_ECC);
 8829#endif
 8830
 8831    /* make sure required variables are reset */
 8832    wc_ecc_reset(key);
 8833    return err;
 8834#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
 8835}
 8836
 8837#ifndef WOLF_CRYPTO_CB_ONLY_ECC
 8838
 8839#if !defined(WOLFSSL_STM32_PKA) && !defined(WOLFSSL_PSOC6_CRYPTO) && \
 8840    !defined(WOLF_CRYPTO_CB_ONLY_ECC)
 8841static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
 8842{
 8843    int err = MP_OKAY;
 8844    DECLARE_CURVE_SPECS(1);
 8845
 8846    ALLOC_CURVE_SPECS(1, err);
 8847    if (err == MP_OKAY) {
 8848        err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
 8849    }
 8850    if (err != 0) {
 8851        FREE_CURVE_SPECS();
 8852        return err;
 8853    }
 8854
 8855    if (mp_iszero(r) || mp_iszero(s)) {
 8856        err = MP_ZERO_E;
 8857    }
 8858    if ((err == 0) && (mp_cmp(r, curve->order) != MP_LT)) {
 8859        err = MP_VAL;
 8860    }
 8861    if ((err == 0) && (mp_cmp(s, curve->order) != MP_LT)) {
 8862        err = MP_VAL;
 8863    }
 8864
 8865    wc_ecc_curve_free(curve);
 8866    FREE_CURVE_SPECS();
 8867    return err;
 8868}
 8869#endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */
 8870
 8871#if defined(HAVE_ECC_VERIFY_HELPER) && !defined(WOLFSSL_MICROCHIP)
 8872static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash,
 8873    word32 hashlen, int* res, ecc_key* key)
 8874{
 8875    (void)r;
 8876    (void)s;
 8877    (void)hash;
 8878    (void)hashlen;
 8879    (void)res;
 8880    (void)key;
 8881
 8882#if defined(WOLFSSL_DSP) && !defined(FREESCALE_LTC_ECC)
 8883  if (key->handle != -1) {
 8884      return sp_dsp_ecc_verify_256(key->handle, hash, hashlen, key->pubkey.x,
 8885        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
 8886  }
 8887  if (wolfSSL_GetHandleCbSet() == 1) {
 8888      return sp_dsp_ecc_verify_256(0, hash, hashlen, key->pubkey.x,
 8889        key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
 8890  }
 8891#endif
 8892
 8893#if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC)
 8894    if (key->idx == ECC_CUSTOM_IDX || (1
 8895    #ifndef WOLFSSL_SP_NO_256
 8896         && ecc_sets[key->idx].id != ECC_SECP256R1
 8897    #endif
 8898    #ifdef WOLFSSL_SP_SM2
 8899         && ecc_sets[key->idx].id != ECC_SM2P256V1
 8900    #endif
 8901    #ifdef WOLFSSL_SP_384
 8902         && ecc_sets[key->idx].id != ECC_SECP384R1
 8903    #endif
 8904    #ifdef WOLFSSL_SP_521
 8905         && ecc_sets[key->idx].id != ECC_SECP521R1
 8906    #endif
 8907        )) {
 8908        return WC_KEY_SIZE_E;
 8909    }
 8910#endif
 8911
 8912#if defined(WOLFSSL_HAVE_SP_ECC)
 8913    if (key->idx != ECC_CUSTOM_IDX) {
 8914    #if defined(WC_ECC_NONBLOCK) && defined(WC_ECC_NONBLOCK_ONLY)
 8915        /* perform blocking call to non-blocking function */
 8916        ecc_nb_ctx_t nb_ctx;
 8917        int err;
 8918        XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
 8919        err = NOT_COMPILED_IN; /* set default error */
 8920    #endif
 8921    #ifndef WOLFSSL_SP_NO_256
 8922        if (ecc_sets[key->idx].id == ECC_SECP256R1) {
 8923        #ifdef WC_ECC_NONBLOCK
 8924            if (key->nb_ctx) {
 8925                return sp_ecc_verify_256_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
 8926                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
 8927                    key->heap);
 8928            }
 8929            #ifdef WC_ECC_NONBLOCK_ONLY
 8930            do { /* perform blocking call to non-blocking function */
 8931                err = sp_ecc_verify_256_nb(&nb_ctx.sp_ctx, hash, hashlen,
 8932                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
 8933                    key->heap);
 8934            } while (err == FP_WOULDBLOCK);
 8935            return err;
 8936            #endif
 8937        #endif /* WC_ECC_NONBLOCK */
 8938        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
 8939            {
 8940                int ret;
 8941                SAVE_VECTOR_REGISTERS(return _svr_ret;);
 8942                ret = sp_ecc_verify_256(hash, hashlen, key->pubkey.x,
 8943                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
 8944                RESTORE_VECTOR_REGISTERS();
 8945                return ret;
 8946            }
 8947        #endif
 8948        }
 8949    #endif
 8950    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 8951        if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
 8952            #if defined(FP_ECC_CONTROL) && !defined(WOLFSSL_DSP_BUILD)
 8953            return sp_ecc_cache_verify_sm2_256(hash, hashlen, key->pubkey.x,
 8954                key->pubkey.y, key->pubkey.z, r, s, res,
 8955                sp_ecc_get_cache_entry_256(&(key->pubkey), ECC_SM2P256V1,
 8956                                          key->fpIdx, key->fpBuild, key->heap),
 8957                key->heap);
 8958            #endif
 8959            #if !defined(FP_ECC_CONTROL)
 8960            return sp_ecc_verify_sm2_256(hash, hashlen, key->pubkey.x,
 8961                key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
 8962            #endif
 8963        }
 8964    #endif
 8965    #ifdef WOLFSSL_SP_384
 8966        if (ecc_sets[key->idx].id == ECC_SECP384R1) {
 8967        #ifdef WC_ECC_NONBLOCK
 8968            if (key->nb_ctx) {
 8969                return sp_ecc_verify_384_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
 8970                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
 8971                    key->heap);
 8972            }
 8973            #ifdef WC_ECC_NONBLOCK_ONLY
 8974            do { /* perform blocking call to non-blocking function */
 8975                err = sp_ecc_verify_384_nb(&nb_ctx.sp_ctx, hash, hashlen,
 8976                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
 8977                    key->heap);
 8978            } while (err == FP_WOULDBLOCK);
 8979            return err;
 8980            #endif
 8981        #endif /* WC_ECC_NONBLOCK */
 8982        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
 8983            {
 8984                int ret;
 8985                SAVE_VECTOR_REGISTERS(return _svr_ret;);
 8986                ret = sp_ecc_verify_384(hash, hashlen, key->pubkey.x,
 8987                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
 8988                RESTORE_VECTOR_REGISTERS();
 8989                return ret;
 8990            }
 8991        #endif
 8992        }
 8993    #endif
 8994    #ifdef WOLFSSL_SP_521
 8995        if (ecc_sets[key->idx].id == ECC_SECP521R1) {
 8996        #ifdef WC_ECC_NONBLOCK
 8997            if (key->nb_ctx) {
 8998                return sp_ecc_verify_521_nb(&key->nb_ctx->sp_ctx, hash, hashlen,
 8999                    key->pubkey.x,  key->pubkey.y, key->pubkey.z, r, s, res,
 9000                    key->heap);
 9001            }
 9002            #ifdef WC_ECC_NONBLOCK_ONLY
 9003            do { /* perform blocking call to non-blocking function */
 9004                err = sp_ecc_verify_521_nb(&nb_ctx.sp_ctx, hash, hashlen,
 9005                    key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res,
 9006                    key->heap);
 9007            } while (err == FP_WOULDBLOCK);
 9008            return err;
 9009            #endif
 9010        #endif /* WC_ECC_NONBLOCK */
 9011        #if !defined(WC_ECC_NONBLOCK) || (defined(WC_ECC_NONBLOCK) && !defined(WC_ECC_NONBLOCK_ONLY))
 9012            {
 9013                int ret;
 9014                SAVE_VECTOR_REGISTERS(return _svr_ret;);
 9015                ret = sp_ecc_verify_521(hash, hashlen, key->pubkey.x,
 9016                    key->pubkey.y, key->pubkey.z, r, s, res, key->heap);
 9017                RESTORE_VECTOR_REGISTERS();
 9018                return ret;
 9019            }
 9020        #endif
 9021        }
 9022    #endif
 9023    }
 9024#endif
 9025
 9026    return NOT_COMPILED_IN;
 9027}
 9028
 9029#if !defined(WOLFSSL_MICROCHIP) && \
 9030    (!defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC))
 9031static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
 9032    word32 hashlen, int* res, ecc_key* key, ecc_curve_spec* curve)
 9033{
 9034   int        err;
 9035   ecc_point* mG = NULL;
 9036   ecc_point* mQ = NULL;
 9037#ifdef WOLFSSL_NO_MALLOC
 9038   ecc_point  lcl_mG;
 9039   ecc_point  lcl_mQ;
 9040#endif
 9041   DECL_MP_INT_SIZE_DYN(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
 9042#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
 9043   DECL_MP_INT_SIZE_DYN(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), MAX_ECC_BITS_USE);
 9044#endif
 9045   mp_int*    e;
 9046   mp_int*    v = NULL;      /* Will be w. */
 9047#if defined(WOLFSSL_CHECK_VER_FAULTS) && defined(WOLFSSL_NO_MALLOC)
 9048   mp_int     u1tmp[1];
 9049   mp_int     u2tmp[1];
 9050#endif
 9051   mp_int*    u1 = NULL;     /* Will be e. */
 9052   mp_int*    u2 = NULL;     /* Will be w. */
 9053#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_CAVIUM_V)
 9054   err = wc_ecc_alloc_mpint(key, &key->e);
 9055   if (err != 0) {
 9056      return err;
 9057   }
 9058   e = key->e;
 9059
 9060   err = mp_init(e);
 9061#else
 9062   NEW_MP_INT_SIZE(e_lcl, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
 9063#ifdef MP_INT_SIZE_CHECK_NULL
 9064   if (e_lcl == NULL) {
 9065       return MEMORY_E;
 9066   }
 9067#endif
 9068   e = e_lcl;
 9069
 9070   err = INIT_MP_INT_SIZE(e, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 9071#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_CAVIUM_V */
 9072   if (err != MP_OKAY) {
 9073#ifdef WOLFSSL_SMALL_STACK
 9074   #if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
 9075      XFREE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
 9076   #endif
 9077#endif
 9078      return MEMORY_E;
 9079   }
 9080
 9081   /* read hash */
 9082   if (err == MP_OKAY) {
 9083       /* we may need to truncate if hash is longer than key size */
 9084       unsigned int orderBits = (unsigned int)mp_count_bits(curve->order);
 9085
 9086       /* truncate down to byte size, may be all that's needed */
 9087       if ( (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
 9088           hashlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE;
 9089       err = mp_read_unsigned_bin(e, hash, hashlen);
 9090
 9091       /* may still need bit truncation too */
 9092       if (err == MP_OKAY && (WOLFSSL_BIT_SIZE * hashlen) > orderBits)
 9093           mp_rshb(e, (int)(WOLFSSL_BIT_SIZE - (orderBits & 0x7)));
 9094   }
 9095
 9096   /* check for async hardware acceleration */
 9097#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
 9098   if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
 9099   #if defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)
 9100   #ifdef HAVE_CAVIUM_V
 9101      if (NitroxEccIsCurveSupported(key))
 9102   #endif
 9103      {
 9104          word32 keySz = (word32)key->dp->size;
 9105          err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
 9106          if (err == MP_OKAY)
 9107              err = wc_mp_to_bigint_sz(key->pubkey.x, &key->pubkey.x->raw, keySz);
 9108          if (err == MP_OKAY)
 9109              err = wc_mp_to_bigint_sz(key->pubkey.y, &key->pubkey.y->raw, keySz);
 9110          if (err == MP_OKAY)
 9111          #ifdef HAVE_CAVIUM_V
 9112              err = NitroxEcdsaVerify(key, &e->raw, &key->pubkey.x->raw,
 9113                    &key->pubkey.y->raw, &r->raw, &s->raw,
 9114                    &curve->prime->raw, &curve->order->raw, res);
 9115          #else
 9116              err = IntelQaEcdsaVerify(&key->asyncDev, &e->raw, &key->pubkey.x->raw,
 9117                    &key->pubkey.y->raw, &r->raw, &s->raw, &curve->Af->raw,
 9118                    &curve->Bf->raw, &curve->prime->raw, &curve->order->raw,
 9119                    &curve->Gx->raw, &curve->Gy->raw, res);
 9120          #endif
 9121
 9122      #ifndef HAVE_CAVIUM_V
 9123          mp_clear(e);
 9124      #endif
 9125
 9126          return err;
 9127      }
 9128   #endif /* HAVE_CAVIUM_V || HAVE_INTEL_QA */
 9129   }
 9130#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_ECC */
 9131
 9132   NEW_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key), key->heap, DYNAMIC_TYPE_ECC);
 9133#ifdef MP_INT_SIZE_CHECK_NULL
 9134   if (w == NULL) {
 9135       err = MEMORY_E;
 9136   }
 9137#endif
 9138
 9139   if (err == MP_OKAY) {
 9140#ifdef WOLFSSL_CHECK_VER_FAULTS
 9141    #ifndef WOLFSSL_NO_MALLOC
 9142        u1 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
 9143        u2 = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_ECC);
 9144       if (u1 == NULL || u2 == NULL)
 9145            err = MEMORY_E;
 9146    #else
 9147        u1 = u1tmp;
 9148        u2 = u2tmp;
 9149    #endif
 9150#else
 9151       u1 = e;
 9152       u2 = w;
 9153#endif
 9154       v = w;
 9155   }
 9156   if (err == MP_OKAY) {
 9157       err = INIT_MP_INT_SIZE(w, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 9158   }
 9159#ifdef WOLFSSL_CHECK_VER_FAULTS
 9160   if (err == MP_OKAY) {
 9161       err = INIT_MP_INT_SIZE(u1, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 9162   }
 9163   if (err == MP_OKAY) {
 9164       err = INIT_MP_INT_SIZE(u2, ECC_KEY_MAX_BITS_NONULLCHECK(key));
 9165   }
 9166#endif
 9167
 9168   /* allocate points */
 9169   if (err == MP_OKAY) {
 9170   #ifdef WOLFSSL_NO_MALLOC
 9171       mG = &lcl_mG;
 9172   #endif
 9173       err = wc_ecc_new_point_ex(&mG, key->heap);
 9174   }
 9175   if (err == MP_OKAY) {
 9176   #ifdef WOLFSSL_NO_MALLOC
 9177       mQ = &lcl_mQ;
 9178   #endif
 9179       err = wc_ecc_new_point_ex(&mQ, key->heap);
 9180   }
 9181
 9182   /*  w  = s^-1 mod n */
 9183   if (err == MP_OKAY)
 9184       err = mp_invmod(s, curve->order, w);
 9185
 9186   /* u1 = ew */
 9187   if (err == MP_OKAY)
 9188       err = mp_mulmod(e, w, curve->order, u1);
 9189
 9190#ifdef WOLFSSL_CHECK_VER_FAULTS
 9191    if (err == MP_OKAY && mp_iszero(e) != MP_YES && mp_cmp(u1, e) == MP_EQ) {
 9192        err = BAD_STATE_E;
 9193    }
 9194#endif
 9195
 9196   /* u2 = rw */
 9197   if (err == MP_OKAY)
 9198       err = mp_mulmod(r, w, curve->order, u2);
 9199
 9200#ifdef WOLFSSL_CHECK_VER_FAULTS
 9201    if (err == MP_OKAY && mp_cmp(u2, w) == MP_EQ) {
 9202        err = BAD_STATE_E;
 9203    }
 9204#endif
 9205
 9206   /* find mG and mQ */
 9207   if (err == MP_OKAY)
 9208       err = mp_copy(curve->Gx, mG->x);
 9209   if (err == MP_OKAY)
 9210       err = mp_copy(curve->Gy, mG->y);
 9211   if (err == MP_OKAY)
 9212       err = mp_set(mG->z, 1);
 9213
 9214   if (err == MP_OKAY)
 9215       err = mp_copy(key->pubkey.x, mQ->x);
 9216   if (err == MP_OKAY)
 9217       err = mp_copy(key->pubkey.y, mQ->y);
 9218   if (err == MP_OKAY)
 9219       err = mp_copy(key->pubkey.z, mQ->z);
 9220
 9221#if defined(FREESCALE_LTC_ECC)
 9222   /* use PKHA to compute u1*mG + u2*mQ */
 9223   if (err == MP_OKAY)
 9224       err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0, key->heap);
 9225   if (err == MP_OKAY)
 9226       err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0, key->heap);
 9227   if (err == MP_OKAY)
 9228       err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
 9229#else
 9230#ifndef ECC_SHAMIR
 9231    if (err == MP_OKAY)
 9232    {
 9233     #ifdef WOLFSSL_CHECK_VER_FAULTS
 9234        ecc_point mG1, mQ1;
 9235        wc_ecc_copy_point(mQ, &mQ1);
 9236        wc_ecc_copy_point(mG, &mG1);
 9237     #endif
 9238
 9239        mp_digit mp = 0;
 9240
 9241        if (!mp_iszero((MP_INT_SIZE*)u1)) {
 9242            /* compute u1*mG + u2*mQ = mG */
 9243            err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
 9244                                                                     key->heap);
 9245        #ifdef WOLFSSL_CHECK_VER_FAULTS
 9246            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
 9247                err = BAD_STATE_E;
 9248            }
 9249
 9250            /* store new value for comparing with after add operation */
 9251           wc_ecc_copy_point(mG, &mG1);
 9252        #endif
 9253            if (err == MP_OKAY) {
 9254                err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
 9255                                                                     key->heap);
 9256            }
 9257        #ifdef WOLFSSL_CHECK_VER_FAULTS
 9258            if (err == MP_OKAY && wc_ecc_cmp_point(mQ, &mQ1) == MP_EQ) {
 9259                err = BAD_STATE_E;
 9260            }
 9261        #endif
 9262
 9263            /* find the montgomery mp */
 9264            if (err == MP_OKAY)
 9265                err = mp_montgomery_setup(curve->prime, &mp);
 9266
 9267            /* add them */
 9268            if (err == MP_OKAY)
 9269                err = ecc_projective_add_point_safe(mQ, mG, mG, curve->Af,
 9270                                                        curve->prime, mp, NULL);
 9271        #ifdef WOLFSSL_CHECK_VER_FAULTS
 9272            if (err == MP_OKAY && wc_ecc_cmp_point(mG, &mG1) == MP_EQ) {
 9273                err = BAD_STATE_E;
 9274            }
 9275            if (err == MP_OKAY && wc_ecc_cmp_point(mG, mQ) == MP_EQ) {
 9276                err = BAD_STATE_E;
 9277            }
 9278        #endif
 9279        }
 9280        else {
 9281            /* compute 0*mG + u2*mQ = mG */
 9282            err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
 9283                                                                     key->heap);
 9284            /* find the montgomery mp */
 9285            if (err == MP_OKAY)
 9286                err = mp_montgomery_setup(curve->prime, &mp);
 9287        }
 9288
 9289        /* reduce */
 9290        if (err == MP_OKAY)
 9291            err = ecc_map(mG, curve->prime, mp);
 9292    }
 9293#else
 9294    /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
 9295    if (err == MP_OKAY) {
 9296        err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
 9297                                                                     key->heap);
 9298    }
 9299#endif /* ECC_SHAMIR */
 9300#endif /* FREESCALE_LTC_ECC */
 9301
 9302   /* v = X_x1 mod n */
 9303   if (err == MP_OKAY)
 9304       err = mp_mod(mG->x, curve->order, v);
 9305
 9306   /* does v == r */
 9307   if (err == MP_OKAY) {
 9308       if (mp_cmp(v, r) == MP_EQ)
 9309           *res = 1;
 9310#ifdef WOLFSSL_CHECK_VER_FAULTS
 9311       /* redundant comparison as sanity check that first one happened */
 9312       if (*res == 1 && mp_cmp(r, v) != MP_EQ)
 9313           *res = 0;
 9314#endif
 9315   }
 9316
 9317   /* cleanup */
 9318   wc_ecc_del_point_ex(mG, key->heap);
 9319   wc_ecc_del_point_ex(mQ, key->heap);
 9320
 9321   mp_clear(e);
 9322   mp_clear(w);
 9323   FREE_MP_INT_SIZE(w, key->heap, DYNAMIC_TYPE_ECC);
 9324#ifdef WOLFSSL_CHECK_VER_FAULTS
 9325   mp_clear(u1);
 9326   mp_clear(u2);
 9327#ifndef WOLFSSL_NO_MALLOC
 9328   XFREE(u1, key->heap, DYNAMIC_TYPE_ECC);
 9329   XFREE(u2, key->heap, DYNAMIC_TYPE_ECC);
 9330#endif
 9331#endif
 9332#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
 9333   FREE_MP_INT_SIZE(e_lcl, key->heap, DYNAMIC_TYPE_ECC);
 9334#endif
 9335
 9336   return err;
 9337}
 9338#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
 9339#endif /* HAVE_ECC_VERIFY_HELPER */
 9340
 9341/**
 9342   Verify an ECC signature
 9343   r           The signature R component to verify
 9344   s           The signature S component to verify
 9345   hash        The hash (message digest) that was signed
 9346   hashlen     The length of the hash (octets)
 9347   res         Result of signature, 1==valid, 0==invalid
 9348   key         The corresponding public ECC key
 9349   return      MP_OKAY if successful (even if the signature is not valid)
 9350               Caller should check the *res value to determine if the signature
 9351               is valid or invalid. Other negative values are returned on error.
 9352*/
 9353int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
 9354                    word32 hashlen, int* res, ecc_key* key)
 9355{
 9356#if defined(WOLFSSL_STM32_PKA)
 9357    return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
 9358#elif defined(WOLFSSL_PSOC6_CRYPTO)
 9359    return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
 9360#else
 9361   int           err;
 9362   word32        keySz = 0;
 9363#ifndef WC_ALLOW_ECC_ZERO_HASH
 9364   byte hashIsZero = 0;
 9365   word32 zIdx;
 9366#endif
 9367#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
 9368   byte sigRS[ATECC_KEY_SIZE*2];
 9369#elif defined(WOLFSSL_MICROCHIP_TA100)
 9370   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
 9371#elif defined(WOLFSSL_CRYPTOCELL)
 9372   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE*2];
 9373   CRYS_ECDSA_VerifyUserContext_t sigCtxTemp;
 9374   word32 msgLenInBytes = hashlen;
 9375   CRYS_ECPKI_HASH_OpMode_t hash_mode;
 9376#elif defined(WOLFSSL_SILABS_SE_ACCEL)
 9377   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
 9378#elif defined(WOLFSSL_KCAPI_ECC)
 9379   byte sigRS[MAX_ECC_BYTES*2];
 9380#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 9381   byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
 9382   byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0};
 9383#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_ECDSA_VERIFY)
 9384#else
 9385   int curveLoaded = 0;
 9386   DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
 9387#endif
 9388
 9389   if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
 9390       return ECC_BAD_ARG_E;
 9391
 9392    /* Check hash length */
 9393    if ((hashlen > WC_MAX_DIGEST_SIZE) ||
 9394        (hashlen < WC_MIN_DIGEST_SIZE)) {
 9395        return BAD_LENGTH_E;
 9396    }
 9397
 9398#ifndef WC_ALLOW_ECC_ZERO_HASH
 9399    /* reject all 0's hash */
 9400    for (zIdx = 0; zIdx < hashlen; zIdx++)
 9401        hashIsZero |= hash[zIdx];
 9402    if (hashIsZero == 0)
 9403        return ECC_BAD_ARG_E;
 9404#endif
 9405
 9406   /* default to invalid signature */
 9407   *res = 0;
 9408
 9409   /* is the IDX valid ?  */
 9410   if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
 9411      return ECC_BAD_ARG_E;
 9412   }
 9413
 9414   err = wc_ecc_check_r_s_range(key, r, s);
 9415   if (err != MP_OKAY) {
 9416      return err;
 9417   }
 9418
 9419   keySz = (word32)key->dp->size;
 9420
 9421#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \
 9422    defined(WOLFSSL_ASYNC_CRYPT_SW)
 9423    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
 9424        if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_ECC_VERIFY)) {
 9425            WC_ASYNC_SW* sw = &key->asyncDev.sw;
 9426            sw->eccVerify.r = r;
 9427            sw->eccVerify.s = s;
 9428            sw->eccVerify.hash = hash;
 9429            sw->eccVerify.hashlen = hashlen;
 9430            sw->eccVerify.stat = res;
 9431            sw->eccVerify.key = key;
 9432            return WC_PENDING_E;
 9433        }
 9434    }
 9435#endif
 9436
 9437#ifndef HAVE_ECC_VERIFY_HELPER
 9438
 9439#ifndef WOLFSSL_SE050
 9440    /* Extract R and S with front zero padding (if required),
 9441     * SE050 does this in port layer  */
 9442    XMEMSET(sigRS, 0, sizeof(sigRS));
 9443    err = mp_to_unsigned_bin(r, sigRS +
 9444                                (keySz - mp_unsigned_bin_size(r)));
 9445    if (err != MP_OKAY) {
 9446        return err;
 9447    }
 9448    err = mp_to_unsigned_bin(s, sigRS + keySz +
 9449                                (keySz - mp_unsigned_bin_size(s)));
 9450    if (err != MP_OKAY) {
 9451        return err;
 9452    }
 9453#endif /* WOLFSSL_SE050 */
 9454
 9455#if defined(WOLFSSL_MICROCHIP_TA100)
 9456    if (microchip_curve_id_for_key(key) == ECC_SECP256R1) {
 9457        err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
 9458        if (err != 0) {
 9459            return err;
 9460        }
 9461        (void)hashlen;
 9462    }
 9463    else {
 9464        err = atmel_ecc_verify_ex(hash, hashlen, sigRS, key->pubkey_raw,
 9465            keySz * 2, microchip_curve_id_for_key(key), res);
 9466        if (err != 0) {
 9467           return err;
 9468        }
 9469    }
 9470#elif defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
 9471    err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
 9472    if (err != 0) {
 9473       return err;
 9474    }
 9475    (void)hashlen;
 9476#elif defined(WOLFSSL_CRYPTOCELL)
 9477
 9478   /* truncate if hash is longer than key size */
 9479   if (msgLenInBytes > keySz) {
 9480       msgLenInBytes = keySz;
 9481   }
 9482   hash_mode = cc310_hashModeECC(msgLenInBytes);
 9483   if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) {
 9484       /* hash_mode = */ cc310_hashModeECC(keySz);
 9485       hash_mode = CRYS_ECPKI_HASH_SHA256_mode;
 9486   }
 9487
 9488   /* verify the signature using the public key */
 9489   err = CRYS_ECDSA_Verify(&sigCtxTemp,
 9490                           &key->ctx.pubKey,
 9491                           hash_mode,
 9492                           &sigRS[0],
 9493                           keySz*2,
 9494                           (byte*)hash,
 9495                           msgLenInBytes);
 9496
 9497   if (err == CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR) {
 9498       /* signature verification reported invalid signature. */
 9499       *res = 0; /* Redundant, added for code clarity */
 9500       err = MP_OKAY;
 9501   }
 9502   else if (err != SA_SILIB_RET_OK) {
 9503       WOLFSSL_MSG("CRYS_ECDSA_Verify failed");
 9504       return err;
 9505   }
 9506   else {
 9507       /* valid signature. */
 9508       *res = 1;
 9509       err = MP_OKAY;
 9510   }
 9511#elif defined(WOLFSSL_SILABS_SE_ACCEL)
 9512   err = silabs_ecc_verify_hash(&sigRS[0], keySz * 2,
 9513                                hash, hashlen,
 9514                                res, key);
 9515#elif defined(WOLFSSL_KCAPI_ECC)
 9516    err = KcapiEcc_Verify(key, hash, hashlen, sigRS, keySz * 2);
 9517    if (err == 0) {
 9518        *res = 1;
 9519    }
 9520#elif defined(WOLFSSL_SE050)
 9521    err = se050_ecc_verify_hash_ex(hash, hashlen, r, s, key, res);
 9522#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
 9523    if (hashlen > sizeof(hashcopy))
 9524        return ECC_BAD_ARG_E;
 9525    buf_reverse(hashcopy, hash, (hashlen < keySz) ? hashlen : keySz);
 9526    mp_reverse(sigRS, keySz);
 9527    mp_reverse(sigRS + keySz, keySz);
 9528    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(hashcopy), keySz);
 9529    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw), keySz * 2);
 9530    WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(sigRS), keySz * 2);
 9531
 9532    err = XSecure_EllipticVerifySign(&(key->xSec.cinst),
 9533                                     xil_curve_type[key->dp->id],
 9534                                     XIL_CAST_U64(hashcopy), keySz,
 9535                                     XIL_CAST_U64(key->keyRaw),
 9536                                     XIL_CAST_U64(sigRS));
 9537
 9538    if (err != XST_SUCCESS) {
 9539        WOLFSSL_XIL_ERROR("Verify ECC signature failed", err);
 9540        err = WC_HW_E;
 9541    } else {
 9542        *res = 1;
 9543    }
 9544#endif
 9545
 9546#else
 9547  /* checking if private key with no public part */
 9548  if (key->type == ECC_PRIVATEKEY_ONLY) {
 9549      WOLFSSL_MSG("Verify called with private key, generating public part");
 9550      ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
 9551      if (err != MP_OKAY) {
 9552          return err;
 9553      }
 9554      err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
 9555      if (err != MP_OKAY) {
 9556          FREE_CURVE_SPECS();
 9557          return err;
 9558      }
 9559      err = ecc_make_pub_ex(key, curve, NULL, NULL);
 9560      if (err != MP_OKAY) {
 9561           WOLFSSL_MSG("Unable to extract public key");
 9562           wc_ecc_curve_free(curve);
 9563           FREE_CURVE_SPECS();
 9564           return err;
 9565      }
 9566      curveLoaded = 1;
 9567  }
 9568
 9569  err = ecc_verify_hash_sp(r, s, hash, hashlen, res, key);
 9570  if (err != WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
 9571      if (curveLoaded) {
 9572           wc_ecc_curve_free(curve);
 9573           FREE_CURVE_SPECS();
 9574      }
 9575      return err;
 9576  }
 9577
 9578#if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
 9579   if (!curveLoaded) {
 9580       ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
 9581       if (err != 0) {
 9582          return err;
 9583       }
 9584       /* read in the specs for this curve */
 9585       err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
 9586       if (err != 0) {
 9587          FREE_CURVE_SPECS();
 9588          return err;
 9589       }
 9590   }
 9591
 9592   err = ecc_verify_hash(r, s, hash, hashlen, res, key, curve);
 9593#endif /* !WOLFSSL_SP_MATH || FREESCALE_LTC_ECC */
 9594
 9595   (void)curveLoaded;
 9596   wc_ecc_curve_free(curve);
 9597   FREE_CURVE_SPECS();
 9598#endif /* HAVE_ECC_VERIFY_HELPER */
 9599
 9600   (void)keySz;
 9601   (void)hashlen;
 9602
 9603   return err;
 9604#endif /* WOLFSSL_STM32_PKA */
 9605}
 9606#endif /* WOLF_CRYPTO_CB_ONLY_ECC */
 9607#endif /* HAVE_ECC_VERIFY */
 9608
 9609#ifdef HAVE_ECC_KEY_IMPORT
 9610/* import point from der
 9611 * if shortKeySize != 0 then keysize is always (inLen-1)>>1 */
 9612int wc_ecc_import_point_der_ex(const byte* in, word32 inLen,
 9613                               const int curve_idx, ecc_point* point,
 9614                               int shortKeySize)
 9615{
 9616    int err = 0;
 9617#ifdef HAVE_COMP_KEY
 9618    int compressed = 0;
 9619#endif
 9620    int keysize;
 9621    byte pointType;
 9622
 9623#ifndef HAVE_COMP_KEY
 9624    (void)shortKeySize;
 9625#endif
 9626
 9627    if (in == NULL || point == NULL || (curve_idx < 0) ||
 9628        (wc_ecc_is_valid_idx(curve_idx) == 0))
 9629        return ECC_BAD_ARG_E;
 9630
 9631    /* must be odd */
 9632    if ((inLen & 1) == 0) {
 9633        return ECC_BAD_ARG_E;
 9634    }
 9635
 9636    /* clear if previously allocated */
 9637    mp_clear(point->x);
 9638    mp_clear(point->y);
 9639    mp_clear(point->z);
 9640
 9641    /* init point */
 9642#ifdef ALT_ECC_SIZE
 9643    point->x = (mp_int*)&point->xyz[0];
 9644    point->y = (mp_int*)&point->xyz[1];
 9645    point->z = (mp_int*)&point->xyz[2];
 9646    alt_fp_init(point->x);
 9647    alt_fp_init(point->y);
 9648    alt_fp_init(point->z);
 9649#else
 9650    err = mp_init_multi(point->x, point->y, point->z, NULL, NULL, NULL);
 9651#endif
 9652    if (err != MP_OKAY)
 9653        return MEMORY_E;
 9654
 9655    SAVE_VECTOR_REGISTERS(return _svr_ret;);
 9656
 9657    /* check for point type (4, 2, or 3) */
 9658    pointType = in[0];
 9659    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
 9660                                         pointType != ECC_POINT_COMP_ODD) {
 9661        err = ASN_PARSE_E;
 9662    }
 9663
 9664    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
 9665#ifdef HAVE_COMP_KEY
 9666        compressed = 1;
 9667#else
 9668        err = NOT_COMPILED_IN;
 9669#endif
 9670    }
 9671
 9672    /* adjust to skip first byte */
 9673    inLen -= 1;
 9674    in += 1;
 9675
 9676    /* calculate key size based on inLen / 2 if uncompressed or shortKeySize
 9677     * is true */
 9678#ifdef HAVE_COMP_KEY
 9679    keysize = (int)((compressed && !shortKeySize) ? inLen : inLen>>1);
 9680#else
 9681    keysize = (int)(inLen>>1);
 9682#endif
 9683
 9684    /* sanity check that x coordinate is expected size */
 9685    if (err == MP_OKAY) {
 9686        if (keysize != ecc_sets[curve_idx].size) {
 9687            err = ECC_BAD_ARG_E;
 9688        }
 9689    }
 9690
 9691    /* read data */
 9692    if (err == MP_OKAY)
 9693        err = mp_read_unsigned_bin(point->x, in, (word32)keysize);
 9694
 9695#ifdef HAVE_COMP_KEY
 9696    if (err == MP_OKAY && compressed == 1) {   /* build y */
 9697    #if defined(WOLFSSL_HAVE_SP_ECC)
 9698        #ifndef WOLFSSL_SP_NO_256
 9699        if (curve_idx != ECC_CUSTOM_IDX &&
 9700                                      ecc_sets[curve_idx].id == ECC_SECP256R1) {
 9701            err = sp_ecc_uncompress_256(point->x, pointType, point->y);
 9702        }
 9703        else
 9704        #endif
 9705        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
 9706        if (curve_idx != ECC_CUSTOM_IDX &&
 9707                                      ecc_sets[curve_idx].id == ECC_SM2P256V1) {
 9708            err = sp_ecc_uncompress_sm2_256(point->x, pointType, point->y);
 9709        }
 9710        else
 9711        #endif
 9712        #ifdef WOLFSSL_SP_384
 9713        if (curve_idx != ECC_CUSTOM_IDX &&
 9714                                      ecc_sets[curve_idx].id == ECC_SECP384R1) {
 9715            err = sp_ecc_uncompress_384(point->x, pointType, point->y);
 9716        }
 9717        else
 9718        #endif
 9719        #ifdef WOLFSSL_SP_521
 9720        if (curve_idx != ECC_CUSTOM_IDX &&
 9721                                      ecc_sets[curve_idx].id == ECC_SECP521R1) {
 9722            err = sp_ecc_uncompress_521(point->x, pointType, point->y);
 9723        }
 9724        else
 9725        #endif
 9726    #endif
 9727    #if !defined(WOLFSSL_SP_MATH)
 9728        {
 9729            int did_init = 0;
 9730        #ifdef WOLFSSL_SMALL_STACK
 9731            mp_int* t1 = NULL;
 9732            mp_int* t2 = NULL;
 9733        #else
 9734            mp_int t1[1], t2[1];
 9735        #endif
 9736            DECLARE_CURVE_SPECS(3);
 9737
 9738            ALLOC_CURVE_SPECS(3, err);
 9739
 9740        #ifdef WOLFSSL_SMALL_STACK
 9741            if (err == MP_OKAY) {
 9742                t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
 9743                                      DYNAMIC_TYPE_BIGINT);
 9744                if (t1 == NULL) {
 9745                    err = MEMORY_E;
 9746                }
 9747            }
 9748            if (err == MP_OKAY) {
 9749                t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
 9750                                      DYNAMIC_TYPE_BIGINT);
 9751                if (t2 == NULL) {
 9752                    err = MEMORY_E;
 9753                }
 9754            }
 9755        #endif
 9756
 9757            if (err == MP_OKAY) {
 9758                if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
 9759                    err = MEMORY_E;
 9760                else
 9761                    did_init = 1;
 9762            }
 9763
 9764            /* load curve info */
 9765            if (err == MP_OKAY)
 9766                err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
 9767                    (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
 9768                        ECC_CURVE_FIELD_BF));
 9769
 9770        #if defined(WOLFSSL_CUSTOM_CURVES) && \
 9771            defined(WOLFSSL_VALIDATE_ECC_IMPORT)
 9772            /* validate prime is prime for custom curves */
 9773            if (err == MP_OKAY && curve_idx == ECC_CUSTOM_IDX) {
 9774                int isPrime = MP_NO;
 9775                err = mp_prime_is_prime(curve->prime, 8, &isPrime);
 9776                if (err == MP_OKAY && isPrime == MP_NO)
 9777                    err = MP_VAL;
 9778            }
 9779        #endif
 9780
 9781            /* compute x^3 */
 9782            if (err == MP_OKAY)
 9783                err = mp_sqr(point->x, t1);
 9784            if (err == MP_OKAY)
 9785                err = mp_mulmod(t1, point->x, curve->prime, t1);
 9786
 9787            /* compute x^3 + a*x */
 9788            if (err == MP_OKAY)
 9789                err = mp_mulmod(curve->Af, point->x, curve->prime, t2);
 9790            if (err == MP_OKAY)
 9791                err = mp_add(t1, t2, t1);
 9792
 9793            /* compute x^3 + a*x + b */
 9794            if (err == MP_OKAY)
 9795                err = mp_add(t1, curve->Bf, t1);
 9796
 9797            /* compute sqrt(x^3 + a*x + b) */
 9798            if (err == MP_OKAY)
 9799                err = mp_sqrtmod_prime(t1, curve->prime, t2);
 9800
 9801            /* adjust y */
 9802            if (err == MP_OKAY) {
 9803                if ((mp_isodd(t2) == MP_YES &&
 9804                                            pointType == ECC_POINT_COMP_ODD) ||
 9805                    (mp_isodd(t2) == MP_NO &&
 9806                                            pointType == ECC_POINT_COMP_EVEN)) {
 9807                    err = mp_mod(t2, curve->prime, point->y);
 9808                }
 9809                else {
 9810                    err = mp_submod(curve->prime, t2, curve->prime, point->y);
 9811                }
 9812            }
 9813
 9814            if (did_init) {
 9815                mp_clear(t2);
 9816                mp_clear(t1);
 9817            }
 9818
 9819            WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
 9820            WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
 9821
 9822            wc_ecc_curve_free(curve);
 9823            FREE_CURVE_SPECS();
 9824        }
 9825    #else
 9826        {
 9827            err = WC_KEY_SIZE_E;
 9828        }
 9829    #endif
 9830    }
 9831#endif
 9832
 9833    if (err == MP_OKAY) {
 9834#ifdef HAVE_COMP_KEY
 9835        if (compressed == 0)
 9836#endif
 9837            err = mp_read_unsigned_bin(point->y, in + keysize, (word32)keysize);
 9838    }
 9839    if (err == MP_OKAY)
 9840        err = mp_set(point->z, 1);
 9841
 9842    if (err != MP_OKAY) {
 9843        mp_clear(point->x);
 9844        mp_clear(point->y);
 9845        mp_clear(point->z);
 9846    }
 9847
 9848    RESTORE_VECTOR_REGISTERS();
 9849
 9850    return err;
 9851}
 9852
 9853/* function for backwards compatibility with previous implementations */
 9854int wc_ecc_import_point_der(const byte* in, word32 inLen, const int curve_idx,
 9855                            ecc_point* point)
 9856{
 9857    return wc_ecc_import_point_der_ex(in, inLen, curve_idx, point, 1);
 9858}
 9859#endif /* HAVE_ECC_KEY_IMPORT */
 9860
 9861#ifdef HAVE_ECC_KEY_EXPORT
 9862/* export point to der */
 9863
 9864int wc_ecc_export_point_der_ex(const int curve_idx, ecc_point* point, byte* out,
 9865                               word32* outLen, int compressed)
 9866{
 9867    if (compressed == 0)
 9868        return wc_ecc_export_point_der(curve_idx, point, out, outLen);
 9869#ifdef HAVE_COMP_KEY
 9870    else
 9871        return wc_ecc_export_point_der_compressed(curve_idx, point, out, outLen);
 9872#else
 9873    return NOT_COMPILED_IN;
 9874#endif
 9875}
 9876
 9877int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
 9878                            word32* outLen)
 9879{
 9880    int    ret = MP_OKAY;
 9881    word32 numlen;
 9882    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
 9883
 9884    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
 9885        return ECC_BAD_ARG_E;
 9886
 9887    numlen = (word32)ecc_sets[curve_idx].size;
 9888
 9889    /* return length needed only */
 9890    if (point != NULL && out == NULL && outLen != NULL) {
 9891        *outLen = 1 + 2*numlen;
 9892        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
 9893    }
 9894
 9895    if (point == NULL || out == NULL || outLen == NULL)
 9896        return ECC_BAD_ARG_E;
 9897
 9898    if (*outLen < (1 + 2*numlen)) {
 9899        *outLen = 1 + 2*numlen;
 9900        return BUFFER_E;
 9901    }
 9902
 9903    /* Sanity check the ordinates' sizes. */
 9904    if (((word32)mp_unsigned_bin_size(point->x) > numlen) ||
 9905        ((word32)mp_unsigned_bin_size(point->y) > numlen)) {
 9906        return ECC_BAD_ARG_E;
 9907    }
 9908
 9909    /* store byte point type */
 9910    out[0] = ECC_POINT_UNCOMP;
 9911
 9912    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
 9913        return MEMORY_E);
 9914
 9915    /* pad and store x */
 9916    XMEMSET(buf, 0, ECC_BUFSIZE);
 9917    ret = mp_to_unsigned_bin(point->x, buf +
 9918        (numlen - (word32)mp_unsigned_bin_size(point->x)));
 9919    if (ret != MP_OKAY)
 9920        goto done;
 9921    XMEMCPY(out+1, buf, numlen);
 9922
 9923    /* pad and store y */
 9924    XMEMSET(buf, 0, ECC_BUFSIZE);
 9925    ret = mp_to_unsigned_bin(point->y, buf +
 9926        (numlen - (word32)mp_unsigned_bin_size(point->y)));
 9927    if (ret != MP_OKAY)
 9928        goto done;
 9929    XMEMCPY(out+1+numlen, buf, numlen);
 9930
 9931    *outLen = 1 + 2*numlen;
 9932
 9933done:
 9934    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
 9935
 9936    return ret;
 9937}
 9938
 9939
 9940/* export point to der */
 9941#ifdef HAVE_COMP_KEY
 9942int wc_ecc_export_point_der_compressed(const int curve_idx, ecc_point* point,
 9943                                       byte* out, word32* outLen)
 9944{
 9945    int    ret = MP_OKAY;
 9946    word32 numlen;
 9947    word32 output_len;
 9948    WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
 9949
 9950    if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
 9951        return ECC_BAD_ARG_E;
 9952
 9953    numlen = (word32)ecc_sets[curve_idx].size;
 9954    output_len = 1 + numlen; /* y point type + x */
 9955
 9956    /* return length needed only */
 9957    if (point != NULL && out == NULL && outLen != NULL) {
 9958        *outLen = output_len;
 9959        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
 9960    }
 9961
 9962    if (point == NULL || out == NULL || outLen == NULL)
 9963        return ECC_BAD_ARG_E;
 9964
 9965
 9966    if (*outLen < output_len) {
 9967        *outLen = output_len;
 9968        return BUFFER_E;
 9969    }
 9970
 9971    /* Sanity check the ordinate's size. */
 9972    if ((word32)mp_unsigned_bin_size(point->x) > numlen) {
 9973        return ECC_BAD_ARG_E;
 9974    }
 9975
 9976    /* store byte point type */
 9977    out[0] = mp_isodd(point->y) == MP_YES ? ECC_POINT_COMP_ODD :
 9978                                            ECC_POINT_COMP_EVEN;
 9979
 9980    WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
 9981        return MEMORY_E);
 9982
 9983    /* pad and store x */
 9984    XMEMSET(buf, 0, ECC_BUFSIZE);
 9985    ret = mp_to_unsigned_bin(point->x, buf +
 9986                             (numlen - (word32)mp_unsigned_bin_size(point->x)));
 9987    if (ret != MP_OKAY)
 9988        goto done;
 9989    XMEMCPY(out+1, buf, numlen);
 9990
 9991    *outLen = output_len;
 9992
 9993done:
 9994    WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
 9995
 9996    return ret;
 9997}
 9998#endif /* HAVE_COMP_KEY */
 9999
10000/* Software-only export of public ECC key in ANSI X9.63 format.
10001 * This internal helper avoids recursion when called from the EXPORT_KEY path. */
10002static int _ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
10003{
10004   int    ret = MP_OKAY;
10005   word32 numlen;
10006   WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0);
10007   word32 pubxlen, pubylen;
10008
10009   /* return length needed only */
10010   if (key != NULL && out == NULL && outLen != NULL) {
10011      /* if key hasn't been setup assume max bytes for size estimation */
10012      numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
10013      /* X9.63 uncompressed point: 0x04 header + x coord + y coord */
10014      *outLen = 1 + 2 * numlen;
10015      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10016   }
10017
10018   if (key == NULL || out == NULL || outLen == NULL) {
10019      return ECC_BAD_ARG_E;
10020   }
10021
10022   if (key->type == ECC_PRIVATEKEY_ONLY) {
10023       return ECC_PRIVATEONLY_E;
10024   }
10025
10026#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
10027    /* check if public key in secure memory */
10028    if (key->securePubKey > 0) {
10029        int keySz = wc_ecc_size(key);
10030
10031        /* store byte point type */
10032        out[0] = ECC_POINT_UNCOMP;
10033
10034        if (caamReadPartition((CAAM_ADDRESS)key->securePubKey, out+1, keySz*2) != 0)
10035            return WC_HW_E;
10036
10037        *outLen = 1 + 2*keySz;
10038        return MP_OKAY;
10039    }
10040#endif
10041
10042   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
10043       return ECC_BAD_ARG_E;
10044   }
10045
10046   numlen = (word32)key->dp->size;
10047
10048    /* verify room in out buffer */
10049   if (*outLen < (1 + 2*numlen)) {
10050      *outLen = 1 + 2*numlen;
10051      return BUFFER_E;
10052   }
10053
10054   /* verify public key length is less than key size */
10055   pubxlen = (word32)mp_unsigned_bin_size(key->pubkey.x);
10056   pubylen = (word32)mp_unsigned_bin_size(key->pubkey.y);
10057   if ((pubxlen > numlen) || (pubylen > numlen)) {
10058      WOLFSSL_MSG("Public key x/y invalid!");
10059      return BUFFER_E;
10060   }
10061
10062   /* store byte point type */
10063   out[0] = ECC_POINT_UNCOMP;
10064
10065   WC_ALLOC_VAR_EX(buf, byte, ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER,
10066       return MEMORY_E);
10067
10068   /* pad and store x */
10069   XMEMSET(buf, 0, ECC_BUFSIZE);
10070   ret = mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - pubxlen));
10071   if (ret != MP_OKAY)
10072      goto done;
10073   XMEMCPY(out+1, buf, numlen);
10074
10075   /* pad and store y */
10076   XMEMSET(buf, 0, ECC_BUFSIZE);
10077   ret = mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - pubylen));
10078   if (ret != MP_OKAY)
10079      goto done;
10080   XMEMCPY(out+1+numlen, buf, numlen);
10081
10082   *outLen = 1 + 2*numlen;
10083
10084done:
10085   WC_FREE_VAR_EX(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
10086
10087   return ret;
10088}
10089
10090
10091/* export public ECC key in ANSI X9.63 format */
10092WOLFSSL_ABI
10093int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
10094{
10095#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
10096    int ret;
10097    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
10098#endif
10099
10100    if (key == NULL || outLen == NULL) {
10101        return ECC_BAD_ARG_E;
10102    }
10103
10104    /* return length needed only */
10105    if (out == NULL) {
10106        word32 numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
10107        /* X9.63 uncompressed point: 0x04 header + x coord + y coord */
10108        *outLen = 1 + 2 * numlen;
10109        return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
10110    }
10111
10112    if (key->type == ECC_PRIVATEKEY_ONLY) {
10113        return ECC_PRIVATEONLY_E;
10114    }
10115
10116#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
10117    #ifndef WOLF_CRYPTO_CB_FIND
10118    if (key->devId != INVALID_DEVID)
10119    #endif
10120    {
10121        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
10122        if (!WC_VAR_OK(tmpKey)) {
10123            return MEMORY_E;
10124        }
10125        XMEMSET(tmpKey, 0, sizeof(ecc_key));
10126
10127        ret = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
10128        if (ret != 0) {
10129            WC_FREE_VAR(tmpKey, key->heap);
10130            return ret;
10131        }
10132
10133        ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN,
10134                                     key, tmpKey);
10135        if (ret == 0) {
10136            /* Call software helper (no callback recursion) */
10137            ret = _ecc_export_x963(tmpKey, out, outLen);
10138        }
10139
10140        wc_ecc_free(tmpKey);
10141        WC_FREE_VAR(tmpKey, key->heap);
10142
10143        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
10144            return ret;
10145        }
10146    }
10147#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
10148
10149    return _ecc_export_x963(key, out, outLen);
10150}
10151
10152/* export public ECC key in ANSI X9.63 format, extended with
10153 * compression option */
10154WOLFSSL_ABI
10155int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen,
10156                          int compressed)
10157{
10158    if (compressed == 0) {
10159        return wc_ecc_export_x963(key, out, outLen);
10160    }
10161#ifdef HAVE_COMP_KEY
10162    else
10163        return wc_ecc_export_x963_compressed(key, out, outLen);
10164#else
10165    return NOT_COMPILED_IN;
10166#endif
10167}
10168#endif /* HAVE_ECC_KEY_EXPORT */
10169
10170
10171/* is ecc point on curve described by dp ? */
10172static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10173{
10174#if !defined(WOLFSSL_SP_MATH)
10175   int err;
10176#ifdef WOLFSSL_SMALL_STACK
10177   mp_int* t1;
10178   mp_int* t2;
10179#else
10180   mp_int  t1[1], t2[1];
10181#endif
10182
10183#ifdef WOLFSSL_SMALL_STACK
10184   t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10185   if (t1 == NULL)
10186       return MEMORY_E;
10187   t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
10188   if (t2 == NULL) {
10189       XFREE(t1, NULL, DYNAMIC_TYPE_ECC);
10190       return MEMORY_E;
10191   }
10192#endif
10193
10194   if ((err = mp_init_multi(t1, t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
10195      WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
10196      WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
10197      return err;
10198   }
10199
10200   SAVE_VECTOR_REGISTERS(err = _svr_ret;);
10201
10202   /* compute y^2 */
10203   if (err == MP_OKAY)
10204       err = mp_sqr(ecp->y, t1);
10205
10206   /* compute x^3 */
10207   if (err == MP_OKAY)
10208       err = mp_sqr(ecp->x, t2);
10209   if (err == MP_OKAY)
10210       err = mp_mod(t2, prime, t2);
10211   if (err == MP_OKAY)
10212       err = mp_mul(ecp->x, t2, t2);
10213
10214   /* compute y^2 - x^3 */
10215   if (err == MP_OKAY)
10216       err = mp_submod(t1, t2, prime, t1);
10217
10218   /* Determine if curve "a" should be used in calc */
10219#ifdef WOLFSSL_CUSTOM_CURVES
10220   if (err == MP_OKAY) {
10221      /* Use a and prime to determine if a == 3 */
10222      err = mp_set(t2, 0);
10223      if (err == MP_OKAY)
10224          err = mp_submod(prime, a, prime, t2);
10225   }
10226   if (err == MP_OKAY && mp_cmp_d(t2, 3) != MP_EQ) {
10227      /* compute y^2 - x^3 + a*x */
10228      if (err == MP_OKAY)
10229          err = mp_mulmod(t2, ecp->x, prime, t2);
10230      if (err == MP_OKAY)
10231          err = mp_addmod(t1, t2, prime, t1);
10232   }
10233   else
10234#endif /* WOLFSSL_CUSTOM_CURVES */
10235   {
10236      /* assumes "a" == 3 */
10237      (void)a;
10238
10239      /* compute y^2 - x^3 + 3x */
10240      if (err == MP_OKAY)
10241          err = mp_add(t1, ecp->x, t1);
10242      if (err == MP_OKAY)
10243          err = mp_add(t1, ecp->x, t1);
10244      if (err == MP_OKAY)
10245          err = mp_add(t1, ecp->x, t1);
10246      if (err == MP_OKAY)
10247          err = mp_mod(t1, prime, t1);
10248  }
10249
10250   /* adjust range (0, prime) */
10251   while (err == MP_OKAY && mp_isneg(t1)) {
10252      err = mp_add(t1, prime, t1);
10253   }
10254   while (err == MP_OKAY && mp_cmp(t1, prime) != MP_LT) {
10255      err = mp_sub(t1, prime, t1);
10256   }
10257
10258   /* compare to b */
10259   if (err == MP_OKAY) {
10260       if (mp_cmp(t1, b) != MP_EQ) {
10261          err = IS_POINT_E;
10262       } else {
10263          err = MP_OKAY;
10264       }
10265   }
10266
10267   mp_clear(t1);
10268   mp_clear(t2);
10269
10270   RESTORE_VECTOR_REGISTERS();
10271
10272   WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_ECC);
10273   WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_ECC);
10274
10275   return err;
10276#else
10277   (void)a;
10278   (void)b;
10279
10280#ifdef WOLFSSL_HAVE_SP_ECC
10281#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10282   if ((mp_count_bits(prime) == 256) && (!mp_is_bit_set(prime, 224))) {
10283       return sp_ecc_is_point_sm2_256(ecp->x, ecp->y);
10284   }
10285#endif
10286#ifndef WOLFSSL_SP_NO_256
10287   if (mp_count_bits(prime) == 256) {
10288       return sp_ecc_is_point_256(ecp->x, ecp->y);
10289   }
10290#endif
10291#ifdef WOLFSSL_SP_384
10292   if (mp_count_bits(prime) == 384) {
10293       return sp_ecc_is_point_384(ecp->x, ecp->y);
10294   }
10295#endif
10296#ifdef WOLFSSL_SP_521
10297   if (mp_count_bits(prime) == 521) {
10298       return sp_ecc_is_point_521(ecp->x, ecp->y);
10299   }
10300#endif
10301#else
10302   (void)ecp;
10303   (void)prime;
10304#endif
10305   return WC_KEY_SIZE_E;
10306#endif
10307}
10308
10309int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime)
10310{
10311    int err = MP_OKAY;
10312
10313    /* Validate parameters. */
10314    if ((ecp == NULL) || (a == NULL) || (b == NULL) || (prime == NULL)) {
10315        err = BAD_FUNC_ARG;
10316    }
10317
10318    if (err == MP_OKAY) {
10319        /* x must be in the range [0, p-1] */
10320        if ((mp_cmp(ecp->x, prime) != MP_LT) || mp_isneg(ecp->x)) {
10321            err = ECC_OUT_OF_RANGE_E;
10322        }
10323    }
10324
10325    if (err == MP_OKAY) {
10326        /* y must be in the range [0, p-1] */
10327        if ((mp_cmp(ecp->y, prime) != MP_LT) || mp_isneg(ecp->y)) {
10328            err = ECC_OUT_OF_RANGE_E;
10329        }
10330    }
10331
10332    if (err == MP_OKAY) {
10333        /* z must be one, that is point must be in affine form. */
10334        if (!mp_isone(ecp->z)) {
10335            err = ECC_BAD_ARG_E;
10336        }
10337    }
10338
10339    if (err == MP_OKAY) {
10340        /* Check x and y are valid for curve equation. */
10341        err = _ecc_is_point(ecp, a, b, prime);
10342    }
10343
10344    return err;
10345}
10346
10347#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER
10348
10349#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || \
10350    (defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_SP_MATH))) && \
10351    !defined(WOLFSSL_KCAPI_ECC) || defined(WOLFSSL_CAAM)
10352/* validate privkey * generator == pubkey, 0 on success */
10353static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
10354{
10355    int        err;
10356    ecc_point* base = NULL;
10357    ecc_point* res  = NULL;
10358#ifdef WOLFSSL_NO_MALLOC
10359    ecc_point lcl_base;
10360    ecc_point lcl_res;
10361#endif
10362    DECLARE_CURVE_SPECS(3);
10363
10364    if (key == NULL)
10365        return BAD_FUNC_ARG;
10366
10367    ALLOC_CURVE_SPECS(3, err);
10368    if (err != MP_OKAY) {
10369        WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
10370        return err;
10371    }
10372
10373#ifdef WOLFSSL_NO_MALLOC
10374    res = &lcl_res;
10375#endif
10376    err = wc_ecc_new_point_ex(&res, key->heap);
10377
10378#ifdef WOLFSSL_HAVE_SP_ECC
10379#ifndef WOLFSSL_SP_NO_256
10380    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10381        if (err == MP_OKAY) {
10382            err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
10383        }
10384    }
10385    else
10386#endif
10387#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10388    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10389        if (err == MP_OKAY) {
10390            err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
10391        }
10392    }
10393    else
10394#endif
10395#ifdef WOLFSSL_SP_384
10396    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10397        if (err == MP_OKAY) {
10398            err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
10399        }
10400    }
10401    else
10402#endif
10403#ifdef WOLFSSL_SP_521
10404    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10405        if (err == MP_OKAY) {
10406            err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
10407        }
10408    }
10409    else
10410#endif
10411#endif
10412    {
10413        if (err == MP_OKAY) {
10414        #ifdef WOLFSSL_NO_MALLOC
10415            base = &lcl_base;
10416        #endif
10417            err = wc_ecc_new_point_ex(&base, key->heap);
10418        }
10419
10420        if (err == MP_OKAY) {
10421            /* load curve info */
10422            err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_GX |
10423                                   ECC_CURVE_FIELD_GY | ECC_CURVE_FIELD_ORDER));
10424        }
10425
10426        /* set up base generator */
10427        if (err == MP_OKAY)
10428            err = mp_copy(curve->Gx, base->x);
10429        if (err == MP_OKAY)
10430            err = mp_copy(curve->Gy, base->y);
10431        if (err == MP_OKAY)
10432            err = mp_set(base->z, 1);
10433
10434#ifdef WOLFSSL_KCAPI_ECC
10435        if (err == MP_OKAY) {
10436            word32 pubkey_sz = (word32)key->dp->size*2;
10437            if (key->handle == NULL) {
10438                /* if handle loaded, then pubkey_raw already populated */
10439                err = KcapiEcc_LoadKey(key, key->pubkey_raw, &pubkey_sz, 1);
10440            }
10441            if (err == 0) {
10442                err = mp_read_unsigned_bin(res->x, key->pubkey_raw,
10443                                           pubkey_sz/2);
10444            }
10445            if (err == MP_OKAY) {
10446                err = mp_read_unsigned_bin(res->y,
10447                                           key->pubkey_raw + pubkey_sz/2,
10448                                           pubkey_sz/2);
10449            }
10450            if (err == MP_OKAY) {
10451                err = mp_set(res->z, 1);
10452            }
10453        }
10454        (void)a;
10455        (void)prime;
10456#else
10457#ifdef ECC_TIMING_RESISTANT
10458        if (err == MP_OKAY)
10459            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10460                                          curve->order, key->rng, 1, key->heap);
10461#else
10462        if (err == MP_OKAY)
10463            err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
10464                                              curve->order, NULL, 1, key->heap);
10465#endif
10466#endif /* WOLFSSL_KCAPI_ECC */
10467    }
10468
10469    if (err == MP_OKAY) {
10470        /* compare result to public key */
10471        if (mp_cmp(res->x, key->pubkey.x) != MP_EQ ||
10472            mp_cmp(res->y, key->pubkey.y) != MP_EQ ||
10473            mp_cmp(res->z, key->pubkey.z) != MP_EQ) {
10474            /* didn't match */
10475            err = ECC_PRIV_KEY_E;
10476        }
10477    }
10478
10479    wc_ecc_curve_free(curve);
10480    wc_ecc_del_point_ex(res, key->heap);
10481    wc_ecc_del_point_ex(base, key->heap);
10482    FREE_CURVE_SPECS();
10483
10484    return err;
10485}
10486#endif /* FIPS_VERSION_GE(5,0) || WOLFSSL_VALIDATE_ECC_KEYGEN ||
10487        * (!WOLFSSL_SP_MATH && WOLFSSL_VALIDATE_ECC_IMPORT) */
10488
10489#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
10490    !defined(WOLFSSL_KCAPI_ECC) && defined(HAVE_ECC_DHE)
10491
10492/* check privkey generator helper, creates prime needed */
10493static int ecc_check_privkey_gen_helper(ecc_key* key)
10494{
10495    int    err;
10496#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
10497    !defined(WOLFSSL_MICROCHIP_TA100)
10498    DECLARE_CURVE_SPECS(2);
10499#endif
10500
10501    if (key == NULL)
10502        return BAD_FUNC_ARG;
10503
10504#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
10505    defined(WOLFSSL_MICROCHIP_TA100)
10506    /* Hardware based private key, so this operation is not supported */
10507    err = MP_OKAY; /* just report success */
10508#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10509    /* Hardware based private key, so this operation is not supported */
10510    err = MP_OKAY; /* just report success */
10511#elif defined(WOLFSSL_KCAPI_ECC)
10512    /* Hardware based private key, so this operation is not supported */
10513    err = MP_OKAY; /* just report success */
10514#else
10515    ALLOC_CURVE_SPECS(2, err);
10516
10517    /* load curve info */
10518    if (err == MP_OKAY)
10519        err = wc_ecc_curve_load(key->dp, &curve,
10520            (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
10521
10522    if (err == MP_OKAY)
10523        err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10524
10525    wc_ecc_curve_free(curve);
10526    FREE_CURVE_SPECS();
10527
10528#endif /* WOLFSSL_ATECC508A */
10529
10530    return err;
10531}
10532
10533/* Performs a Pairwise Consistency Test on an ECC key pair. */
10534static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng)
10535{
10536    int err = 0;
10537    word32 flags = key->flags;
10538
10539    /* If flags not set default to cofactor and dec/sign */
10540    if ((flags & (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN)) == 0) {
10541        flags = (WC_ECC_FLAG_COFACTOR | WC_ECC_FLAG_DEC_SIGN);
10542    }
10543
10544    if (flags & WC_ECC_FLAG_COFACTOR) {
10545        err = ecc_check_privkey_gen_helper(key);
10546    }
10547
10548    if (!err && (flags & WC_ECC_FLAG_DEC_SIGN)) {
10549#ifndef WOLFSSL_SMALL_STACK
10550        #define SIG_SZ ((MAX_ECC_BYTES * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ)
10551        byte sig[SIG_SZ + WC_SHA256_DIGEST_SIZE];
10552#else
10553        byte* sig;
10554#endif
10555        byte* digest;
10556        word32 sigLen, digestLen;
10557        int dynRng = 0, res = 0;
10558
10559        sigLen = (word32)wc_ecc_sig_size(key);
10560        digestLen = WC_SHA256_DIGEST_SIZE;
10561        WC_ALLOC_VAR_EX(sig, byte, sigLen+digestLen, key->heap,
10562            DYNAMIC_TYPE_ECC, return MEMORY_E);
10563        digest = sig + sigLen;
10564
10565        if (rng == NULL) {
10566            dynRng = 1;
10567            rng = wc_rng_new(NULL, 0, key->heap);
10568            if (rng == NULL) {
10569                WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10570                return MEMORY_E;
10571            }
10572        }
10573
10574        err = wc_RNG_GenerateBlock(rng, digest, digestLen);
10575
10576        if (!err)
10577            err = wc_ecc_sign_hash(digest, WC_SHA256_DIGEST_SIZE, sig, &sigLen,
10578                    rng, key);
10579        if (!err)
10580            err = wc_ecc_verify_hash(sig, sigLen,
10581                    digest, WC_SHA256_DIGEST_SIZE, &res, key);
10582
10583        if (res == 0)
10584            err = ECC_PCT_E;
10585
10586        if (dynRng) {
10587            wc_rng_free(rng);
10588        }
10589        ForceZero(sig, sigLen + digestLen);
10590        WC_FREE_VAR_EX(sig, key->heap, DYNAMIC_TYPE_ECC);
10591    }
10592    (void)rng;
10593
10594    if (err != 0)
10595        err = ECC_PCT_E;
10596
10597    return err;
10598}
10599#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \
10600          !WOLFSSL_KCAPI_ECC && HAVE_ECC_DHE */
10601
10602#ifndef WOLFSSL_SP_MATH
10603/* validate order * pubkey = point at infinity, 0 on success */
10604static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a,
10605        mp_int* prime, mp_int* order)
10606{
10607    ecc_point* inf = NULL;
10608#ifdef WOLFSSL_NO_MALLOC
10609    ecc_point  lcl_inf;
10610#endif
10611    int err;
10612
10613    if (key == NULL)
10614        return BAD_FUNC_ARG;
10615   if (mp_count_bits(pubkey->x) > mp_count_bits(prime) ||
10616       mp_count_bits(pubkey->y) > mp_count_bits(prime) ||
10617       mp_count_bits(pubkey->z) > mp_count_bits(prime)) {
10618       return IS_POINT_E;
10619   }
10620
10621#ifdef WOLFSSL_NO_MALLOC
10622    inf = &lcl_inf;
10623#endif
10624    err = wc_ecc_new_point_ex(&inf, key->heap);
10625    if (err == MP_OKAY) {
10626#ifdef WOLFSSL_HAVE_SP_ECC
10627#ifndef WOLFSSL_SP_NO_256
10628        if (key->idx != ECC_CUSTOM_IDX &&
10629                                       ecc_sets[key->idx].id == ECC_SECP256R1) {
10630            err = sp_ecc_mulmod_256(order, pubkey, inf, 1, key->heap);
10631        }
10632        else
10633#endif
10634#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10635        if (key->idx != ECC_CUSTOM_IDX &&
10636                                       ecc_sets[key->idx].id == ECC_SM2P256V1) {
10637            err = sp_ecc_mulmod_sm2_256(order, pubkey, inf, 1, key->heap);
10638        }
10639        else
10640#endif
10641#ifdef WOLFSSL_SP_384
10642        if (key->idx != ECC_CUSTOM_IDX &&
10643                                       ecc_sets[key->idx].id == ECC_SECP384R1) {
10644            err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap);
10645        }
10646        else
10647#endif
10648#ifdef WOLFSSL_SP_521
10649        if (key->idx != ECC_CUSTOM_IDX &&
10650                                       ecc_sets[key->idx].id == ECC_SECP521R1) {
10651            err = sp_ecc_mulmod_521(order, pubkey, inf, 1, key->heap);
10652        }
10653        else
10654#endif
10655#endif
10656#if !defined(WOLFSSL_SP_MATH)
10657            err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap);
10658        if (err == MP_OKAY && !wc_ecc_point_is_at_infinity(inf))
10659            err = ECC_INF_E;
10660#else
10661        {
10662            (void)a;
10663            (void)prime;
10664
10665            err = WC_KEY_SIZE_E;
10666        }
10667#endif
10668    }
10669
10670    wc_ecc_del_point_ex(inf, key->heap);
10671
10672    return err;
10673}
10674#endif /* !WOLFSSL_SP_MATH */
10675#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10676
10677
10678#ifdef OPENSSL_EXTRA
10679int wc_ecc_get_generator(ecc_point* ecp, int curve_idx)
10680{
10681    int err = MP_OKAY;
10682    DECLARE_CURVE_SPECS(2);
10683
10684    if (!ecp || curve_idx < 0 || curve_idx > (int)(ECC_SET_COUNT-1))
10685        return BAD_FUNC_ARG;
10686
10687    ALLOC_CURVE_SPECS(2, err);
10688
10689    if (err == MP_OKAY)
10690        err = wc_ecc_curve_load(&ecc_sets[curve_idx], &curve,
10691                            (ECC_CURVE_FIELD_GX | ECC_CURVE_FIELD_GY));
10692    if (err == MP_OKAY)
10693        err = mp_copy(curve->Gx, ecp->x);
10694    if (err == MP_OKAY)
10695        err = mp_copy(curve->Gy, ecp->y);
10696    if (err == MP_OKAY)
10697        err = mp_set(ecp->z, 1);
10698
10699    wc_ecc_curve_free(curve);
10700    FREE_CURVE_SPECS();
10701
10702    return err;
10703}
10704#endif /* OPENSSL_EXTRA */
10705
10706
10707/* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3,
10708 * ECC Full Public Key Validation Routine. If the parameter
10709 * partial is set, then it follows section 5.6.2.3.4, the ECC
10710 * Partial Public Key Validation Routine.
10711 * If the parameter priv is set, add in a few extra
10712 * checks on the bounds of the private key. */
10713static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
10714{
10715    int err = MP_OKAY;
10716#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH)
10717    mp_int* b = NULL;
10718    DECLARE_CURVE_SPECS(4);
10719#endif
10720
10721    ASSERT_SAVED_VECTOR_REGISTERS();
10722
10723    if (key == NULL)
10724        return BAD_FUNC_ARG;
10725
10726#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER
10727    /* consider key check success on HW crypto
10728     * ex: ATECC508/608A, CryptoCell and Silabs
10729     *
10730     * consider key check success on most Crypt Cb only builds
10731     */
10732    err = MP_OKAY;
10733
10734#else
10735
10736#ifdef WOLFSSL_HAVE_SP_ECC
10737#ifndef WOLFSSL_SP_NO_256
10738    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
10739        return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
10740            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10741    }
10742#endif
10743#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
10744    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
10745        return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
10746            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10747    }
10748#endif
10749#ifdef WOLFSSL_SP_384
10750    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
10751        return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
10752            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10753    }
10754#endif
10755#ifdef WOLFSSL_SP_521
10756    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
10757        return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
10758            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10759    }
10760#endif
10761#if defined(WOLFSSL_SP_1024) && defined(WOLFCRYPT_HAVE_SAKKE)
10762    if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
10763        return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
10764            key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
10765    }
10766#endif
10767#endif
10768
10769#ifndef WOLFSSL_SP_MATH
10770    ALLOC_CURVE_SPECS(4, err);
10771
10772    #ifdef WOLFSSL_CAAM
10773    /* keys can be black encrypted ones which can not be checked like plain text
10774     * keys */
10775    if (key->blackKey > 0) {
10776        /* encrypted key was used */
10777        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10778        FREE_CURVE_SPECS();
10779        return 0;
10780    }
10781    #endif
10782
10783    /* SP 800-56Ar3, section 5.6.2.3.3, process step 1 */
10784    /* SP 800-56Ar3, section 5.6.2.3.4, process step 1 */
10785    /* pubkey point cannot be at infinity */
10786    if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
10787        WC_FREE_VAR_EX(b, key->heap, DYNAMIC_TYPE_ECC);
10788        FREE_CURVE_SPECS();
10789        return ECC_INF_E;
10790    }
10791
10792    /* load curve info */
10793    if (err == MP_OKAY)
10794        err = wc_ecc_curve_load(key->dp, &curve, (ECC_CURVE_FIELD_PRIME |
10795            ECC_CURVE_FIELD_AF | ECC_CURVE_FIELD_ORDER | ECC_CURVE_FIELD_BF));
10796
10797    if (err == MP_OKAY)
10798        b = curve->Bf;
10799
10800    /* SP 800-56Ar3, section 5.6.2.3.3, process step 2 */
10801    /* SP 800-56Ar3, section 5.6.2.3.4, process step 2 */
10802    /* Qx must be in the range [0, p-1] */
10803    if (err == MP_OKAY) {
10804        if ((mp_cmp(key->pubkey.x, curve->prime) != MP_LT) ||
10805                mp_isneg(key->pubkey.x)) {
10806            err = ECC_OUT_OF_RANGE_E;
10807        }
10808    }
10809
10810    /* Qy must be in the range [0, p-1] */
10811    if (err == MP_OKAY) {
10812        if ((mp_cmp(key->pubkey.y, curve->prime) != MP_LT) ||
10813                mp_isneg(key->pubkey.y)) {
10814            err = ECC_OUT_OF_RANGE_E;
10815        }
10816    }
10817
10818    /* SP 800-56Ar3, section 5.6.2.3.3, process step 3 */
10819    /* SP 800-56Ar3, section 5.6.2.3.4, process step 3 */
10820    /* make sure point is actually on curve */
10821    if (err == MP_OKAY)
10822        err = _ecc_is_point(&key->pubkey, curve->Af, b, curve->prime);
10823
10824    if (!partial) {
10825        /* SP 800-56Ar3, section 5.6.2.3.3, process step 4 */
10826        /* pubkey * order must be at infinity */
10827        if (err == MP_OKAY)
10828            err = ecc_check_pubkey_order(key, &key->pubkey, curve->Af,
10829                    curve->prime, curve->order);
10830    }
10831
10832    if (priv) {
10833        /* SP 800-56Ar3, section 5.6.2.1.2 */
10834        /* private keys must be in the range [1, n-1] */
10835        if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
10836            (mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
10837            (mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
10838        #ifdef WOLFSSL_KCAPI_ECC
10839            && key->handle == NULL
10840        #endif
10841        ) {
10842            err = ECC_PRIV_KEY_E;
10843        }
10844
10845    #if defined(WOLFSSL_VALIDATE_ECC_IMPORT) || defined(WOLFSSL_CAAM)
10846        /* SP 800-56Ar3, section 5.6.2.1.4, method (b) for ECC */
10847        /* private * base generator must equal pubkey */
10848        if (err == MP_OKAY && key->type == ECC_PRIVATEKEY)
10849            err = ecc_check_privkey_gen(key, curve->Af, curve->prime);
10850    #endif
10851    }
10852
10853    wc_ecc_curve_free(curve);
10854
10855    FREE_CURVE_SPECS();
10856
10857#else
10858    /* The single precision math curve is not available */
10859    err = WC_KEY_SIZE_E;
10860#endif /* !WOLFSSL_SP_MATH */
10861#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */
10862
10863    (void)partial;
10864    (void)priv;
10865    return err;
10866}
10867
10868
10869/* perform sanity checks on ecc key validity, 0 on success */
10870WOLFSSL_ABI
10871int wc_ecc_check_key(ecc_key* key)
10872{
10873    int ret;
10874    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10875    ret = _ecc_validate_public_key(key, 0, 1);
10876    RESTORE_VECTOR_REGISTERS();
10877    return ret;
10878}
10879
10880
10881#ifdef HAVE_ECC_KEY_IMPORT
10882/* Software-only import of public ECC key in ANSI X9.63 format.
10883 * This internal helper avoids recursion when called from the SETKEY path. */
10884static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
10885                                int curve_id, int untrusted)
10886{
10887    int err = MP_OKAY;
10888#ifdef HAVE_COMP_KEY
10889    int compressed = 0;
10890#endif
10891    int keysize = 0;
10892    byte pointType;
10893#ifdef WOLFSSL_CRYPTOCELL
10894    const CRYS_ECPKI_Domain_t* pDomain;
10895    CRYS_ECPKI_BUILD_TempData_t tempBuff;
10896#endif
10897
10898    if (in == NULL || key == NULL) {
10899        return BAD_FUNC_ARG;
10900    }
10901
10902    /* must be odd */
10903    if ((inLen & 1) == 0) {
10904        return ECC_BAD_ARG_E;
10905    }
10906
10907    /* make sure required variables are reset */
10908    wc_ecc_reset(key);
10909
10910    /* init key */
10911    #ifdef ALT_ECC_SIZE
10912        key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
10913        key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
10914        key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
10915        alt_fp_init(key->pubkey.x);
10916        alt_fp_init(key->pubkey.y);
10917        alt_fp_init(key->pubkey.z);
10918        key->k = (mp_int*)key->ka;
10919        alt_fp_init(key->k);
10920    #ifdef WOLFSSL_ECC_BLIND_K
10921        key->kb = (mp_int*)key->kba;
10922        key->ku = (mp_int*)key->kua;
10923        alt_fp_init(key->kb);
10924        alt_fp_init(key->ku);
10925    #endif
10926    #else
10927        err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
10928    #ifndef WOLFSSL_ECC_BLIND_K
10929                                                                      NULL, NULL
10930    #else
10931                                                                key->kb, key->ku
10932    #endif
10933                            );
10934    #endif
10935    if (err != MP_OKAY)
10936        return MEMORY_E;
10937#ifdef WOLFSSL_ECC_BLIND_K
10938    mp_forcezero(key->kb);
10939#endif
10940
10941    SAVE_VECTOR_REGISTERS(return _svr_ret;);
10942
10943    /* check for point type (4, 2, or 3) */
10944    pointType = in[0];
10945    if (pointType != ECC_POINT_UNCOMP && pointType != ECC_POINT_COMP_EVEN &&
10946                                         pointType != ECC_POINT_COMP_ODD) {
10947        err = ASN_PARSE_E;
10948    }
10949
10950    if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) {
10951    #ifdef HAVE_COMP_KEY
10952        compressed = 1;
10953    #else
10954        err = NOT_COMPILED_IN;
10955    #endif
10956    }
10957
10958    /* adjust to skip first byte */
10959    inLen -= 1;
10960    in += 1;
10961
10962#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
10963    defined(WOLFSSL_MICROCHIP_TA100)
10964    /* For SECP256R1 only save raw public key for hardware */
10965    if (curve_id == ECC_SECP256R1 && inLen <= (word32)sizeof(key->pubkey_raw)) {
10966    #ifdef HAVE_COMP_KEY
10967        if (!compressed)
10968    #endif
10969            XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10970    }
10971#elif defined(WOLFSSL_KCAPI_ECC)
10972    if (inLen <= (word32)sizeof(key->pubkey_raw))
10973        XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
10974    else
10975        err = BAD_FUNC_ARG;
10976#endif
10977
10978    if (err == MP_OKAY) {
10979    #ifdef HAVE_COMP_KEY
10980        /* adjust inLen if compressed */
10981        if (compressed)
10982            inLen = inLen*2 + 1;  /* used uncompressed len */
10983    #endif
10984
10985        /* determine key size */
10986        keysize = (int)(inLen>>1);
10987        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
10988         *       on created keys or signatures */
10989        err = wc_ecc_set_curve(key, keysize, curve_id);
10990        key->type = ECC_PUBLICKEY;
10991    }
10992
10993    /* read data */
10994    if (err == MP_OKAY)
10995        err = mp_read_unsigned_bin(key->pubkey.x, in, (word32)keysize);
10996
10997#ifdef HAVE_COMP_KEY
10998    if (err == MP_OKAY && compressed == 1) {   /* build y */
10999#if !defined(WOLFSSL_SP_MATH)
11000    #ifdef WOLFSSL_SMALL_STACK
11001        mp_int* t1 = NULL;
11002        mp_int* t2 = NULL;
11003    #else
11004        mp_int t1[1], t2[1];
11005    #endif
11006        int did_init = 0;
11007
11008        DECLARE_CURVE_SPECS(3);
11009        ALLOC_CURVE_SPECS(3, err);
11010
11011        #ifdef WOLFSSL_SMALL_STACK
11012        if (err == MP_OKAY) {
11013            t1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11014            if (t1 == NULL) {
11015                err = MEMORY_E;
11016            }
11017        }
11018        if (err == MP_OKAY) {
11019            t2 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
11020            if (t2 == NULL) {
11021                err = MEMORY_E;
11022            }
11023        }
11024        #endif
11025        if (err == MP_OKAY) {
11026            if (mp_init_multi(t1, t2, NULL, NULL, NULL, NULL) != MP_OKAY)
11027                err = MEMORY_E;
11028            else
11029                did_init = 1;
11030        }
11031
11032        /* load curve info */
11033        if (err == MP_OKAY)
11034            err = wc_ecc_curve_load(key->dp, &curve,
11035                (ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF |
11036                 ECC_CURVE_FIELD_BF));
11037
11038    #if defined(WOLFSSL_CUSTOM_CURVES) && \
11039        defined(WOLFSSL_VALIDATE_ECC_IMPORT)
11040        /* validate prime is prime for custom curves */
11041        if (err == MP_OKAY && key->idx == ECC_CUSTOM_IDX) {
11042            int isPrime = MP_NO;
11043            err = mp_prime_is_prime(curve->prime, 8, &isPrime);
11044            if (err == MP_OKAY && isPrime == MP_NO)
11045                err = MP_VAL;
11046        }
11047    #endif
11048
11049        /* compute x^3 */
11050        if (err == MP_OKAY)
11051            err = mp_sqrmod(key->pubkey.x, curve->prime, t1);
11052        if (err == MP_OKAY)
11053            err = mp_mulmod(t1, key->pubkey.x, curve->prime, t1);
11054
11055        /* compute x^3 + a*x */
11056        if (err == MP_OKAY)
11057            err = mp_mulmod(curve->Af, key->pubkey.x, curve->prime, t2);
11058        if (err == MP_OKAY)
11059            err = mp_add(t1, t2, t1);
11060
11061        /* compute x^3 + a*x + b */
11062        if (err == MP_OKAY)
11063            err = mp_add(t1, curve->Bf, t1);
11064
11065        /* compute sqrt(x^3 + a*x + b) */
11066        if (err == MP_OKAY)
11067            err = mp_sqrtmod_prime(t1, curve->prime, t2);
11068
11069        /* adjust y */
11070        if (err == MP_OKAY) {
11071            if ((mp_isodd(t2) == MP_YES && pointType == ECC_POINT_COMP_ODD) ||
11072                (mp_isodd(t2) == MP_NO &&  pointType == ECC_POINT_COMP_EVEN)) {
11073                err = mp_mod(t2, curve->prime, t2);
11074            }
11075            else {
11076                err = mp_submod(curve->prime, t2, curve->prime, t2);
11077            }
11078            if (err == MP_OKAY)
11079                err = mp_copy(t2, key->pubkey.y);
11080        }
11081
11082        if (did_init) {
11083            mp_clear(t2);
11084            mp_clear(t1);
11085        }
11086        WC_FREE_VAR_EX(t1, NULL, DYNAMIC_TYPE_BIGINT);
11087        WC_FREE_VAR_EX(t2, NULL, DYNAMIC_TYPE_BIGINT);
11088
11089        wc_ecc_curve_free(curve);
11090        FREE_CURVE_SPECS();
11091#else
11092    #ifndef WOLFSSL_SP_NO_256
11093        if (key->dp->id == ECC_SECP256R1) {
11094            err = sp_ecc_uncompress_256(key->pubkey.x, pointType,
11095                key->pubkey.y);
11096        }
11097        else
11098    #endif
11099    #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11100        if (key->dp->id == ECC_SM2P256V1) {
11101            err = sp_ecc_uncompress_sm2_256(key->pubkey.x, pointType, key->pubkey.y);
11102        }
11103        else
11104    #endif
11105    #ifdef WOLFSSL_SP_384
11106        if (key->dp->id == ECC_SECP384R1) {
11107            err = sp_ecc_uncompress_384(key->pubkey.x, pointType,
11108                key->pubkey.y);
11109        }
11110        else
11111    #endif
11112    #ifdef WOLFSSL_SP_521
11113        if (key->dp->id == ECC_SECP521R1) {
11114            err = sp_ecc_uncompress_521(key->pubkey.x, pointType,
11115                key->pubkey.y);
11116        }
11117        else
11118    #endif
11119        {
11120            err = WC_KEY_SIZE_E;
11121        }
11122#endif
11123    }
11124#endif /* HAVE_COMP_KEY */
11125
11126    if (err == MP_OKAY) {
11127    #ifdef HAVE_COMP_KEY
11128        if (compressed == 0)
11129    #endif
11130        {
11131            err = mp_read_unsigned_bin(key->pubkey.y, in + keysize,
11132                (word32)keysize);
11133        }
11134    }
11135    if (err == MP_OKAY)
11136        err = mp_set(key->pubkey.z, 1);
11137
11138#ifdef WOLFSSL_CRYPTOCELL
11139    if (err == MP_OKAY) {
11140        pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11141
11142        /* create public key from external key buffer */
11143        err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
11144                                               (byte*)in-1, /* re-adjust */
11145                                               inLen+1,     /* original input */
11146                                               &key->ctx.pubKey,
11147                                               &tempBuff);
11148
11149        if (err != SA_SILIB_RET_OK){
11150            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
11151        }
11152    }
11153#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11154    if (err == MP_OKAY)
11155        err = silabs_ecc_import(key, keysize, 1, 0);
11156#elif defined(WOLFSSL_SE050)
11157    if (err == MP_OKAY) {
11158        /* reset key ID, in case used before */
11159        key->keyId = 0;
11160        key->keyIdSet = 0;
11161    }
11162#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
11163    #ifndef HAVE_COMP_KEY
11164    if (err == MP_OKAY) {
11165    #else
11166    if (err == MP_OKAY && !compressed) {
11167    #endif
11168        buf_reverse(&key->keyRaw[0], &in[0], keysize);
11169        buf_reverse(&key->keyRaw[keysize], &in[keysize], keysize);
11170    }
11171#endif
11172#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11173    if (err == MP_OKAY)
11174        err = wc_ecc_check_key(key);
11175#endif
11176#if (!defined(WOLFSSL_VALIDATE_ECC_IMPORT) || \
11177     !defined(HAVE_ECC_CHECK_PUBKEY_ORDER)) && \
11178     !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
11179     !defined(WOLFSSL_CRYPTOCELL) && \
11180     (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \
11181       defined(WOLFSSL_IMXRT1170_CAAM))
11182    if ((err == MP_OKAY) && untrusted) {
11183        /* Reject point at infinity. */
11184        if (wc_ecc_point_is_at_infinity(&key->pubkey)) {
11185            err = ECC_INF_E;
11186        }
11187        /* Verify the point lies on the curve (y^2 = x^3 + ax + b mod p) */
11188        if ((err == MP_OKAY) && (key->idx != ECC_CUSTOM_IDX)) {
11189    #ifdef WOLFSSL_HAVE_SP_ECC
11190        #ifndef WOLFSSL_SP_NO_256
11191            if (ecc_sets[key->idx].id == ECC_SECP256R1) {
11192                err = sp_ecc_is_point_256(key->pubkey.x, key->pubkey.y);
11193            #if defined(WOLFSSL_SM2)
11194                if (err != MP_OKAY && curve_id < 0) {
11195                    /* Retry with SM2 curve when P-256 returns invalid.
11196                     * Only when no explicit curve was requested (curve_id < 0).
11197                     * Needed because SM2 keys can be mis-identified as
11198                     * SECP256R1 during parsing. */
11199                #if defined(WOLFSSL_SP_SM2)
11200                    err = sp_ecc_is_point_sm2_256(key->pubkey.x,
11201                                                  key->pubkey.y);
11202                #else
11203                    int sm2_idx = wc_ecc_get_curve_idx(ECC_SM2P256V1);
11204                    if (sm2_idx != ECC_CURVE_INVALID)
11205                        err = wc_ecc_point_is_on_curve(&key->pubkey, sm2_idx);
11206                #endif
11207                    if (err == MP_OKAY) {
11208                        err = wc_ecc_set_curve(key, WOLFSSL_SM2_KEY_BITS / 8,
11209                                               ECC_SM2P256V1);
11210                    }
11211                }
11212            #endif
11213            }
11214            else
11215        #endif
11216        #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
11217            if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
11218                err = sp_ecc_is_point_sm2_256(key->pubkey.x, key->pubkey.y);
11219            }
11220            else
11221        #endif
11222        #ifdef WOLFSSL_SP_384
11223            if (ecc_sets[key->idx].id == ECC_SECP384R1) {
11224                err = sp_ecc_is_point_384(key->pubkey.x, key->pubkey.y);
11225            }
11226            else
11227        #endif
11228        #ifdef WOLFSSL_SP_521
11229            if (ecc_sets[key->idx].id == ECC_SECP521R1) {
11230                err = sp_ecc_is_point_521(key->pubkey.x, key->pubkey.y);
11231            }
11232            else
11233        #endif
11234            {
11235                err = wc_ecc_point_is_on_curve(&key->pubkey, key->idx);
11236            }
11237    #else
11238            err = wc_ecc_point_is_on_curve(&key->pubkey, key->idx);
11239        #if defined(WOLFSSL_SM2)
11240            if (err != MP_OKAY && curve_id < 0) {
11241                /* Retry with SM2 curve when P-256 returns invalid.
11242                 * Only when no explicit curve was requested (curve_id < 0).
11243                 * Needed because SM2 keys can be mis-identified as
11244                 * SECP256R1 during parsing. */
11245                int sm2_idx = wc_ecc_get_curve_idx(ECC_SM2P256V1);
11246                if (sm2_idx != ECC_CURVE_INVALID) {
11247                    err = wc_ecc_point_is_on_curve(&key->pubkey, sm2_idx);
11248                    if (err == MP_OKAY) {
11249                        err = wc_ecc_set_curve(key, WOLFSSL_SM2_KEY_BITS / 8,
11250                                               ECC_SM2P256V1);
11251                    }
11252                }
11253            }
11254        #endif
11255    #endif /* WOLFSSL_HAVE_SP_ECC */
11256        }
11257    }
11258#endif
11259    (void)untrusted;
11260
11261#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11262    if (err == MP_OKAY) {
11263        err = wc_MAXQ10XX_EccSetKey(key, keysize);
11264    }
11265#endif
11266
11267    if (err != MP_OKAY) {
11268        mp_clear(key->pubkey.x);
11269        mp_clear(key->pubkey.y);
11270        mp_clear(key->pubkey.z);
11271        mp_forcezero(key->k);
11272    }
11273
11274    RESTORE_VECTOR_REGISTERS();
11275
11276    return err;
11277}
11278
11279/* import public ECC key in ANSI X9.63 format */
11280int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
11281                           int curve_id, int untrusted)
11282{
11283#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
11284    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
11285    int err = 0;
11286    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
11287#endif
11288
11289    if (in == NULL || key == NULL) {
11290        return BAD_FUNC_ARG;
11291    }
11292
11293    /* must be odd */
11294    if ((inLen & 1) == 0) {
11295        return ECC_BAD_ARG_E;
11296    }
11297
11298#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
11299    #ifndef WOLF_CRYPTO_CB_FIND
11300    if (key->devId != INVALID_DEVID)
11301    #endif
11302    {
11303        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
11304        if (!WC_VAR_OK(tmpKey)) {
11305            return MEMORY_E;
11306        }
11307        XMEMSET(tmpKey, 0, sizeof(ecc_key));
11308
11309        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
11310        if (err != 0) {
11311            WC_FREE_VAR(tmpKey, key->heap);
11312            return err;
11313        }
11314
11315    #ifdef WOLFSSL_CUSTOM_CURVES
11316        if (key->dp != NULL) {
11317            err = wc_ecc_set_custom_curve(tmpKey, key->dp);
11318            if (err != 0) {
11319                wc_ecc_free(tmpKey);
11320                WC_FREE_VAR(tmpKey, key->heap);
11321                return err;
11322            }
11323        }
11324    #endif
11325
11326        /* Import into temp via software helper (no callback recursion) */
11327        err = _ecc_import_x963_ex2(in, inLen, tmpKey, curve_id, untrusted);
11328        if (err == MP_OKAY) {
11329            cbRet = wc_CryptoCb_SetKey(key->devId,
11330                WC_SETKEY_ECC_PUB, key, tmpKey,
11331                wc_ecc_size(tmpKey), NULL, 0, 0);
11332        }
11333
11334        wc_ecc_free(tmpKey);
11335        WC_FREE_VAR(tmpKey, key->heap);
11336
11337        if (err != MP_OKAY) {
11338            return err;
11339        }
11340        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
11341            return cbRet;
11342        }
11343    }
11344#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
11345
11346    return _ecc_import_x963_ex2(in, inLen, key, curve_id, untrusted);
11347}
11348
11349/* import public ECC key in ANSI X9.63 format */
11350int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
11351                          int curve_id)
11352{
11353    /* treat as untrusted: validate the point is on the curve */
11354    return wc_ecc_import_x963_ex2(in, inLen, key, curve_id, 1);
11355}
11356
11357WOLFSSL_ABI
11358int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
11359{
11360    return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF);
11361}
11362#endif /* HAVE_ECC_KEY_IMPORT */
11363
11364#ifdef HAVE_ECC_KEY_EXPORT
11365
11366/* Software-only export of ecc key to component form.
11367 * This internal helper avoids recursion when called from the EXPORT_KEY path. */
11368static int _ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
11369                          byte* qy, word32* qyLen, byte* d, word32* dLen,
11370                          int encType)
11371{
11372    int err = 0;
11373    word32 keySz;
11374
11375    if (key == NULL) {
11376        return BAD_FUNC_ARG;
11377    }
11378
11379    if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) {
11380        return ECC_BAD_ARG_E;
11381    }
11382    keySz = (word32)key->dp->size;
11383
11384    /* private key, d */
11385    if (d != NULL) {
11386        if (dLen == NULL ||
11387            (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY))
11388            return BAD_FUNC_ARG;
11389
11390    #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11391        defined(WOLFSSL_MICROCHIP_TA100)
11392        /* Hardware cannot export private portion */
11393        return NOT_COMPILED_IN;
11394    #else
11395    #if defined(WOLFSSL_SECO_CAAM)
11396        if (key->blackKey > 0 && key->devId == WOLFSSL_SECO_DEVID) {
11397            /* Hardware cannot export private portion */
11398            WOLFSSL_MSG("Can not export private key from HSM");
11399            return NOT_COMPILED_IN;
11400        }
11401    #endif
11402    #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11403        if (key->blackKey == CAAM_BLACK_KEY_CCM) {
11404            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11405                *dLen = keySz + WC_CAAM_MAC_SZ;
11406                return BUFFER_E;
11407            }
11408
11409            err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
11410                encType);
11411            *dLen = keySz + WC_CAAM_MAC_SZ;
11412        }
11413        else if (encType == WC_TYPE_BLACK_KEY &&
11414                key->blackKey != CAAM_BLACK_KEY_ECB &&
11415                key->blackKey > 0) {
11416            if (*dLen < keySz + WC_CAAM_MAC_SZ) {
11417                *dLen = keySz + WC_CAAM_MAC_SZ;
11418                return BUFFER_E;
11419            }
11420
11421            if (key->blackKey != CAAM_BLACK_KEY_CCM) {
11422                if (caamReadPartition(key->blackKey, d, keySz + WC_CAAM_MAC_SZ) != 0)
11423                    return WC_HW_E;
11424            }
11425
11426            *dLen = keySz + WC_CAAM_MAC_SZ;
11427        }
11428        else
11429    #endif
11430        {
11431            err = wc_export_int(ecc_get_k(key), d, dLen, keySz, encType);
11432            if (err != MP_OKAY)
11433                return err;
11434        }
11435    #endif
11436    }
11437
11438    /* public x component */
11439    if (qx != NULL) {
11440        if (qxLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11441            return BAD_FUNC_ARG;
11442
11443        err = wc_export_int(key->pubkey.x, qx, qxLen, keySz, encType);
11444        if (err != MP_OKAY)
11445            return err;
11446    }
11447
11448    /* public y component */
11449    if (qy != NULL) {
11450        if (qyLen == NULL || key->type == ECC_PRIVATEKEY_ONLY)
11451            return BAD_FUNC_ARG;
11452
11453        err = wc_export_int(key->pubkey.y, qy, qyLen, keySz, encType);
11454        if (err != MP_OKAY)
11455            return err;
11456    }
11457
11458    return err;
11459}
11460
11461
11462/* export ecc key to component form, d is optional if only exporting public
11463 * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR
11464 * return MP_OKAY on success */
11465int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
11466                 byte* qy, word32* qyLen, byte* d, word32* dLen, int encType)
11467{
11468#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
11469    int err;
11470    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
11471#endif
11472
11473    if (key == NULL) {
11474        return BAD_FUNC_ARG;
11475    }
11476
11477#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
11478    #ifndef WOLF_CRYPTO_CB_FIND
11479    if (key->devId != INVALID_DEVID)
11480    #endif
11481    {
11482        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
11483        if (!WC_VAR_OK(tmpKey)) {
11484            return MEMORY_E;
11485        }
11486        XMEMSET(tmpKey, 0, sizeof(ecc_key));
11487
11488        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
11489        if (err != 0) {
11490            WC_FREE_VAR(tmpKey, key->heap);
11491            return err;
11492        }
11493
11494        err = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN,
11495                                     key, tmpKey);
11496        if (err == 0) {
11497            /* Call software helper (no callback recursion) */
11498            err = _ecc_export_ex(tmpKey, qx, qxLen, qy, qyLen, d, dLen,
11499                                  encType);
11500        }
11501
11502        wc_ecc_free(tmpKey);
11503        WC_FREE_VAR(tmpKey, key->heap);
11504
11505        if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
11506            return err;
11507        }
11508    }
11509#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
11510
11511    return _ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen, encType);
11512}
11513
11514/* export ecc private key only raw, outLen is in/out size as unsigned bin
11515   return MP_OKAY on success */
11516WOLFSSL_ABI
11517int wc_ecc_export_private_only(ecc_key* key, byte* out, word32* outLen)
11518{
11519    if (out == NULL || outLen == NULL) {
11520        return BAD_FUNC_ARG;
11521    }
11522
11523#if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11524    /* check if black key in secure memory */
11525    if ((key->blackKey != CAAM_BLACK_KEY_CCM &&
11526         key->blackKey != CAAM_BLACK_KEY_ECB) && key->blackKey > 0) {
11527        return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11528            WC_TYPE_BLACK_KEY);
11529    }
11530#endif
11531
11532    return wc_ecc_export_ex(key, NULL, NULL, NULL, NULL, out, outLen,
11533        WC_TYPE_UNSIGNED_BIN);
11534}
11535
11536/* export public key to raw elements including public (Qx,Qy) as unsigned bin
11537 * return MP_OKAY on success, negative on error */
11538int wc_ecc_export_public_raw(ecc_key* key, byte* qx, word32* qxLen,
11539                             byte* qy, word32* qyLen)
11540{
11541    if (qx == NULL || qxLen == NULL || qy == NULL || qyLen == NULL) {
11542        return BAD_FUNC_ARG;
11543    }
11544
11545    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, NULL, NULL,
11546        WC_TYPE_UNSIGNED_BIN);
11547}
11548
11549/* export ecc key to raw elements including public (Qx,Qy) and
11550 *   private (d) as unsigned bin
11551 * return MP_OKAY on success, negative on error */
11552int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen,
11553                              byte* qy, word32* qyLen, byte* d, word32* dLen)
11554{
11555    return wc_ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen,
11556        WC_TYPE_UNSIGNED_BIN);
11557}
11558
11559#endif /* HAVE_ECC_KEY_EXPORT */
11560
11561#ifdef HAVE_ECC_KEY_IMPORT
11562/* Software-only import of private key, public part optional.
11563 * This internal helper avoids recursion when called from the SETKEY path. */
11564static int _ecc_import_private_key_ex(const byte* priv, word32 privSz,
11565                                      const byte* pub, word32 pubSz,
11566                                      ecc_key* key, int curve_id)
11567{
11568    int ret;
11569#ifdef WOLFSSL_CRYPTOCELL
11570    const CRYS_ECPKI_Domain_t* pDomain;
11571#endif
11572
11573    if (key == NULL || priv == NULL) {
11574        return BAD_FUNC_ARG;
11575    }
11576
11577    /* public optional, NULL if only importing private */
11578    if (pub != NULL) {
11579    #ifndef NO_ASN
11580        word32 idx = 0;
11581        ret = _ecc_import_x963_ex2(pub, pubSz, key, curve_id, 0);
11582        if (ret < 0)
11583            ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
11584        key->type = ECC_PRIVATEKEY;
11585    #else
11586        (void)pubSz;
11587        ret = NOT_COMPILED_IN;
11588    #endif
11589    }
11590    else {
11591        /* make sure required variables are reset */
11592        wc_ecc_reset(key);
11593
11594        /* set key size */
11595        /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11596         *       on created keys or signatures */
11597        ret = wc_ecc_set_curve(key, (int)privSz, curve_id);
11598        key->type = ECC_PRIVATEKEY_ONLY;
11599    }
11600
11601    if (ret != 0)
11602        return ret;
11603
11604#ifdef WOLFSSL_CRYPTOCELL
11605    pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
11606    /* import private key - priv checked for NULL at top */
11607    if (priv[0] != '\0') {
11608
11609        /* Create private key from external key buffer*/
11610        ret = CRYS_ECPKI_BuildPrivKey(pDomain,
11611                                      priv,
11612                                      privSz,
11613                                      &key->ctx.privKey);
11614
11615        if (ret != SA_SILIB_RET_OK) {
11616            WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
11617            return ret;
11618        }
11619
11620        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11621    #ifdef WOLFSSL_ECC_BLIND_K
11622        if (ret == MP_OKAY) {
11623            err = ecc_blind_k_rng(key, NULL);
11624        }
11625    #endif
11626    }
11627#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
11628    if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
11629    #ifdef WOLFSSL_CAAM_BLACK_KEY_SM
11630        int part = caamFindUnusedPartition();
11631        if (part >= 0) {
11632            CAAM_ADDRESS vaddr = caamGetPartition(part, privSz*3);
11633            if (vaddr == 0) {
11634                WOLFSSL_MSG("Unable to get partition");
11635                return MEMORY_E;
11636            }
11637
11638            key->partNum  = part;
11639            key->blackKey = (word32)vaddr;
11640            if (caamWriteToPartition(vaddr, priv, privSz) != 0)
11641                return WC_HW_E;
11642
11643            if (pub != NULL) {
11644                /* +1 to account for x963 compressed bit */
11645                if (caamWriteToPartition(vaddr + privSz, pub + 1, pubSz - 1) != 0)
11646                    return WC_HW_E;
11647                key->securePubKey = (word32)vaddr + privSz;
11648            }
11649        }
11650        else {
11651            WOLFSSL_MSG("Unable to find an unused partition");
11652            return MEMORY_E;
11653        }
11654    #else
11655        key->blackKey = CAAM_BLACK_KEY_CCM;
11656        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11657    #ifdef WOLFSSL_ECC_BLIND_K
11658        if (ret == MP_OKAY) {
11659            err = ecc_blind_k_rng(key, NULL);
11660        }
11661    #endif
11662    #endif
11663    }
11664    else {
11665        key->blackKey = 0;
11666        ret = mp_read_unsigned_bin(key->k, priv, privSz);
11667    #ifdef WOLFSSL_ECC_BLIND_K
11668        if (ret == MP_OKAY) {
11669            err = ecc_blind_k_rng(key, NULL);
11670        }
11671    #endif
11672
11673        /* If using AES-ECB encrypted black keys check here if key is valid,
11674         * if not valid than assume is an encrypted key. A public key is needed
11675         * for testing validity. */
11676        if (key->devId == WOLFSSL_CAAM_DEVID && (
11677            wc_ecc_get_curve_id(key->idx) == ECC_SECP256R1 ||
11678            wc_ecc_get_curve_id(key->idx) == ECC_SECP384R1)) {
11679            if ((pub != NULL) && (ret == MP_OKAY) &&
11680                (_ecc_validate_public_key(key, 1, 1) != MP_OKAY)) {
11681                key->blackKey = CAAM_BLACK_KEY_ECB;
11682            }
11683            else if ((pub == NULL) && (ret == MP_OKAY)) {
11684                WOLFSSL_MSG("Assuming encrypted key with no public key to check");
11685                key->blackKey = CAAM_BLACK_KEY_ECB;
11686            }
11687            else {
11688                WOLFSSL_MSG("Importing key that is not a black key!");
11689            }
11690        }
11691    }
11692#else
11693
11694#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11695    SAVE_VECTOR_REGISTERS(return _svr_ret;);
11696#endif
11697
11698    ret = mp_read_unsigned_bin(key->k, priv, privSz);
11699#ifdef HAVE_WOLF_BIGINT
11700    if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
11701                                                                 privSz) != 0) {
11702        mp_clear(key->k);
11703        ret = ASN_GETINT_E;
11704    }
11705#endif /* HAVE_WOLF_BIGINT */
11706#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11707    if (ret == 0) {
11708        WC_DECLARE_VAR(order, mp_int, 1, 0);
11709
11710        WC_ALLOC_VAR_EX(order, mp_int, 1, key->heap, DYNAMIC_TYPE_ECC,
11711            ret=MEMORY_E);
11712
11713        if (ret == 0) {
11714            ret = mp_init(order);
11715        }
11716        if (ret == 0) {
11717            ret = mp_read_radix(order, key->dp->order, MP_RADIX_HEX);
11718        }
11719    #ifdef WOLFSSL_SM2
11720        /* SM2 curve: private key must be less than order-1. */
11721        if ((ret == 0) && (key->idx != ECC_CUSTOM_IDX) &&
11722                (ecc_sets[key->idx].id == ECC_SM2P256V1)) {
11723            ret = mp_sub_d(order, 1, order);
11724        }
11725    #endif
11726        if ((ret == 0) && (mp_cmp(key->k, order) != MP_LT)) {
11727            ret = ECC_PRIV_KEY_E;
11728        }
11729
11730        WC_FREE_VAR_EX(order, key->heap, DYNAMIC_TYPE_ECC);
11731    }
11732#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
11733#ifdef WOLFSSL_ECC_BLIND_K
11734    if (ret == 0) {
11735        ret = ecc_blind_k_rng(key, NULL);
11736    }
11737#endif
11738
11739#endif /* WOLFSSL_CRYPTOCELL */
11740
11741#if defined(WOLFSSL_VALIDATE_ECC_IMPORT) && !defined(WOLFSSL_KCAPI_ECC)
11742    if ((pub != NULL) && (ret == MP_OKAY))
11743        /* public key needed to perform key validation */
11744        ret = _ecc_validate_public_key(key, 1, 1);
11745
11746#endif
11747
11748#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
11749    RESTORE_VECTOR_REGISTERS();
11750#endif
11751
11752#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11753    if ((ret == 0) && (key->devId != INVALID_DEVID)) {
11754        ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
11755    }
11756#elif defined(WOLFSSL_SILABS_SE_ACCEL)
11757    if (ret == 0) {
11758        ret = silabs_ecc_import(key, key->dp->size, (pub != NULL), 1);
11759    }
11760#endif
11761
11762    return ret;
11763}
11764
11765/* import private key, public part optional if (pub) passed as NULL */
11766int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
11767                                 const byte* pub, word32 pubSz, ecc_key* key,
11768                                 int curve_id)
11769{
11770#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
11771    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
11772    int tmpErr = 0;
11773    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
11774#endif
11775
11776    if (key == NULL || priv == NULL) {
11777        return BAD_FUNC_ARG;
11778    }
11779
11780#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
11781    #ifndef WOLF_CRYPTO_CB_FIND
11782    if (key->devId != INVALID_DEVID)
11783    #endif
11784    {
11785        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
11786        if (!WC_VAR_OK(tmpKey)) {
11787            return MEMORY_E;
11788        }
11789        XMEMSET(tmpKey, 0, sizeof(ecc_key));
11790
11791        tmpErr = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
11792        if (tmpErr != 0) {
11793            WC_FREE_VAR(tmpKey, key->heap);
11794            return tmpErr;
11795        }
11796
11797    #ifdef WOLFSSL_CUSTOM_CURVES
11798        if (key->dp != NULL) {
11799            tmpErr = wc_ecc_set_custom_curve(tmpKey, key->dp);
11800            if (tmpErr != 0) {
11801                wc_ecc_free(tmpKey);
11802                WC_FREE_VAR(tmpKey, key->heap);
11803                return tmpErr;
11804            }
11805        }
11806    #endif
11807
11808        /* Import into temp via software helper (no callback recursion) */
11809        tmpErr = _ecc_import_private_key_ex(priv, privSz, pub, pubSz,
11810            tmpKey, curve_id);
11811        if (tmpErr == 0) {
11812            cbRet = wc_CryptoCb_SetKey(key->devId,
11813                WC_SETKEY_ECC_PRIV, key, tmpKey,
11814                wc_ecc_size(tmpKey), NULL, 0, 0);
11815        }
11816
11817        /* wc_ecc_free calls mp_forcezero on private key components,
11818         * so no separate ForceZero of the struct is needed here. */
11819        wc_ecc_free(tmpKey);
11820        WC_FREE_VAR(tmpKey, key->heap);
11821
11822        if (tmpErr != 0) {
11823            return tmpErr;
11824        }
11825        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
11826            return cbRet;
11827        }
11828    }
11829#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
11830
11831    return _ecc_import_private_key_ex(priv, privSz, pub, pubSz, key, curve_id);
11832}
11833
11834/* ecc private key import, public key in ANSI X9.63 format, private raw */
11835WOLFSSL_ABI
11836int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,
11837                           word32 pubSz, ecc_key* key)
11838{
11839    return wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, key,
11840                                                                ECC_CURVE_DEF);
11841}
11842#endif /* HAVE_ECC_KEY_IMPORT */
11843
11844#ifndef NO_ASN
11845/**
11846   Convert ECC R,S to signature
11847   r       R component of signature
11848   s       S component of signature
11849   out     DER-encoded ECDSA signature
11850   outlen  [in/out] output buffer size, output signature size
11851   return  MP_OKAY on success
11852*/
11853WOLFSSL_ABI
11854int wc_ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen)
11855{
11856    int err;
11857#ifdef WOLFSSL_SMALL_STACK
11858    mp_int* rtmp = NULL;
11859    mp_int* stmp = NULL;
11860#else
11861    mp_int  rtmp[1];
11862    mp_int  stmp[1];
11863#endif
11864
11865    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11866        return ECC_BAD_ARG_E;
11867
11868#ifdef WOLFSSL_SMALL_STACK
11869    rtmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11870    if (rtmp == NULL)
11871        return MEMORY_E;
11872    stmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
11873    if (stmp == NULL) {
11874        XFREE(rtmp, NULL, DYNAMIC_TYPE_ECC);
11875        return MEMORY_E;
11876    }
11877#endif
11878
11879    err = mp_init_multi(rtmp, stmp, NULL, NULL, NULL, NULL);
11880    if (err != MP_OKAY) {
11881        WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11882        WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11883        return err;
11884    }
11885
11886    err = mp_read_radix(rtmp, r, MP_RADIX_HEX);
11887    if (err == MP_OKAY)
11888        err = mp_read_radix(stmp, s, MP_RADIX_HEX);
11889
11890    if (err == MP_OKAY) {
11891        if (mp_iszero(rtmp) == MP_YES || mp_iszero(stmp) == MP_YES)
11892            err = MP_ZERO_E;
11893    }
11894    if (err == MP_OKAY) {
11895        if (mp_isneg(rtmp) == MP_YES || mp_isneg(stmp) == MP_YES) {
11896            err = MP_READ_E;
11897        }
11898    }
11899
11900    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11901    if (err == MP_OKAY)
11902        err = StoreECC_DSA_Sig(out, outlen, rtmp, stmp);
11903
11904    mp_clear(rtmp);
11905    mp_clear(stmp);
11906    WC_FREE_VAR_EX(stmp, NULL, DYNAMIC_TYPE_ECC);
11907    WC_FREE_VAR_EX(rtmp, NULL, DYNAMIC_TYPE_ECC);
11908
11909    return err;
11910}
11911
11912/**
11913   Convert ECC R,S raw unsigned bin to signature
11914   r       R component of signature
11915   rSz     R size
11916   s       S component of signature
11917   sSz     S size
11918   out     DER-encoded ECDSA signature
11919   outlen  [in/out] output buffer size, output signature size
11920   return  MP_OKAY on success
11921*/
11922int wc_ecc_rs_raw_to_sig(const byte* r, word32 rSz, const byte* s, word32 sSz,
11923    byte* out, word32* outlen)
11924{
11925    if (r == NULL || s == NULL || out == NULL || outlen == NULL)
11926        return ECC_BAD_ARG_E;
11927
11928    /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */
11929    return StoreECC_DSA_Sig_Bin(out, outlen, r, rSz, s, sSz);
11930}
11931
11932/**
11933   Convert ECC signature to R,S
11934   sig     DER-encoded ECDSA signature
11935   sigLen  length of signature in octets
11936   r       R component of signature
11937   rLen    [in/out] output "r" buffer size, output "r" size
11938   s       S component of signature
11939   sLen    [in/out] output "s" buffer size, output "s" size
11940   return  MP_OKAY on success, negative on error
11941*/
11942int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen,
11943                     byte* s, word32* sLen)
11944{
11945    if (sig == NULL || r == NULL || rLen == NULL || s == NULL || sLen == NULL)
11946        return ECC_BAD_ARG_E;
11947
11948    return DecodeECC_DSA_Sig_Bin(sig, sigLen, r, rLen, s, sLen);
11949}
11950#endif /* !NO_ASN */
11951
11952#ifdef HAVE_ECC_KEY_IMPORT
11953/* Software-only import of raw ECC key material.
11954 * This internal helper avoids recursion when called from the SETKEY path. */
11955static int _ecc_import_raw_private(ecc_key* key, const char* qx,
11956          const char* qy, const char* d, int curve_id, int encType)
11957{
11958    int err = MP_OKAY;
11959#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
11960    !defined(WOLFSSL_ATECC608A) && !defined(WOLFSSL_MICROCHIP_TA100)
11961    const CRYS_ECPKI_Domain_t* pDomain;
11962    CRYS_ECPKI_BUILD_TempData_t tempBuff;
11963    byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
11964#endif
11965#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
11966    defined(WOLFSSL_MICROCHIP_TA100) || defined(WOLFSSL_CRYPTOCELL)
11967    word32 keySz = 0;
11968#endif
11969
11970    /* if d is NULL, only import as public key using Qx,Qy */
11971    if (key == NULL || qx == NULL || qy == NULL) {
11972        return BAD_FUNC_ARG;
11973    }
11974
11975    /* make sure required variables are reset */
11976    wc_ecc_reset(key);
11977
11978    /* set curve type and index */
11979    /* NOTE: FIPS v6.0.0 or greater, no restriction on imported keys, only
11980     *       on created keys or signatures */
11981    err = wc_ecc_set_curve(key, 0, curve_id);
11982    if (err != 0) {
11983        return err;
11984    }
11985
11986    /* init key */
11987#ifdef ALT_ECC_SIZE
11988    key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
11989    key->pubkey.y = (mp_int*)&key->pubkey.xyz[1];
11990    key->pubkey.z = (mp_int*)&key->pubkey.xyz[2];
11991    alt_fp_init(key->pubkey.x);
11992    alt_fp_init(key->pubkey.y);
11993    alt_fp_init(key->pubkey.z);
11994    key->k = (mp_int*)key->ka;
11995    alt_fp_init(key->k);
11996#ifdef WOLFSSL_ECC_BLIND_K
11997    key->kb = (mp_int*)key->kba;
11998    key->ku = (mp_int*)key->kua;
11999    alt_fp_init(key->kb);
12000    alt_fp_init(key->ku);
12001#endif
12002#else
12003    err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
12004#ifndef WOLFSSL_ECC_BLIND_K
12005                                                                      NULL, NULL
12006#else
12007                                                                key->kb, key->ku
12008#endif
12009                        );
12010#endif
12011    if (err != MP_OKAY)
12012        return MEMORY_E;
12013#ifdef WOLFSSL_ECC_BLIND_K
12014    mp_forcezero(key->kb);
12015#endif
12016
12017    /* read Qx */
12018    if (err == MP_OKAY) {
12019        if (encType == WC_TYPE_HEX_STR)
12020            err = mp_read_radix(key->pubkey.x, qx, MP_RADIX_HEX);
12021        else
12022            err = mp_read_unsigned_bin(key->pubkey.x, (const byte*)qx,
12023                (word32)key->dp->size);
12024
12025        if (mp_isneg(key->pubkey.x)) {
12026            WOLFSSL_MSG("Invalid Qx");
12027            err = BAD_FUNC_ARG;
12028        }
12029        if (mp_unsigned_bin_size(key->pubkey.x) > key->dp->size) {
12030            err = BAD_FUNC_ARG;
12031        }
12032    }
12033
12034    /* read Qy */
12035    if (err == MP_OKAY) {
12036        if (encType == WC_TYPE_HEX_STR)
12037            err = mp_read_radix(key->pubkey.y, qy, MP_RADIX_HEX);
12038        else
12039            err = mp_read_unsigned_bin(key->pubkey.y, (const byte*)qy,
12040                (word32)key->dp->size);
12041
12042        if (mp_isneg(key->pubkey.y)) {
12043            WOLFSSL_MSG("Invalid Qy");
12044            err = BAD_FUNC_ARG;
12045        }
12046        if (mp_unsigned_bin_size(key->pubkey.y) > key->dp->size) {
12047            err = BAD_FUNC_ARG;
12048        }
12049    }
12050
12051    if (err == MP_OKAY) {
12052        if (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y)) {
12053            WOLFSSL_MSG("Invalid Qx and Qy");
12054            err = ECC_INF_E;
12055        }
12056    }
12057
12058    if (err == MP_OKAY)
12059        err = mp_set(key->pubkey.z, 1);
12060
12061#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
12062    defined(WOLFSSL_MICROCHIP_TA100)
12063    /* For SECP256R1 only save raw public key for hardware */
12064    if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
12065        keySz = key->dp->size;
12066        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
12067            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12068        if (err == MP_OKAY)
12069            err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
12070                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12071    }
12072#elif defined(WOLFSSL_CRYPTOCELL)
12073    if (err == MP_OKAY) {
12074        keyRaw[0] = ECC_POINT_UNCOMP;
12075        keySz = (word32)key->dp->size;
12076        err = wc_export_int(key->pubkey.x, &keyRaw[1], &keySz, keySz,
12077            WC_TYPE_UNSIGNED_BIN);
12078        if (err == MP_OKAY) {
12079            err = wc_export_int(key->pubkey.y, &keyRaw[1+keySz],
12080                &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12081        }
12082
12083        if (err == MP_OKAY) {
12084            pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
12085
12086            /* create public key from external key buffer */
12087            err = CRYS_ECPKI_BuildPublKeyFullCheck(pDomain,
12088                                                   keyRaw,
12089                                                   keySz*2 + 1,
12090                                                   &key->ctx.pubKey,
12091                                                   &tempBuff);
12092        }
12093
12094        if (err != SA_SILIB_RET_OK){
12095            WOLFSSL_MSG("CRYS_ECPKI_BuildPublKeyFullCheck failed");
12096            return err;
12097        }
12098    }
12099#elif defined(WOLFSSL_KCAPI_ECC)
12100    if (err == MP_OKAY) {
12101        word32 keySz = key->dp->size;
12102        err = wc_export_int(key->pubkey.x, key->pubkey_raw,
12103            &keySz, keySz, WC_TYPE_UNSIGNED_BIN);
12104        if (err == MP_OKAY) {
12105            err = wc_export_int(key->pubkey.y,
12106                &key->pubkey_raw[keySz], &keySz, keySz,
12107                WC_TYPE_UNSIGNED_BIN);
12108        }
12109    }
12110#elif defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12111    if (err == MP_OKAY) {
12112        const word32 keySize = key->dp->size;
12113        word32 bufSize = sizeof(key->keyRaw);
12114        err = wc_export_int(key->pubkey.x, key->keyRaw, &bufSize, keySize,
12115                            WC_TYPE_UNSIGNED_BIN);
12116        if (err == MP_OKAY) {
12117            const word32 offset = bufSize;
12118            bufSize = sizeof(key->keyRaw) - offset;
12119            err = wc_export_int(key->pubkey.y, &key->keyRaw[offset], &bufSize,
12120                                keySize, WC_TYPE_UNSIGNED_BIN);
12121        }
12122        if (err == MP_OKAY) {
12123            mp_reverse(key->keyRaw, keySize);
12124            mp_reverse(&key->keyRaw[keySize], keySize);
12125            WOLFSSL_XIL_DCACHE_FLUSH_RANGE(XIL_CAST_U64(key->keyRaw),
12126                                           keySize * 2);
12127#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN
12128            err = XSecure_EllipticValidateKey(&(key->xSec.cinst),
12129                                              xil_curve_type[key->dp->id],
12130                                              XIL_CAST_U64(key->keyRaw));
12131            if (err) {
12132                WOLFSSL_XIL_ERROR("Validation of ECC key failed", err);
12133                err = WC_HW_E;
12134            }
12135#endif
12136        }
12137    }
12138#endif
12139
12140#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
12141    SAVE_VECTOR_REGISTERS(return _svr_ret;);
12142#endif
12143
12144    /* import private key */
12145    if (err == MP_OKAY) {
12146        if (d != NULL) {
12147        #if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
12148            defined(WOLFSSL_MICROCHIP_TA100)
12149            /* Hardware doesn't support loading private key */
12150            err = NOT_COMPILED_IN;
12151
12152        #elif defined(WOLFSSL_CRYPTOCELL)
12153            key->type = ECC_PRIVATEKEY;
12154
12155            if (encType == WC_TYPE_HEX_STR)
12156                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
12157            else
12158                err = mp_read_unsigned_bin(key->k, (const byte*)d,
12159                    key->dp->size);
12160            if (err == MP_OKAY) {
12161                err = wc_export_int(key->k, &keyRaw[0], &keySz, keySz,
12162                    WC_TYPE_UNSIGNED_BIN);
12163            }
12164        #ifdef WOLFSSL_ECC_BLIND_K
12165            if (err == 0) {
12166                err = ecc_blind_k_rng(key, NULL);
12167            }
12168        #endif
12169
12170            if (err == MP_OKAY) {
12171                /* Create private key from external key buffer*/
12172                err = CRYS_ECPKI_BuildPrivKey(pDomain,
12173                                              keyRaw,
12174                                              keySz,
12175                                              &key->ctx.privKey);
12176
12177                if (err != SA_SILIB_RET_OK){
12178                    WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed");
12179                    return err;
12180                }
12181            }
12182
12183        #else
12184            key->type = ECC_PRIVATEKEY;
12185            if (encType == WC_TYPE_HEX_STR)
12186                err = mp_read_radix(key->k, d, MP_RADIX_HEX);
12187            else {
12188            #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
12189                if (key->blackKey == CAAM_BLACK_KEY_CCM) {
12190                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
12191                    key->dp->size + WC_CAAM_MAC_SZ);
12192                }
12193                else
12194            #endif /* WOLFSSL_QNX_CAAM */
12195                {
12196                    err = mp_read_unsigned_bin(key->k, (const byte*)d,
12197                        (word32)key->dp->size);
12198                }
12199            }
12200        #ifdef WOLFSSL_ECC_BLIND_K
12201            if (err == 0) {
12202                err = ecc_blind_k_rng(key, NULL);
12203            }
12204        #endif
12205#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12206            if (err == MP_OKAY) {
12207                const word32 key_size = key->dp->size;
12208                word32 buf_size = key_size;
12209                err = wc_export_int(key, key->privKey, &buf_size, key_size,
12210                                    WC_TYPE_UNSIGNED_BIN);
12211                mp_reverse(key->privKey, key_size);
12212            }
12213#endif
12214
12215        #endif /* #else-case of custom HW-specific implementations */
12216            if (err == MP_OKAY) {
12217                if (mp_iszero(key->k) || mp_isneg(key->k)) {
12218                    WOLFSSL_MSG("Invalid private key");
12219                    err = BAD_FUNC_ARG;
12220                }
12221            }
12222        } else {
12223            key->type = ECC_PUBLICKEY;
12224        }
12225    }
12226
12227#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
12228    if (err == MP_OKAY) {
12229        err = wc_ecc_check_key(key);
12230        if (err == WC_NO_ERR_TRACE(IS_POINT_E) && (mp_iszero(key->pubkey.x) ||
12231                                  mp_iszero(key->pubkey.y))) {
12232            err = BAD_FUNC_ARG;
12233        }
12234    }
12235#endif
12236
12237#ifdef WOLFSSL_VALIDATE_ECC_IMPORT
12238    RESTORE_VECTOR_REGISTERS();
12239#endif
12240
12241#ifdef WOLFSSL_MAXQ10XX_CRYPTO
12242    if (err == MP_OKAY) {
12243        err = wc_MAXQ10XX_EccSetKey(key, key->dp->size);
12244    }
12245#elif defined(WOLFSSL_SILABS_SE_ACCEL)
12246    if (err == MP_OKAY) {
12247        err = silabs_ecc_import(key, key->dp->size, 1, (d != NULL));
12248    }
12249#endif
12250
12251    if (err != MP_OKAY) {
12252        mp_clear(key->pubkey.x);
12253        mp_clear(key->pubkey.y);
12254        mp_clear(key->pubkey.z);
12255        mp_forcezero(key->k);
12256#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
12257        ForceZero(key->keyRaw, sizeof(key->keyRaw));
12258#endif
12259    }
12260
12261    return err;
12262}
12263
12264static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
12265          const char* qy, const char* d, int curve_id, int encType)
12266{
12267#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12268    int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
12269    int setKeyType = WC_SETKEY_ECC_PRIV;
12270    int err;
12271    WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
12272#endif
12273
12274    /* if d is NULL, only import as public key using Qx,Qy */
12275    if (key == NULL || qx == NULL || qy == NULL) {
12276        return BAD_FUNC_ARG;
12277    }
12278
12279#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
12280    #ifndef WOLF_CRYPTO_CB_FIND
12281    if (key->devId != INVALID_DEVID)
12282    #endif
12283    {
12284        WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
12285        if (!WC_VAR_OK(tmpKey)) {
12286            return MEMORY_E;
12287        }
12288        XMEMSET(tmpKey, 0, sizeof(ecc_key));
12289
12290        err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
12291        if (err != 0) {
12292            WC_FREE_VAR(tmpKey, key->heap);
12293            return err;
12294        }
12295
12296    #ifdef WOLFSSL_CUSTOM_CURVES
12297        if (key->dp != NULL) {
12298            err = wc_ecc_set_custom_curve(tmpKey, key->dp);
12299            if (err != 0) {
12300                wc_ecc_free(tmpKey);
12301                WC_FREE_VAR(tmpKey, key->heap);
12302                return err;
12303            }
12304        }
12305    #endif
12306
12307        /* Import into temp via software helper (no callback recursion) */
12308        err = _ecc_import_raw_private(tmpKey, qx, qy, d, curve_id, encType);
12309        if (err == MP_OKAY) {
12310            if (d == NULL) {
12311                setKeyType = WC_SETKEY_ECC_PUB;
12312            }
12313            cbRet = wc_CryptoCb_SetKey(key->devId,
12314                setKeyType, key, tmpKey,
12315                wc_ecc_size(tmpKey), NULL, 0, 0);
12316        }
12317
12318        /* wc_ecc_free calls mp_forcezero on private key components,
12319         * so no separate ForceZero of the struct is needed here. */
12320        wc_ecc_free(tmpKey);
12321        WC_FREE_VAR(tmpKey, key->heap);
12322
12323        if (err != MP_OKAY) {
12324            return err;
12325        }
12326        if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12327            return cbRet;
12328        }
12329    }
12330#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
12331
12332    return _ecc_import_raw_private(key, qx, qy, d, curve_id, encType);
12333}
12334
12335/**
12336   Import raw ECC key
12337   key       The destination ecc_key structure
12338   qx        x component of the public key, as ASCII hex string
12339   qy        y component of the public key, as ASCII hex string
12340   d         private key, as ASCII hex string, optional if importing public
12341             key only
12342   curve_id  The id of the curve.
12343   @return    MP_OKAY on success
12344*/
12345int wc_ecc_import_raw_ex(ecc_key* key, const char* qx, const char* qy,
12346                   const char* d, int curve_id)
12347{
12348    return wc_ecc_import_raw_private(key, qx, qy, d, curve_id,
12349        WC_TYPE_HEX_STR);
12350}
12351
12352/* Import x, y and optional private (d) as unsigned binary */
12353int wc_ecc_import_unsigned(ecc_key* key, const byte* qx, const byte* qy,
12354                   const byte* d, int curve_id)
12355{
12356    return wc_ecc_import_raw_private(key, (const char*)qx, (const char*)qy,
12357        (const char*)d, curve_id, WC_TYPE_UNSIGNED_BIN);
12358}
12359
12360/**
12361   Import raw ECC key
12362   key       The destination ecc_key structure
12363   qx        x component of the public key, as ASCII hex string
12364   qy        y component of the public key, as ASCII hex string
12365   d         private key, as ASCII hex string, optional if importing public
12366             key only
12367   curveName ECC curve name, from ecc_sets[]
12368   return    MP_OKAY on success
12369*/
12370WOLFSSL_ABI
12371int wc_ecc_import_raw(ecc_key* key, const char* qx, const char* qy,
12372                   const char* d, const char* curveName)
12373{
12374    int err, x;
12375
12376    /* if d is NULL, only import as public key using Qx,Qy */
12377    if (key == NULL || qx == NULL || qy == NULL || curveName == NULL) {
12378        return BAD_FUNC_ARG;
12379    }
12380
12381    /* set curve type and index */
12382    for (x = 0; ecc_sets[x].size != 0; x++) {
12383        if (XSTRNCMP(ecc_sets[x].name, curveName,
12384                     XSTRLEN(curveName)) == 0) {
12385            break;
12386        }
12387    }
12388
12389    if (ecc_sets[x].size == 0) {
12390        WOLFSSL_MSG("ecc_set curve name not found");
12391        err = ASN_PARSE_E;
12392    } else {
12393        return wc_ecc_import_raw_private(key, qx, qy, d, ecc_sets[x].id,
12394            WC_TYPE_HEX_STR);
12395    }
12396
12397    return err;
12398}
12399#endif /* HAVE_ECC_KEY_IMPORT */
12400
12401#if defined(HAVE_ECC_ENCRYPT) && !defined(WOLFSSL_ECIES_OLD)
12402/* public key size in octets */
12403static int ecc_public_key_size(ecc_key* key, word32* sz)
12404{
12405    if (key == NULL || key->dp == NULL)
12406        return BAD_FUNC_ARG;
12407
12408    /* 'Uncompressed' | x | y */
12409    *sz = 1 + 2 * (word32)key->dp->size;
12410
12411    return 0;
12412}
12413#endif
12414
12415/* key size in octets */
12416WOLFSSL_ABI
12417int wc_ecc_size(ecc_key* key)
12418{
12419    if (key == NULL) {
12420        return 0;
12421    }
12422
12423#if defined(WOLF_CRYPTO_CB) && \
12424    (defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
12425    if (key->devId != INVALID_DEVID) {
12426        int ret;
12427        int keySz = 0;
12428
12429        ret = wc_CryptoCb_EccGetSize(key, &keySz);
12430        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12431            if (ret != 0) {
12432                return 0;
12433            }
12434            return keySz;
12435        }
12436    }
12437#endif
12438
12439    if (key->dp == NULL) {
12440        return 0;
12441    }
12442
12443    return key->dp->size;
12444}
12445
12446/* maximum signature size based on key size */
12447WOLFSSL_ABI
12448int wc_ecc_sig_size_calc(int sz)
12449{
12450    int maxSigSz = 0;
12451
12452    /* calculate based on key bits */
12453    /* maximum possible signature header size is 7 bytes plus 2 bytes padding */
12454    maxSigSz = (sz * 2) + SIG_HEADER_SZ + ECC_MAX_PAD_SZ;
12455
12456    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
12457    if (maxSigSz < (128 + 2)) {
12458        maxSigSz -= 1;
12459    }
12460
12461    return maxSigSz;
12462}
12463
12464/* maximum signature size based on actual key curve */
12465WOLFSSL_ABI
12466int wc_ecc_sig_size(const ecc_key* key)
12467{
12468    int maxSigSz;
12469    int orderBits, keySz;
12470
12471    if (key == NULL) {
12472        return 0;
12473    }
12474
12475#if defined(WOLF_CRYPTO_CB) && \
12476    (defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
12477    if (key->devId != INVALID_DEVID) {
12478        int ret;
12479        int cbKeySz = 0;
12480
12481        ret = wc_CryptoCb_EccGetSigSize(key, &cbKeySz);
12482        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
12483            if (ret != 0 || cbKeySz == 0) {
12484                return 0;
12485            }
12486            return cbKeySz;
12487        }
12488    }
12489#endif
12490
12491    if (key->dp == NULL) {
12492        return 0;
12493    }
12494
12495    /* the signature r and s will always be less than order */
12496    /* if the order MSB (top bit of byte) is set then ASN encoding needs
12497        extra byte for r and s, so add 2 */
12498    keySz = key->dp->size;
12499    orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
12500    if (orderBits > keySz * 8) {
12501        keySz = (orderBits + 7) >> 3;
12502    }
12503    /* maximum possible signature header size is 7 bytes */
12504    maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
12505    if ((orderBits % 8) == 0) {
12506        /* MSB can be set, so add 2 */
12507        maxSigSz += ECC_MAX_PAD_SZ;
12508    }
12509    /* if total length is less than 128 + SEQ(1)+LEN(1) then subtract 1 */
12510    if (maxSigSz < (128 + 2)) {
12511        maxSigSz -= 1;
12512    }
12513
12514    return maxSigSz;
12515}
12516
12517
12518#ifdef FP_ECC
12519
12520/* fixed point ECC cache */
12521/* number of entries in the cache */
12522#ifndef FP_ENTRIES
12523    #define FP_ENTRIES 15
12524#endif
12525
12526/* number of bits in LUT */
12527#ifndef FP_LUT
12528    #define FP_LUT     8U
12529#endif
12530
12531#ifdef ECC_SHAMIR
12532    /* Sharmir requires a bigger LUT, TAO */
12533    #if (FP_LUT > 12) || (FP_LUT < 4)
12534        #error FP_LUT must be between 4 and 12 inclusively
12535    #endif
12536#else
12537    #if (FP_LUT > 12) || (FP_LUT < 2)
12538        #error FP_LUT must be between 2 and 12 inclusively
12539    #endif
12540#endif
12541
12542
12543#if !defined(WOLFSSL_SP_MATH)
12544
12545/** Our FP cache */
12546typedef struct {
12547   ecc_point* g;               /* cached COPY of base point */
12548   ecc_point* LUT[1U<<FP_LUT]; /* fixed point lookup */
12549   int        LUT_set;         /* flag to determine if the LUT has been computed */
12550   mp_int     mu;              /* copy of the montgomery constant */
12551   int        lru_count;       /* amount of times this entry has been used */
12552   int        lock;            /* flag to indicate cache eviction */
12553                               /* permitted (0) or not (1) */
12554} fp_cache_t;
12555
12556/* if HAVE_THREAD_LS this cache is per thread, no locking needed */
12557static THREAD_LS_T fp_cache_t fp_cache[FP_ENTRIES];
12558
12559#ifndef HAVE_THREAD_LS
12560    static wolfSSL_Mutex ecc_fp_lock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(ecc_fp_lock);
12561#ifndef WOLFSSL_MUTEX_INITIALIZER
12562    static volatile int initMutex = 0;  /* prevent multiple mutex inits */
12563#endif
12564#endif /* HAVE_THREAD_LS */
12565
12566/* simple table to help direct the generation of the LUT */
12567static const struct {
12568   int ham, terma, termb;
12569} lut_orders[] = {
12570   { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 2, 1, 2 }, { 1, 0, 0 }, { 2, 1, 4 }, { 2, 2, 4 }, { 3, 3, 4 },
12571   { 1, 0, 0 }, { 2, 1, 8 }, { 2, 2, 8 }, { 3, 3, 8 }, { 2, 4, 8 }, { 3, 5, 8 }, { 3, 6, 8 }, { 4, 7, 8 },
12572   { 1, 0, 0 }, { 2, 1, 16 }, { 2, 2, 16 }, { 3, 3, 16 }, { 2, 4, 16 }, { 3, 5, 16 }, { 3, 6, 16 }, { 4, 7, 16 },
12573   { 2, 8, 16 }, { 3, 9, 16 }, { 3, 10, 16 }, { 4, 11, 16 }, { 3, 12, 16 }, { 4, 13, 16 }, { 4, 14, 16 }, { 5, 15, 16 },
12574   { 1, 0, 0 }, { 2, 1, 32 }, { 2, 2, 32 }, { 3, 3, 32 }, { 2, 4, 32 }, { 3, 5, 32 }, { 3, 6, 32 }, { 4, 7, 32 },
12575   { 2, 8, 32 }, { 3, 9, 32 }, { 3, 10, 32 }, { 4, 11, 32 }, { 3, 12, 32 }, { 4, 13, 32 }, { 4, 14, 32 }, { 5, 15, 32 },
12576   { 2, 16, 32 }, { 3, 17, 32 }, { 3, 18, 32 }, { 4, 19, 32 }, { 3, 20, 32 }, { 4, 21, 32 }, { 4, 22, 32 }, { 5, 23, 32 },
12577   { 3, 24, 32 }, { 4, 25, 32 }, { 4, 26, 32 }, { 5, 27, 32 }, { 4, 28, 32 }, { 5, 29, 32 }, { 5, 30, 32 }, { 6, 31, 32 },
12578#if FP_LUT > 6
12579   { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 },
12580   { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 },
12581   { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 },
12582   { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 },
12583   { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 },
12584   { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 },
12585   { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 },
12586   { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 },
12587#if FP_LUT > 7
12588   { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 },
12589   { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 },
12590   { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 },
12591   { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 },
12592   { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 },
12593   { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 },
12594   { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 },
12595   { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 },
12596   { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 },
12597   { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 },
12598   { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 },
12599   { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 },
12600   { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 },
12601   { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 },
12602   { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 },
12603   { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 },
12604#if FP_LUT > 8
12605   { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 },
12606   { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 },
12607   { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 },
12608   { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 },
12609   { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 },
12610   { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 },
12611   { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 },
12612   { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 },
12613   { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 },
12614   { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 },
12615   { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 },
12616   { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 },
12617   { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 },
12618   { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 },
12619   { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 },
12620   { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 },
12621   { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 },
12622   { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 },
12623   { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 },
12624   { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 },
12625   { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 },
12626   { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 },
12627   { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 },
12628   { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 },
12629   { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 },
12630   { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 },
12631   { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 },
12632   { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 },
12633   { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 },
12634   { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 },
12635   { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 },
12636   { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 },
12637#if FP_LUT > 9
12638   { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 },
12639   { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 },
12640   { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 },
12641   { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 },
12642   { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 },
12643   { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 },
12644   { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 },
12645   { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 },
12646   { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 },
12647   { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 },
12648   { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 },
12649   { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 },
12650   { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 },
12651   { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 },
12652   { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 },
12653   { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 },
12654   { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 },
12655   { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 },
12656   { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 },
12657   { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 },
12658   { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 },
12659   { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 },
12660   { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 },
12661   { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 },
12662   { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 },
12663   { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 },
12664   { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 },
12665   { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 },
12666   { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 },
12667   { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 },
12668   { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 },
12669   { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 },
12670   { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 },
12671   { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 },
12672   { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 },
12673   { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 },
12674   { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 },
12675   { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 },
12676   { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 },
12677   { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 },
12678   { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 },
12679   { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 },
12680   { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 },
12681   { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 },
12682   { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 },
12683   { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 },
12684   { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 },
12685   { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 },
12686   { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 },
12687   { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 },
12688   { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 },
12689   { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 },
12690   { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 },
12691   { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 },
12692   { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 },
12693   { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 },
12694   { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 },
12695   { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 },
12696   { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 },
12697   { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 },
12698   { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 },
12699   { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 },
12700   { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 },
12701   { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 },
12702#if FP_LUT > 10
12703   { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 },
12704   { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 },
12705   { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 },
12706   { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 },
12707   { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 },
12708   { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 },
12709   { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 },
12710   { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 },
12711   { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 },
12712   { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 },
12713   { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 },
12714   { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 },
12715   { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 },
12716   { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 },
12717   { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 },
12718   { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 },
12719   { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 },
12720   { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 },
12721   { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 },
12722   { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 },
12723   { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 },
12724   { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 },
12725   { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 },
12726   { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 },
12727   { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 },
12728   { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 },
12729   { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 },
12730   { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 },
12731   { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 },
12732   { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 },
12733   { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 },
12734   { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 },
12735   { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 },
12736   { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 },
12737   { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 },
12738   { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 },
12739   { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 },
12740   { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 },
12741   { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 },
12742   { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 },
12743   { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 },
12744   { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 },
12745   { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 },
12746   { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 },
12747   { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 },
12748   { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 },
12749   { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 },
12750   { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 },
12751   { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 },
12752   { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 },
12753   { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 },
12754   { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 },
12755   { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 },
12756   { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 },
12757   { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 },
12758   { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 },
12759   { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 },
12760   { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 },
12761   { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 },
12762   { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 },
12763   { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 },
12764   { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 },
12765   { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 },
12766   { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 },
12767   { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 },
12768   { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 },
12769   { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 },
12770   { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 },
12771   { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 },
12772   { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 },
12773   { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 },
12774   { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 },
12775   { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 },
12776   { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 },
12777   { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 },
12778   { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 },
12779   { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 },
12780   { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 },
12781   { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 },
12782   { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 },
12783   { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 },
12784   { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 },
12785   { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 },
12786   { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 },
12787   { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 },
12788   { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 },
12789   { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 },
12790   { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 },
12791   { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 },
12792   { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 },
12793   { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 },
12794   { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 },
12795   { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 },
12796   { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 },
12797   { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 },
12798   { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 },
12799   { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 },
12800   { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 },
12801   { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 },
12802   { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 },
12803   { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 },
12804   { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 },
12805   { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 },
12806   { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 },
12807   { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 },
12808   { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 },
12809   { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 },
12810   { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 },
12811   { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 },
12812   { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 },
12813   { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 },
12814   { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 },
12815   { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 },
12816   { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 },
12817   { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 },
12818   { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 },
12819   { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 },
12820   { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 },
12821   { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 },
12822   { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 },
12823   { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 },
12824   { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 },
12825   { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 },
12826   { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 },
12827   { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 },
12828   { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 },
12829   { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 },
12830   { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 },
12831#if FP_LUT > 11
12832   { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 },
12833   { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 },
12834   { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 },
12835   { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 },
12836   { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 },
12837   { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 },
12838   { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 },
12839   { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 },
12840   { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 },
12841   { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 },
12842   { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 },
12843   { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 },
12844   { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 },
12845   { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 },
12846   { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 },
12847   { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 },
12848   { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 },
12849   { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 },
12850   { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 },
12851   { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 },
12852   { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 },
12853   { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 },
12854   { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 },
12855   { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 },
12856   { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 },
12857   { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 },
12858   { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 },
12859   { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 },
12860   { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 },
12861   { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 },
12862   { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 },
12863   { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 },
12864   { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 },
12865   { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 },
12866   { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 },
12867   { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 },
12868   { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 },
12869   { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 },
12870   { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 },
12871   { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 },
12872   { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 },
12873   { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 },
12874   { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 },
12875   { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 },
12876   { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 },
12877   { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 },
12878   { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 },
12879   { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 },
12880   { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 },
12881   { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 },
12882   { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 },
12883   { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 },
12884   { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 },
12885   { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 },
12886   { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 },
12887   { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 },
12888   { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 },
12889   { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 },
12890   { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 },
12891   { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 },
12892   { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 },
12893   { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 },
12894   { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 },
12895   { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 },
12896   { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 },
12897   { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 },
12898   { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 },
12899   { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 },
12900   { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 },
12901   { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 },
12902   { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 },
12903   { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 },
12904   { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 },
12905   { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 },
12906   { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 },
12907   { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 },
12908   { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 },
12909   { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 },
12910   { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 },
12911   { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 },
12912   { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 },
12913   { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 },
12914   { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 },
12915   { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 },
12916   { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 },
12917   { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 },
12918   { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 },
12919   { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 },
12920   { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 },
12921   { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 },
12922   { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 },
12923   { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 },
12924   { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 },
12925   { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 },
12926   { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 },
12927   { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 },
12928   { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 },
12929   { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 },
12930   { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 },
12931   { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 },
12932   { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 },
12933   { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 },
12934   { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 },
12935   { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 },
12936   { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 },
12937   { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 },
12938   { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 },
12939   { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 },
12940   { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 },
12941   { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 },
12942   { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 },
12943   { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 },
12944   { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 },
12945   { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 },
12946   { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 },
12947   { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 },
12948   { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 },
12949   { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 },
12950   { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 },
12951   { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 },
12952   { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 },
12953   { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 },
12954   { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 },
12955   { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 },
12956   { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 },
12957   { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 },
12958   { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 },
12959   { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 },
12960   { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 },
12961   { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 },
12962   { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 },
12963   { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 },
12964   { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 },
12965   { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 },
12966   { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 },
12967   { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 },
12968   { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 },
12969   { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 },
12970   { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 },
12971   { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 },
12972   { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 },
12973   { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 },
12974   { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 },
12975   { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 },
12976   { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 },
12977   { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 },
12978   { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 },
12979   { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 },
12980   { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 },
12981   { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 },
12982   { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 },
12983   { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 },
12984   { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 },
12985   { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 },
12986   { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 },
12987   { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 },
12988   { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 },
12989   { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 },
12990   { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 },
12991   { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 },
12992   { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 },
12993   { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 },
12994   { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 },
12995   { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 },
12996   { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 },
12997   { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 },
12998   { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 },
12999   { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 },
13000   { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 },
13001   { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 },
13002   { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 },
13003   { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 },
13004   { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 },
13005   { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 },
13006   { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 },
13007   { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 },
13008   { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 },
13009   { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 },
13010   { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 },
13011   { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 },
13012   { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 },
13013   { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 },
13014   { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 },
13015   { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 },
13016   { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 },
13017   { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 },
13018   { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 },
13019   { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 },
13020   { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 },
13021   { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 },
13022   { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 },
13023   { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 },
13024   { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 },
13025   { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 },
13026   { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 },
13027   { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 },
13028   { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 },
13029   { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 },
13030   { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 },
13031   { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 },
13032   { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 },
13033   { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 },
13034   { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 },
13035   { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 },
13036   { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 },
13037   { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 },
13038   { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 },
13039   { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 },
13040   { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 },
13041   { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 },
13042   { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 },
13043   { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 },
13044   { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 },
13045   { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 },
13046   { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 },
13047   { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 },
13048   { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 },
13049   { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 },
13050   { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 },
13051   { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 },
13052   { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 },
13053   { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 },
13054   { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 },
13055   { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 },
13056   { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 },
13057   { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 },
13058   { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 },
13059   { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 },
13060   { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 },
13061   { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 },
13062   { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 },
13063   { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 },
13064   { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 },
13065   { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 },
13066   { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 },
13067   { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 },
13068   { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 },
13069   { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 },
13070   { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 },
13071   { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 },
13072   { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 },
13073   { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 },
13074   { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 },
13075   { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 },
13076   { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 },
13077   { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 },
13078   { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 },
13079   { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 },
13080   { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 },
13081   { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 },
13082   { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 },
13083   { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 },
13084   { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 },
13085   { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 },
13086   { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 },
13087   { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 },
13088#endif
13089#endif
13090#endif
13091#endif
13092#endif
13093#endif
13094};
13095
13096
13097/* find a hole and free as required, return -1 if no hole found */
13098static int find_hole(void)
13099{
13100#ifdef WOLFSSL_NO_MALLOC
13101   return -1;
13102#else
13103   int      x, y, z;
13104   for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
13105       if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
13106          z = x;
13107          y = fp_cache[x].lru_count;
13108       }
13109   }
13110
13111   /* decrease all */
13112   for (x = 0; x < FP_ENTRIES; x++) {
13113      if (fp_cache[x].lru_count > 3) {
13114         --(fp_cache[x].lru_count);
13115      }
13116   }
13117
13118   /* free entry z */
13119   if (z >= 0 && fp_cache[z].g) {
13120      mp_clear(&fp_cache[z].mu);
13121      wc_ecc_del_point(fp_cache[z].g);
13122      fp_cache[z].g  = NULL;
13123      for (x = 0; x < (1<<FP_LUT); x++) {
13124         wc_ecc_del_point(fp_cache[z].LUT[x]);
13125         fp_cache[z].LUT[x] = NULL;
13126      }
13127      fp_cache[z].LUT_set = 0;
13128      fp_cache[z].lru_count = 0;
13129   }
13130   return z;
13131#endif /* !WOLFSSL_NO_MALLOC */
13132}
13133
13134/* determine if a base is already in the cache and if so, where */
13135static int find_base(ecc_point* g)
13136{
13137   int x;
13138   for (x = 0; x < FP_ENTRIES; x++) {
13139      if (fp_cache[x].g != NULL &&
13140          mp_cmp(fp_cache[x].g->x, g->x) == MP_EQ &&
13141          mp_cmp(fp_cache[x].g->y, g->y) == MP_EQ &&
13142          mp_cmp(fp_cache[x].g->z, g->z) == MP_EQ) {
13143         break;
13144      }
13145   }
13146   if (x == FP_ENTRIES) {
13147      x = -1;
13148   }
13149   return x;
13150}
13151
13152/* add a new base to the cache */
13153static int add_entry(int idx, ecc_point *g)
13154{
13155   unsigned x, y;
13156
13157   /* allocate base and LUT */
13158   fp_cache[idx].g = wc_ecc_new_point();
13159   if (fp_cache[idx].g == NULL) {
13160      return MP_MEM;
13161   }
13162
13163   /* copy x and y */
13164   if ((mp_copy(g->x, fp_cache[idx].g->x) != MP_OKAY) ||
13165       (mp_copy(g->y, fp_cache[idx].g->y) != MP_OKAY) ||
13166       (mp_copy(g->z, fp_cache[idx].g->z) != MP_OKAY)) {
13167      wc_ecc_del_point(fp_cache[idx].g);
13168      fp_cache[idx].g = NULL;
13169      return MP_MEM;
13170   }
13171
13172   for (x = 0; x < (1U<<FP_LUT); x++) {
13173      fp_cache[idx].LUT[x] = wc_ecc_new_point();
13174      if (fp_cache[idx].LUT[x] == NULL) {
13175         for (y = 0; y < x; y++) {
13176            wc_ecc_del_point(fp_cache[idx].LUT[y]);
13177            fp_cache[idx].LUT[y] = NULL;
13178         }
13179         wc_ecc_del_point(fp_cache[idx].g);
13180         fp_cache[idx].g         = NULL;
13181         fp_cache[idx].lru_count = 0;
13182         return MP_MEM;
13183      }
13184   }
13185
13186   fp_cache[idx].LUT_set   = 0;
13187   fp_cache[idx].lru_count = 0;
13188
13189   return MP_OKAY;
13190}
13191#endif
13192
13193#if !defined(WOLFSSL_SP_MATH)
13194/* build the LUT by spacing the bits of the input by #modulus/FP_LUT bits apart
13195 *
13196 * The algorithm builds patterns in increasing bit order by first making all
13197 * single bit input patterns, then all two bit input patterns and so on
13198 */
13199static int build_lut(int idx, mp_int* a, mp_int* modulus, mp_digit mp,
13200    mp_int* mu)
13201{
13202   int err;
13203   unsigned x, y, bitlen, lut_gap;
13204   WC_DECLARE_VAR(tmp, mp_int, 1, 0);
13205   int infinity;
13206
13207#ifdef WOLFSSL_SMALL_STACK
13208   if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13209       return MEMORY_E;
13210#endif
13211
13212   err = mp_init(tmp);
13213   if (err != MP_OKAY) {
13214       err = MP_MEM;
13215       goto errout;
13216   }
13217
13218   /* sanity check to make sure lut_order table is of correct size,
13219      should compile out to a NOP if true */
13220   if ((sizeof(lut_orders) / sizeof(lut_orders[0])) < (1U<<FP_LUT)) {
13221       err = BAD_FUNC_ARG;
13222       goto errout;
13223   }
13224
13225   /* get bitlen and round up to next multiple of FP_LUT */
13226   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
13227   x       = bitlen % FP_LUT;
13228   if (x) {
13229       bitlen += FP_LUT - x;
13230   }
13231   lut_gap = bitlen / FP_LUT;
13232
13233   /* init the mu */
13234   err = mp_init_copy(&fp_cache[idx].mu, mu);
13235   if (err != MP_OKAY)
13236       goto errout;
13237
13238   /* copy base */
13239   if ((mp_mulmod(fp_cache[idx].g->x, mu, modulus,
13240                  fp_cache[idx].LUT[1]->x) != MP_OKAY) ||
13241       (mp_mulmod(fp_cache[idx].g->y, mu, modulus,
13242                  fp_cache[idx].LUT[1]->y) != MP_OKAY) ||
13243       (mp_mulmod(fp_cache[idx].g->z, mu, modulus,
13244                  fp_cache[idx].LUT[1]->z) != MP_OKAY)) {
13245       err = MP_MULMOD_E;
13246       goto errout;
13247   }
13248
13249   /* make all single bit entries */
13250   for (x = 1; x < FP_LUT; x++) {
13251      if ((mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->x,
13252                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->x) != MP_OKAY) ||
13253          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->y,
13254                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->y) != MP_OKAY) ||
13255          (mp_copy(fp_cache[idx].LUT[(unsigned int)(1 << (x-1))]->z,
13256                   fp_cache[idx].LUT[(unsigned int)(1 <<  x   )]->z) != MP_OKAY)) {
13257          err = MP_INIT_E;
13258          goto errout;
13259      } else {
13260
13261         /* now double it bitlen/FP_LUT times */
13262         for (y = 0; y < lut_gap; y++) {
13263             if ((err = ecc_projective_dbl_point_safe(
13264                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
13265                                      fp_cache[idx].LUT[(unsigned int)(1<<x)],
13266                                      a, modulus, mp)) != MP_OKAY) {
13267                 goto errout;
13268             }
13269         }
13270     }
13271  }
13272
13273   /* now make all entries in increase order of hamming weight */
13274   for (x = 2; x <= FP_LUT; x++) {
13275       if (err != MP_OKAY)
13276           goto errout;
13277       for (y = 0; y < (1UL<<FP_LUT); y++) {
13278           if (lut_orders[y].ham != (int)x) continue;
13279
13280           /* perform the add */
13281           if ((err = ecc_projective_add_point_safe(
13282                           fp_cache[idx].LUT[lut_orders[y].terma],
13283                           fp_cache[idx].LUT[lut_orders[y].termb],
13284                           fp_cache[idx].LUT[y], a, modulus, mp,
13285                           &infinity)) != MP_OKAY) {
13286               goto errout;
13287           }
13288       }
13289   }
13290
13291   /* now map all entries back to affine space to make point addition faster */
13292   for (x = 1; x < (1UL<<FP_LUT); x++) {
13293       if (err != MP_OKAY)
13294           break;
13295
13296       /* convert z to normal from montgomery */
13297       err = mp_montgomery_reduce(fp_cache[idx].LUT[x]->z, modulus, mp);
13298
13299       /* invert it */
13300       if (err == MP_OKAY)
13301         err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus,
13302                         fp_cache[idx].LUT[x]->z);
13303
13304       if (err == MP_OKAY)
13305         /* now square it */
13306         err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp);
13307
13308       if (err == MP_OKAY)
13309         /* fix x */
13310         err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus,
13311                         fp_cache[idx].LUT[x]->x);
13312
13313       if (err == MP_OKAY)
13314         /* get 1/z^3 */
13315         err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp);
13316
13317       if (err == MP_OKAY)
13318         /* fix y */
13319         err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus,
13320                         fp_cache[idx].LUT[x]->y);
13321
13322       if (err == MP_OKAY)
13323         /* free z */
13324         mp_clear(fp_cache[idx].LUT[x]->z);
13325   }
13326
13327  errout:
13328
13329   mp_clear(tmp);
13330   WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13331
13332   if (err == MP_OKAY) {
13333       fp_cache[idx].LUT_set = 1;
13334       return MP_OKAY;
13335   }
13336
13337   /* err cleanup */
13338   for (y = 0; y < (1U<<FP_LUT); y++) {
13339      wc_ecc_del_point(fp_cache[idx].LUT[y]);
13340      fp_cache[idx].LUT[y] = NULL;
13341   }
13342   wc_ecc_del_point(fp_cache[idx].g);
13343   fp_cache[idx].g         = NULL;
13344   fp_cache[idx].LUT_set   = 0;
13345   fp_cache[idx].lru_count = 0;
13346   mp_clear(&fp_cache[idx].mu);
13347
13348   return err;
13349}
13350
13351/* perform a fixed point ECC mulmod */
13352static int accel_fp_mul(int idx, const mp_int* k, ecc_point *R, mp_int* a,
13353                        mp_int* modulus, mp_digit mp, int map)
13354{
13355#ifdef WOLFCRYPT_HAVE_SAKKE
13356    #define KB_SIZE 256
13357#else
13358    #define KB_SIZE 128
13359#endif
13360
13361#ifdef WOLFSSL_SMALL_STACK
13362   unsigned char* kb = NULL;
13363   mp_int*        tk = NULL;
13364   mp_int*        order = NULL;
13365#else
13366   unsigned char kb[KB_SIZE];
13367   mp_int        tk[1];
13368   mp_int        order[1];
13369#endif
13370   int      x, err;
13371   unsigned y, z = 0, bitlen, bitpos, lut_gap;
13372   int first;
13373   int tk_zeroize = 0;
13374
13375#ifdef WOLFSSL_SMALL_STACK
13376   tk = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13377   if (tk == NULL) {
13378      err = MEMORY_E; goto done;
13379   }
13380   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13381   if (order == NULL) {
13382      err = MEMORY_E; goto done;
13383   }
13384#endif
13385
13386   if (mp_init_multi(tk, order, NULL, NULL, NULL, NULL) != MP_OKAY) {
13387       err = MP_INIT_E; goto done;
13388   }
13389
13390   if ((err = mp_copy(k, tk)) != MP_OKAY)
13391       goto done;
13392   tk_zeroize = 1;
13393
13394#ifdef WOLFSSL_CHECK_MEM_ZERO
13395   mp_memzero_add("accel_fp_mul tk", tk);
13396#endif
13397
13398   /* if it's smaller than modulus we fine */
13399   if (mp_unsigned_bin_size(k) > mp_unsigned_bin_size(modulus)) {
13400      /* find order */
13401       y = (unsigned)mp_unsigned_bin_size(modulus);
13402      for (x = 0; ecc_sets[x].size; x++) {
13403         if (y <= (unsigned)ecc_sets[x].size) break;
13404      }
13405
13406      /* back off if we are on the 521 bit curve */
13407      if (y == 66) --x;
13408
13409      if ((err = mp_read_radix(order, ecc_sets[x].order,
13410                                                MP_RADIX_HEX)) != MP_OKAY) {
13411         goto done;
13412      }
13413
13414      /* k must be less than modulus */
13415      if (mp_cmp(tk, order) != MP_LT) {
13416         if ((err = mp_mod(tk, order, tk)) != MP_OKAY) {
13417            goto done;
13418         }
13419      }
13420   }
13421
13422   /* get bitlen and round up to next multiple of FP_LUT */
13423   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
13424   x       = bitlen % FP_LUT;
13425   if (x) {
13426      bitlen += FP_LUT - (unsigned)x;
13427   }
13428   lut_gap = bitlen / FP_LUT;
13429
13430   /* get the k value */
13431   if (mp_unsigned_bin_size(tk) > (int)(KB_SIZE - 2)) {
13432      err = BUFFER_E; goto done;
13433   }
13434
13435   /* store k */
13436#ifdef WOLFSSL_SMALL_STACK
13437   kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13438   if (kb == NULL) {
13439      err = MEMORY_E; goto done;
13440   }
13441#endif
13442
13443   XMEMSET(kb, 0, KB_SIZE);
13444   if ((err = mp_to_unsigned_bin(tk, kb)) == MP_OKAY) {
13445   #ifdef WOLFSSL_CHECK_MEM_ZERO
13446      wc_MemZero_Add("accel_fp_mul kb", kb, KB_SIZE);
13447   #endif
13448      /* let's reverse kb so it's little endian */
13449      x = 0;
13450      y = (unsigned)mp_unsigned_bin_size(tk);
13451      if (y > 0) {
13452          y -= 1;
13453      }
13454
13455      while ((unsigned)x < y) {
13456         z = kb[x]; kb[x] = kb[y]; kb[y] = (byte)z;
13457         ++x; --y;
13458      }
13459
13460      /* at this point we can start, yipee */
13461      first = 1;
13462      for (x = (int)lut_gap-1; x >= 0; x--) {
13463          /* extract FP_LUT bits from kb spread out by lut_gap bits and offset
13464             by x bits from the start */
13465          bitpos = (unsigned)x;
13466          for (y = z = 0; y < FP_LUT; y++) {
13467             z |= (((word32)kb[bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13468             bitpos += lut_gap;  /* it's y*lut_gap + x, but here we can avoid
13469                                    the mult in each loop */
13470          }
13471
13472          /* double if not first */
13473          if (!first) {
13474             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
13475                                                              mp)) != MP_OKAY) {
13476                break;
13477             }
13478          }
13479
13480          /* add if not first, otherwise copy */
13481          if (!first && z) {
13482             if ((err = ecc_projective_add_point_safe(R, fp_cache[idx].LUT[z],
13483                                       R, a, modulus, mp, &first)) != MP_OKAY) {
13484                break;
13485             }
13486          } else if (z) {
13487             if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
13488                 (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
13489                 (mp_copy(&fp_cache[idx].mu,       R->z) != MP_OKAY)) {
13490                 err = MP_MEM;
13491                 break;
13492             }
13493             first = 0;
13494          }
13495      }
13496   }
13497
13498   if (err == MP_OKAY) {
13499      (void) z; /* Acknowledge the unused assignment */
13500      ForceZero(kb, KB_SIZE);
13501
13502      /* map R back from projective space */
13503      if (map) {
13504         err = ecc_map(R, modulus, mp);
13505      } else {
13506         err = MP_OKAY;
13507      }
13508   }
13509
13510done:
13511   /* cleanup */
13512   mp_clear(order);
13513   /* Ensure it was initialized. */
13514   if (tk_zeroize) {
13515       mp_forcezero(tk);
13516   }
13517
13518#ifdef WOLFSSL_SMALL_STACK
13519   XFREE(kb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13520   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13521   XFREE(tk, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13522#elif defined(WOLFSSL_CHECK_MEM_ZERO)
13523   wc_MemZero_Check(kb, KB_SIZE);
13524   mp_memzero_check(tk);
13525#endif
13526
13527#undef KB_SIZE
13528
13529   return err;
13530}
13531#endif
13532
13533#ifdef ECC_SHAMIR
13534#if !defined(WOLFSSL_SP_MATH)
13535/* perform a fixed point ECC mulmod */
13536static int accel_fp_mul2add(int idx1, int idx2,
13537                            mp_int* kA, mp_int* kB,
13538                            ecc_point *R, mp_int* a,
13539                            mp_int* modulus, mp_digit mp)
13540{
13541#define KB_SIZE 128
13542
13543#ifdef WOLFSSL_SMALL_STACK
13544   unsigned char* kb[2] = {NULL, NULL};
13545   mp_int*        tka = NULL;
13546   mp_int*        tkb = NULL;
13547   mp_int*        order = NULL;
13548#else
13549   unsigned char kb[2][KB_SIZE];
13550   mp_int        tka[1];
13551   mp_int        tkb[1];
13552   mp_int        order[1];
13553#endif
13554   int      x, err;
13555   unsigned y, z, bitlen, bitpos, lut_gap, zA, zB;
13556   int first;
13557
13558#ifdef WOLFSSL_SMALL_STACK
13559   tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13560   if (tka == NULL) {
13561      err = MEMORY_E; goto done;
13562   }
13563   tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13564   if (tkb == NULL) {
13565      err = MEMORY_E; goto done;
13566   }
13567   order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC);
13568   if (order == NULL) {
13569      err = MEMORY_E; goto done;
13570   }
13571#endif
13572
13573   if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) {
13574      err = MP_INIT_E; goto done;
13575   }
13576
13577   /* if it's smaller than modulus we fine */
13578   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
13579      /* find order */
13580      y = (unsigned)mp_unsigned_bin_size(modulus);
13581      for (x = 0; ecc_sets[x].size; x++) {
13582         if (y <= (unsigned)ecc_sets[x].size) break;
13583      }
13584
13585      /* back off if we are on the 521 bit curve */
13586      if (y == 66) --x;
13587
13588      if ((err = mp_read_radix(order, ecc_sets[x].order,
13589                                                MP_RADIX_HEX)) != MP_OKAY) {
13590         goto done;
13591      }
13592
13593      /* kA must be less than modulus */
13594      if (mp_cmp(kA, order) != MP_LT) {
13595         if ((err = mp_mod(kA, order, tka)) != MP_OKAY) {
13596            goto done;
13597         }
13598      } else {
13599         if ((err = mp_copy(kA, tka)) != MP_OKAY) {
13600            goto done;
13601         }
13602      }
13603   } else {
13604      if ((err = mp_copy(kA, tka)) != MP_OKAY) {
13605         goto done;
13606      }
13607   }
13608#ifdef WOLFSSL_CHECK_MEM_ZERO
13609   mp_memzero_add("accel_fp_mul2add tka", tka);
13610#endif
13611
13612   /* if it's smaller than modulus we fine */
13613   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
13614      /* find order */
13615      y = (unsigned)mp_unsigned_bin_size(modulus);
13616      for (x = 0; ecc_sets[x].size; x++) {
13617         if (y <= (unsigned)ecc_sets[x].size) break;
13618      }
13619
13620      /* back off if we are on the 521 bit curve */
13621      if (y == 66) --x;
13622
13623      if ((err = mp_read_radix(order, ecc_sets[x].order,
13624                                                MP_RADIX_HEX)) != MP_OKAY) {
13625         goto done;
13626      }
13627
13628      /* kB must be less than modulus */
13629      if (mp_cmp(kB, order) != MP_LT) {
13630         if ((err = mp_mod(kB, order, tkb)) != MP_OKAY) {
13631            goto done;
13632         }
13633      } else {
13634         if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
13635            goto done;
13636         }
13637      }
13638   } else {
13639      if ((err = mp_copy(kB, tkb)) != MP_OKAY) {
13640         goto done;
13641      }
13642   }
13643#ifdef WOLFSSL_CHECK_MEM_ZERO
13644   mp_memzero_add("accel_fp_mul2add tkb", tkb);
13645#endif
13646
13647   /* get bitlen and round up to next multiple of FP_LUT */
13648   bitlen  = (unsigned)mp_unsigned_bin_size(modulus) << 3;
13649   x       = bitlen % FP_LUT;
13650   if (x) {
13651      bitlen += FP_LUT - (unsigned)x;
13652   }
13653   lut_gap = bitlen / FP_LUT;
13654
13655   /* get the k value */
13656   if ((mp_unsigned_bin_size(tka) > (int)(KB_SIZE - 2)) ||
13657       (mp_unsigned_bin_size(tkb) > (int)(KB_SIZE - 2))  ) {
13658      err = BUFFER_E; goto done;
13659   }
13660
13661   /* store k */
13662#ifdef WOLFSSL_SMALL_STACK
13663   kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13664   if (kb[0] == NULL) {
13665      err = MEMORY_E; goto done;
13666   }
13667#endif
13668
13669   XMEMSET(kb[0], 0, KB_SIZE);
13670   if ((err = mp_to_unsigned_bin(tka, kb[0])) != MP_OKAY) {
13671      goto done;
13672   }
13673#ifdef WOLFSSL_CHECK_MEM_ZERO
13674   wc_MemZero_Add("accel_fp_mul2add kb[0]", kb[0], KB_SIZE);
13675#endif
13676
13677   /* let's reverse kb so it's little endian */
13678   x = 0;
13679   y = (unsigned)mp_unsigned_bin_size(tka);
13680   if (y > 0) {
13681       y -= 1;
13682   }
13683   mp_clear(tka);
13684   while ((unsigned)x < y) {
13685      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = (byte)z;
13686      ++x; --y;
13687   }
13688
13689   /* store b */
13690#ifdef WOLFSSL_SMALL_STACK
13691   kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13692   if (kb[1] == NULL) {
13693      err = MEMORY_E; goto done;
13694   }
13695#endif
13696
13697   XMEMSET(kb[1], 0, KB_SIZE);
13698#ifdef WOLFSSL_CHECK_MEM_ZERO
13699   wc_MemZero_Add("accel_fp_mul2add kb[1]", kb[1], KB_SIZE);
13700#endif
13701   if ((err = mp_to_unsigned_bin(tkb, kb[1])) == MP_OKAY) {
13702      x = 0;
13703      y = (unsigned)mp_unsigned_bin_size(tkb);
13704      if (y > 0) {
13705          y -= 1;
13706      }
13707
13708      while ((unsigned)x < y) {
13709         z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = (byte)z;
13710         ++x; --y;
13711      }
13712
13713      /* at this point we can start, yipee */
13714      first = 1;
13715      for (x = (int)lut_gap-1; x >= 0; x--) {
13716          /* extract FP_LUT bits from kb spread out by lut_gap bits and
13717             offset by x bits from the start */
13718          bitpos = (unsigned)x;
13719          for (y = zA = zB = 0; y < FP_LUT; y++) {
13720             zA |= (((word32)kb[0][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13721             zB |= (((word32)kb[1][bitpos>>3U] >> (bitpos&7U)) & 1U) << y;
13722             bitpos += lut_gap;    /* it's y*lut_gap + x, but here we can avoid
13723                                      the mult in each loop */
13724          }
13725
13726          /* double if not first */
13727          if (!first) {
13728             if ((err = ecc_projective_dbl_point_safe(R, R, a, modulus,
13729                                                              mp)) != MP_OKAY) {
13730                break;
13731             }
13732
13733             /* add if not first, otherwise copy */
13734             if (zA) {
13735                if ((err = ecc_projective_add_point_safe(R,
13736                                             fp_cache[idx1].LUT[zA], R, a,
13737                                             modulus, mp, &first)) != MP_OKAY) {
13738                   break;
13739                }
13740             }
13741
13742             if (zB) {
13743                if ((err = ecc_projective_add_point_safe(R,
13744                                             fp_cache[idx2].LUT[zB], R, a,
13745                                             modulus, mp, &first)) != MP_OKAY) {
13746                   break;
13747                }
13748             }
13749          } else {
13750             if (zA) {
13751                 if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
13752                     (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
13753                     (mp_copy(&fp_cache[idx1].mu,        R->z) != MP_OKAY)) {
13754                     err = MP_MEM;
13755                     break;
13756                 }
13757                    first = 0;
13758             }
13759             if (zB && first == 0) {
13760                if ((err = ecc_projective_add_point_safe(R,
13761                                        fp_cache[idx2].LUT[zB], R, a,
13762                                        modulus, mp, &first)) != MP_OKAY){
13763                   break;
13764                }
13765             } else if (zB && first == 1) {
13766                 if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
13767                     (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
13768                     (mp_copy(&fp_cache[idx2].mu,        R->z) != MP_OKAY)) {
13769                     err = MP_MEM;
13770                     break;
13771                 }
13772                    first = 0;
13773             }
13774          }
13775      }
13776   }
13777
13778done:
13779   /* cleanup */
13780   mp_forcezero(tkb);
13781   mp_forcezero(tka);
13782   mp_clear(order);
13783
13784#ifdef WOLFSSL_SMALL_STACK
13785   if (kb[0])
13786#endif
13787      ForceZero(kb[0], KB_SIZE);
13788#ifdef WOLFSSL_SMALL_STACK
13789   if (kb[1])
13790#endif
13791      ForceZero(kb[1], KB_SIZE);
13792
13793#ifdef WOLFSSL_SMALL_STACK
13794   XFREE(kb[1], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13795   XFREE(kb[0], NULL, DYNAMIC_TYPE_ECC_BUFFER);
13796   XFREE(order, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13797   XFREE(tkb, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13798   XFREE(tka, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13799#elif defined(WOLFSSL_CHECK_MEM_ZERO)
13800   wc_MemZero_Check(kb[1], KB_SIZE);
13801   wc_MemZero_Check(kb[0], KB_SIZE);
13802   mp_memzero_check(tkb);
13803   mp_memzero_check(tka);
13804#endif
13805
13806#undef KB_SIZE
13807
13808    if (err != MP_OKAY)
13809        return err;
13810
13811   return ecc_map(R, modulus, mp);
13812}
13813
13814
13815/** ECC Fixed Point mulmod global with heap hint used
13816  Computes kA*A + kB*B = C using Shamir's Trick
13817  A        First point to multiply
13818  kA       What to multiple A by
13819  B        Second point to multiply
13820  kB       What to multiple B by
13821  C        [out] Destination point (can overlap with A or B)
13822  a        ECC curve parameter a
13823  modulus  Modulus for curve
13824  return MP_OKAY on success
13825*/
13826int ecc_mul2add(ecc_point* A, mp_int* kA,
13827                ecc_point* B, mp_int* kB,
13828                ecc_point* C, mp_int* a, mp_int* modulus, void* heap)
13829{
13830   int  idx1 = -1, idx2 = -1, err, mpInit = 0;
13831   mp_digit mp = 0;
13832#ifdef WOLFSSL_SMALL_STACK
13833   mp_int   *mu = (mp_int *)XMALLOC(sizeof *mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13834
13835   if (mu == NULL)
13836       return MP_MEM;
13837#else
13838   mp_int   mu[1];
13839#endif
13840
13841   err = mp_init(mu);
13842   if (err != MP_OKAY) {
13843       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13844       return err;
13845   }
13846
13847#ifndef HAVE_THREAD_LS
13848#ifndef WOLFSSL_MUTEX_INITIALIZER
13849   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
13850        wc_InitMutex(&ecc_fp_lock);
13851        initMutex = 1;
13852   }
13853#endif
13854
13855   if (wc_LockMutex(&ecc_fp_lock) != 0) {
13856       WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13857      return BAD_MUTEX_E;
13858   }
13859#endif /* HAVE_THREAD_LS */
13860
13861      SAVE_VECTOR_REGISTERS(err = _svr_ret;);
13862
13863      /* find point */
13864      idx1 = find_base(A);
13865
13866      /* no entry? */
13867      if (idx1 == -1) {
13868         /* find hole and add it */
13869         if ((idx1 = find_hole()) >= 0) {
13870            err = add_entry(idx1, A);
13871         }
13872      }
13873      if (err == MP_OKAY && idx1 != -1 && fp_cache[idx1].lru_count < (INT_MAX-1)) {
13874         /* increment LRU */
13875         ++(fp_cache[idx1].lru_count);
13876      }
13877
13878      if (err == MP_OKAY) {
13879        /* find point */
13880        idx2 = find_base(B);
13881
13882        /* no entry? */
13883        if (idx2 == -1) {
13884           /* find hole and add it */
13885           if ((idx2 = find_hole()) >= 0)
13886              err = add_entry(idx2, B);
13887         }
13888      }
13889
13890      if (err == MP_OKAY && idx2 != -1 && fp_cache[idx2].lru_count < (INT_MAX-1)) {
13891         /* increment LRU */
13892         ++(fp_cache[idx2].lru_count);
13893      }
13894
13895      if (err == MP_OKAY) {
13896        /* if it's >= 2 AND the LUT is not set build the LUT */
13897        if (idx1 >= 0 && fp_cache[idx1].lru_count >= 2 && !fp_cache[idx1].LUT_set) {
13898           /* compute mp */
13899           err = mp_montgomery_setup(modulus, &mp);
13900
13901           if (err == MP_OKAY) {
13902             mpInit = 1;
13903             err = mp_montgomery_calc_normalization(mu, modulus);
13904           }
13905
13906           if (err == MP_OKAY)
13907             /* build the LUT */
13908             err = build_lut(idx1, a, modulus, mp, mu);
13909        }
13910      }
13911
13912      if (err == MP_OKAY) {
13913        /* if it's >= 2 AND the LUT is not set build the LUT */
13914        if (idx2 >= 0 && fp_cache[idx2].lru_count >= 2 && !fp_cache[idx2].LUT_set) {
13915           if (mpInit == 0) {
13916                /* compute mp */
13917                err = mp_montgomery_setup(modulus, &mp);
13918                if (err == MP_OKAY) {
13919                    mpInit = 1;
13920                    err = mp_montgomery_calc_normalization(mu, modulus);
13921                }
13922            }
13923
13924            if (err == MP_OKAY)
13925              /* build the LUT */
13926              err = build_lut(idx2, a, modulus, mp, mu);
13927        }
13928      }
13929
13930
13931      if (err == MP_OKAY) {
13932        if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].LUT_set &&
13933                                     fp_cache[idx2].LUT_set) {
13934           if (mpInit == 0) {
13935              /* compute mp */
13936              err = mp_montgomery_setup(modulus, &mp);
13937           }
13938           if (err == MP_OKAY)
13939             err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
13940        } else {
13941           err = normal_ecc_mul2add(A, kA, B, kB, C, a, modulus, heap);
13942        }
13943      }
13944
13945      RESTORE_VECTOR_REGISTERS();
13946
13947#ifndef HAVE_THREAD_LS
13948    wc_UnLockMutex(&ecc_fp_lock);
13949#endif /* HAVE_THREAD_LS */
13950    mp_clear(mu);
13951    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
13952
13953    return err;
13954}
13955#endif
13956#endif /* ECC_SHAMIR */
13957
13958/** ECC Fixed Point mulmod global
13959    k        The multiplicand
13960    G        Base point to multiply
13961    R        [out] Destination of product
13962    a        ECC curve parameter a
13963    modulus  The modulus for the curve
13964    map      [boolean] If non-zero maps the point back to affine coordinates,
13965             otherwise it's left in jacobian-montgomery form
13966    return MP_OKAY if successful
13967*/
13968int wc_ecc_mulmod_ex(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
13969    mp_int* modulus, int map, void* heap)
13970{
13971#if !defined(WOLFSSL_SP_MATH)
13972   int   idx, err = MP_OKAY;
13973   mp_digit mp = 0;
13974   WC_DECLARE_VAR(mu, mp_int, 1, 0);
13975   int      mpSetup = 0;
13976#ifndef HAVE_THREAD_LS
13977   int got_ecc_fp_lock = 0;
13978#endif
13979
13980   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
13981       return ECC_BAD_ARG_E;
13982   }
13983
13984   /* k can't have more bits than modulus count plus 1 */
13985   if (mp_count_bits(k) > mp_count_bits(modulus) + 1) {
13986      return ECC_OUT_OF_RANGE_E;
13987   }
13988
13989#ifdef WOLFSSL_SMALL_STACK
13990   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
13991       return MP_MEM;
13992#endif
13993
13994   if (mp_init(mu) != MP_OKAY) {
13995       err = MP_INIT_E;
13996       goto out;
13997   }
13998
13999#ifndef HAVE_THREAD_LS
14000#ifndef WOLFSSL_MUTEX_INITIALIZER
14001   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14002        wc_InitMutex(&ecc_fp_lock);
14003        initMutex = 1;
14004   }
14005#endif
14006
14007   if (wc_LockMutex(&ecc_fp_lock) != 0) {
14008      err = BAD_MUTEX_E;
14009      goto out;
14010   }
14011   got_ecc_fp_lock = 1;
14012#endif /* HAVE_THREAD_LS */
14013
14014      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
14015
14016      /* find point */
14017      idx = find_base(G);
14018
14019      /* no entry? */
14020      if (idx == -1) {
14021         /* find hole and add it */
14022         idx = find_hole();
14023
14024         if (idx >= 0)
14025            err = add_entry(idx, G);
14026      }
14027      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
14028         /* increment LRU */
14029         ++(fp_cache[idx].lru_count);
14030      }
14031
14032
14033      if (err == MP_OKAY) {
14034        /* if it's 2 build the LUT, if it's higher just use the LUT */
14035        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
14036           /* compute mp */
14037           err = mp_montgomery_setup(modulus, &mp);
14038
14039           if (err == MP_OKAY) {
14040             /* compute mu */
14041             mpSetup = 1;
14042             err = mp_montgomery_calc_normalization(mu, modulus);
14043           }
14044
14045           if (err == MP_OKAY)
14046             /* build the LUT */
14047             err = build_lut(idx, a, modulus, mp, mu);
14048        }
14049      }
14050
14051      if (err == MP_OKAY) {
14052        if (idx >= 0 && fp_cache[idx].LUT_set) {
14053           if (mpSetup == 0) {
14054              /* compute mp */
14055              err = mp_montgomery_setup(modulus, &mp);
14056           }
14057           if (err == MP_OKAY)
14058             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
14059        } else {
14060           err = normal_ecc_mulmod(k, G, R, a, modulus, NULL, map, heap);
14061        }
14062      }
14063
14064      RESTORE_VECTOR_REGISTERS();
14065
14066  out:
14067
14068#ifndef HAVE_THREAD_LS
14069    if (got_ecc_fp_lock)
14070        wc_UnLockMutex(&ecc_fp_lock);
14071#endif /* HAVE_THREAD_LS */
14072    mp_clear(mu);
14073    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14074
14075    return err;
14076
14077#else /* WOLFSSL_SP_MATH */
14078
14079    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL) {
14080        return ECC_BAD_ARG_E;
14081    }
14082    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
14083        mp_count_bits(G->y) > mp_count_bits(modulus) ||
14084        mp_count_bits(G->z) > mp_count_bits(modulus)) {
14085        return IS_POINT_E;
14086    }
14087
14088#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
14089    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
14090        int ret;
14091        SAVE_VECTOR_REGISTERS(return _svr_ret);
14092        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
14093        RESTORE_VECTOR_REGISTERS();
14094        return ret;
14095    }
14096#endif
14097#ifndef WOLFSSL_SP_NO_256
14098    if (mp_count_bits(modulus) == 256) {
14099        int ret;
14100        SAVE_VECTOR_REGISTERS(return _svr_ret;);
14101        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
14102        RESTORE_VECTOR_REGISTERS();
14103        return ret;
14104    }
14105#endif
14106#ifdef WOLFSSL_SP_384
14107    if (mp_count_bits(modulus) == 384) {
14108        int ret;
14109        SAVE_VECTOR_REGISTERS(return _svr_ret;);
14110        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
14111        RESTORE_VECTOR_REGISTERS();
14112        return ret;
14113    }
14114#endif
14115#ifdef WOLFSSL_SP_521
14116    if (mp_count_bits(modulus) == 521) {
14117        int ret;
14118        SAVE_VECTOR_REGISTERS(return _svr_ret;);
14119        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
14120        RESTORE_VECTOR_REGISTERS();
14121        return ret;
14122    }
14123#endif
14124    return WC_KEY_SIZE_E;
14125#endif /* WOLFSSL_SP_MATH */
14126}
14127
14128/** ECC Fixed Point mulmod global
14129    k        The multiplicand
14130    G        Base point to multiply
14131    R        [out] Destination of product
14132    a        ECC curve parameter a
14133    modulus  The modulus for the curve
14134    map      [boolean] If non-zero maps the point back to affine coordinates,
14135             otherwise it's left in jacobian-montgomery form
14136    return MP_OKAY if successful
14137*/
14138int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point *G, ecc_point *R, mp_int* a,
14139    mp_int* modulus, mp_int* order, WC_RNG* rng, int map, void* heap)
14140{
14141#if !defined(WOLFSSL_SP_MATH)
14142   int   idx, err = MP_OKAY;
14143   mp_digit mp = 0;
14144   WC_DECLARE_VAR(mu, mp_int, 1, 0);
14145   int      mpSetup = 0;
14146#ifndef HAVE_THREAD_LS
14147   int got_ecc_fp_lock = 0;
14148#endif
14149
14150   if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
14151                                                                order == NULL) {
14152       return ECC_BAD_ARG_E;
14153   }
14154
14155   /* k can't have more bits than order */
14156   if (mp_count_bits(k) > mp_count_bits(order)) {
14157      return ECC_OUT_OF_RANGE_E;
14158   }
14159
14160#ifdef WOLFSSL_SMALL_STACK
14161   if ((mu = (mp_int *)XMALLOC(sizeof(*mu), NULL, DYNAMIC_TYPE_ECC_BUFFER)) == NULL)
14162       return MP_MEM;
14163#endif
14164
14165   if (mp_init(mu) != MP_OKAY) {
14166       err = MP_INIT_E;
14167       goto out;
14168   }
14169
14170#ifndef HAVE_THREAD_LS
14171#ifndef WOLFSSL_MUTEX_INITIALIZER
14172   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14173        wc_InitMutex(&ecc_fp_lock);
14174        initMutex = 1;
14175   }
14176#endif
14177
14178   if (wc_LockMutex(&ecc_fp_lock) != 0) {
14179      err = BAD_MUTEX_E;
14180      goto out;
14181   }
14182   got_ecc_fp_lock = 1;
14183#endif /* HAVE_THREAD_LS */
14184
14185      SAVE_VECTOR_REGISTERS(err = _svr_ret; goto out;);
14186
14187      /* find point */
14188      idx = find_base(G);
14189
14190      /* no entry? */
14191      if (idx == -1) {
14192         /* find hole and add it */
14193         idx = find_hole();
14194
14195         if (idx >= 0)
14196            err = add_entry(idx, G);
14197      }
14198      if (err == MP_OKAY && idx >= 0 && fp_cache[idx].lru_count < (INT_MAX-1)) {
14199         /* increment LRU */
14200         ++(fp_cache[idx].lru_count);
14201      }
14202
14203
14204      if (err == MP_OKAY) {
14205        /* if it's 2 build the LUT, if it's higher just use the LUT */
14206        if (idx >= 0 && fp_cache[idx].lru_count >= 2 && !fp_cache[idx].LUT_set) {
14207           /* compute mp */
14208           err = mp_montgomery_setup(modulus, &mp);
14209
14210           if (err == MP_OKAY) {
14211             /* compute mu */
14212             mpSetup = 1;
14213             err = mp_montgomery_calc_normalization(mu, modulus);
14214           }
14215
14216           if (err == MP_OKAY)
14217             /* build the LUT */
14218             err = build_lut(idx, a, modulus, mp, mu);
14219        }
14220      }
14221
14222      if (err == MP_OKAY) {
14223        if (idx >= 0 && fp_cache[idx].LUT_set) {
14224           if (mpSetup == 0) {
14225              /* compute mp */
14226              err = mp_montgomery_setup(modulus, &mp);
14227           }
14228           if (err == MP_OKAY)
14229             err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
14230        } else {
14231          err = normal_ecc_mulmod(k, G, R, a, modulus, rng, map, heap);
14232        }
14233      }
14234
14235      RESTORE_VECTOR_REGISTERS();
14236
14237  out:
14238
14239#ifndef HAVE_THREAD_LS
14240    if (got_ecc_fp_lock)
14241        wc_UnLockMutex(&ecc_fp_lock);
14242#endif /* HAVE_THREAD_LS */
14243    mp_clear(mu);
14244    WC_FREE_VAR_EX(mu, NULL, DYNAMIC_TYPE_ECC_BUFFER);
14245
14246    return err;
14247
14248#else /* WOLFSSL_SP_MATH */
14249
14250    (void)rng;
14251
14252    if (k == NULL || G == NULL || R == NULL || a == NULL || modulus == NULL ||
14253                                                                order == NULL) {
14254        return ECC_BAD_ARG_E;
14255    }
14256    if (mp_count_bits(G->x) > mp_count_bits(modulus) ||
14257        mp_count_bits(G->y) > mp_count_bits(modulus) ||
14258        mp_count_bits(G->z) > mp_count_bits(modulus)) {
14259        return IS_POINT_E;
14260    }
14261
14262#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
14263    if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
14264        int ret;
14265        SAVE_VECTOR_REGISTERS(return _svr_ret;);
14266        ret = sp_ecc_mulmod_sm2_256(k, G, R, map, heap);
14267        RESTORE_VECTOR_REGISTERS();
14268        return ret;
14269    }
14270#endif
14271#ifndef WOLFSSL_SP_NO_256
14272    if (mp_count_bits(modulus) == 256) {
14273        int ret;
14274        SAVE_VECTOR_REGISTERS(return _svr_ret;);
14275        ret = sp_ecc_mulmod_256(k, G, R, map, heap);
14276        RESTORE_VECTOR_REGISTERS();
14277        return ret;
14278    }
14279#endif
14280#ifdef WOLFSSL_SP_384
14281    if (mp_count_bits(modulus) == 384) {
14282        int ret;
14283        SAVE_VECTOR_REGISTERS(return _svr_ret;);
14284        ret = sp_ecc_mulmod_384(k, G, R, map, heap);
14285        RESTORE_VECTOR_REGISTERS();
14286        return ret;
14287    }
14288#endif
14289#ifdef WOLFSSL_SP_521
14290    if (mp_count_bits(modulus) == 521) {
14291        int ret;
14292        SAVE_VECTOR_REGISTERS(return _svr_ret;);
14293        ret = sp_ecc_mulmod_521(k, G, R, map, heap);
14294        RESTORE_VECTOR_REGISTERS();
14295        return ret;
14296    }
14297#endif
14298    return WC_KEY_SIZE_E;
14299#endif /* WOLFSSL_SP_MATH */
14300}
14301
14302#if !defined(WOLFSSL_SP_MATH)
14303/* helper function for freeing the cache ...
14304   must be called with the cache mutex locked */
14305static void wc_ecc_fp_free_cache(void)
14306{
14307   unsigned x, y;
14308   for (x = 0; x < FP_ENTRIES; x++) {
14309      if (fp_cache[x].g != NULL) {
14310         for (y = 0; y < (1U<<FP_LUT); y++) {
14311            wc_ecc_del_point(fp_cache[x].LUT[y]);
14312            fp_cache[x].LUT[y] = NULL;
14313         }
14314         wc_ecc_del_point(fp_cache[x].g);
14315         fp_cache[x].g         = NULL;
14316         mp_clear(&fp_cache[x].mu);
14317         fp_cache[x].LUT_set   = 0;
14318         fp_cache[x].lru_count = 0;
14319         fp_cache[x].lock = 0;
14320      }
14321   }
14322}
14323#endif
14324
14325
14326/** Init the Fixed Point cache */
14327void wc_ecc_fp_init(void)
14328{
14329#ifndef WOLFSSL_SP_MATH
14330#ifndef HAVE_THREAD_LS
14331#ifndef WOLFSSL_MUTEX_INITIALIZER
14332   if (initMutex == 0) {
14333        wc_InitMutex(&ecc_fp_lock);
14334        initMutex = 1;
14335   }
14336#endif
14337#endif
14338#endif
14339}
14340
14341
14342/** Free the Fixed Point cache */
14343WOLFSSL_ABI
14344void wc_ecc_fp_free(void)
14345{
14346#if !defined(WOLFSSL_SP_MATH)
14347#ifndef HAVE_THREAD_LS
14348#ifndef WOLFSSL_MUTEX_INITIALIZER
14349   if (initMutex == 0) { /* extra sanity check if wolfCrypt_Init not called */
14350        wc_InitMutex(&ecc_fp_lock);
14351        initMutex = 1;
14352   }
14353#endif
14354
14355   if (wc_LockMutex(&ecc_fp_lock) == 0) {
14356#endif /* HAVE_THREAD_LS */
14357
14358       wc_ecc_fp_free_cache();
14359
14360#ifndef HAVE_THREAD_LS
14361       wc_UnLockMutex(&ecc_fp_lock);
14362#ifndef WOLFSSL_MUTEX_INITIALIZER
14363       wc_FreeMutex(&ecc_fp_lock);
14364       initMutex = 0;
14365#endif
14366   }
14367#endif /* HAVE_THREAD_LS */
14368#endif
14369}
14370
14371
14372#endif /* FP_ECC */
14373
14374int wc_ecc_set_rng(ecc_key* key, WC_RNG* rng)
14375{
14376    int err = 0;
14377
14378#ifdef ECC_TIMING_RESISTANT
14379    if (key == NULL) {
14380        err = BAD_FUNC_ARG;
14381    }
14382    else {
14383        key->rng = rng;
14384    }
14385#else
14386    (void)key;
14387    (void)rng;
14388    /* report success, not an error if ECC_TIMING_RESISTANT is not defined */
14389#endif
14390
14391    return err;
14392}
14393
14394#ifdef HAVE_ECC_ENCRYPT
14395
14396
14397enum ecCliState {
14398    ecCLI_INIT      = 1,
14399    ecCLI_SALT_GET  = 2,
14400    ecCLI_SALT_SET  = 3,
14401    ecCLI_SENT_REQ  = 4,
14402    ecCLI_RECV_RESP = 5,
14403    ecCLI_BAD_STATE = 99
14404};
14405
14406enum ecSrvState {
14407    ecSRV_INIT      = 1,
14408    ecSRV_SALT_GET  = 2,
14409    ecSRV_SALT_SET  = 3,
14410    ecSRV_RECV_REQ  = 4,
14411    ecSRV_SENT_RESP = 5,
14412    ecSRV_BAD_STATE = 99
14413};
14414
14415
14416struct ecEncCtx {
14417    byte* kdfSalt;         /* optional salt for kdf */
14418    const byte* kdfInfo;   /* optional info for kdf */
14419    const byte* macSalt;   /* optional salt for mac */
14420    word32    kdfSaltSz;   /* size of kdfSalt */
14421    word32    kdfInfoSz;   /* size of kdfInfo */
14422    word32    macSaltSz;   /* size of macSalt */
14423    void*     heap;        /* heap hint for memory used */
14424    byte      clientSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
14425    byte      serverSalt[EXCHANGE_SALT_SZ];  /* for msg exchange */
14426    byte      encAlgo;     /* which encryption type */
14427    byte      kdfAlgo;     /* which key derivation function type */
14428    byte      macAlgo;     /* which mac function type */
14429    byte      protocol;    /* are we REQ_RESP client or server ? */
14430    byte      cliSt;       /* protocol state, for sanity checks */
14431    byte      srvSt;       /* protocol state, for sanity checks */
14432    WC_RNG*   rng;
14433};
14434
14435/* optional set info, can be called before or after set_peer_salt */
14436int wc_ecc_ctx_set_algo(ecEncCtx* ctx, byte encAlgo, byte kdfAlgo, byte macAlgo)
14437{
14438    if (ctx == NULL)
14439        return BAD_FUNC_ARG;
14440
14441    ctx->encAlgo = encAlgo;
14442    ctx->kdfAlgo = kdfAlgo;
14443    ctx->macAlgo = macAlgo;
14444
14445    return 0;
14446}
14447
14448
14449const byte* wc_ecc_ctx_get_own_salt(ecEncCtx* ctx)
14450{
14451    if (ctx == NULL || ctx->protocol == 0)
14452        return NULL;
14453
14454    if (ctx->protocol == REQ_RESP_CLIENT) {
14455        if (ctx->cliSt == ecCLI_INIT) {
14456            ctx->cliSt =  ecCLI_SALT_GET;
14457            return ctx->clientSalt;
14458        }
14459        else {
14460            ctx->cliSt = ecCLI_BAD_STATE;
14461            return NULL;
14462        }
14463    }
14464    else if (ctx->protocol == REQ_RESP_SERVER) {
14465        if (ctx->srvSt == ecSRV_INIT) {
14466            ctx->srvSt =  ecSRV_SALT_GET;
14467            return ctx->serverSalt;
14468        }
14469        else {
14470            ctx->srvSt = ecSRV_BAD_STATE;
14471            return NULL;
14472        }
14473    }
14474
14475    return NULL;
14476}
14477
14478
14479/* optional set info, can be called before or after set_peer_salt */
14480int wc_ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz)
14481{
14482    if (ctx == NULL || info == 0 || sz < 0)
14483        return BAD_FUNC_ARG;
14484
14485    ctx->kdfInfo   = info;
14486    ctx->kdfInfoSz = (word32)sz;
14487
14488    return 0;
14489}
14490
14491
14492static const char* exchange_info = "Secure Message Exchange";
14493
14494int wc_ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt)
14495{
14496    byte tmp[EXCHANGE_SALT_SZ/2];
14497    int  halfSz = EXCHANGE_SALT_SZ/2;
14498
14499    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
14500        return BAD_FUNC_ARG;
14501
14502    if (ctx->protocol == REQ_RESP_CLIENT) {
14503        XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ);
14504        if (ctx->cliSt == ecCLI_SALT_GET)
14505            ctx->cliSt =  ecCLI_SALT_SET;
14506        else {
14507            ctx->cliSt =  ecCLI_BAD_STATE;
14508            return BAD_STATE_E;
14509        }
14510    }
14511    else {
14512        XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ);
14513        if (ctx->srvSt == ecSRV_SALT_GET)
14514            ctx->srvSt =  ecSRV_SALT_SET;
14515        else {
14516            ctx->srvSt =  ecSRV_BAD_STATE;
14517            return BAD_STATE_E;
14518        }
14519    }
14520
14521    /* mix half and half */
14522    /* tmp stores 2nd half of client before overwrite */
14523    XMEMCPY(tmp, ctx->clientSalt + halfSz, (size_t)halfSz);
14524    XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, (size_t)halfSz);
14525    XMEMCPY(ctx->serverSalt, tmp, (size_t)halfSz);
14526
14527    ctx->kdfSalt   = ctx->clientSalt;
14528    ctx->kdfSaltSz = EXCHANGE_SALT_SZ;
14529
14530    ctx->macSalt   = ctx->serverSalt;
14531    ctx->macSaltSz = EXCHANGE_SALT_SZ;
14532
14533    if (ctx->kdfInfo == NULL) {
14534        /* default info */
14535        ctx->kdfInfo   = (const byte*)exchange_info;
14536        ctx->kdfInfoSz = EXCHANGE_INFO_SZ;
14537    }
14538
14539    return 0;
14540}
14541
14542/* Set the salt pointer into context.
14543 *
14544 * @param  [in, out]  ctx   ECIES context object.
14545 * @param  [in]       salt  Salt to use with KDF.
14546 * @param  [in]       sz    Length of salt in bytes.
14547 * @return  0 on success.
14548 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
14549 */
14550int wc_ecc_ctx_set_kdf_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
14551{
14552    if (ctx == NULL || (salt == NULL && sz != 0))
14553        return BAD_FUNC_ARG;
14554
14555    /* truncate salt if exceeds max */
14556    if (sz > EXCHANGE_SALT_SZ)
14557        sz = EXCHANGE_SALT_SZ;
14558
14559    /* using a custom kdf salt, so borrow clientSalt/serverSalt for it,
14560     * since wc_ecc_ctx_set_peer_salt will set kdf and mac salts */
14561    if (ctx->protocol == REQ_RESP_CLIENT) {
14562        ctx->cliSt = ecCLI_SALT_SET;
14563        ctx->kdfSalt = ctx->clientSalt;
14564    }
14565    else if (ctx->protocol == REQ_RESP_SERVER) {
14566        ctx->srvSt = ecSRV_SALT_SET;
14567        ctx->kdfSalt = ctx->serverSalt;
14568    }
14569
14570    if (salt != NULL) {
14571        XMEMCPY((byte*)ctx->kdfSalt, salt, sz);
14572    }
14573    ctx->kdfSaltSz = sz;
14574
14575    return 0;
14576}
14577
14578/* Set your own salt. By default we generate a random salt for ourselves.
14579 * This allows overriding that after init or reset.
14580 *
14581 * @param  [in, out]  ctx   ECIES context object.
14582 * @param  [in]       salt  Salt to use for ourselves
14583 * @param  [in]       sz    Length of salt in bytes.
14584 * @return  0 on success.
14585 * @return  BAD_FUNC_ARG when ctx is NULL or salt is NULL and len is not 0.
14586 */
14587int wc_ecc_ctx_set_own_salt(ecEncCtx* ctx, const byte* salt, word32 sz)
14588{
14589    byte* saltBuffer;
14590
14591    if (ctx == NULL || ctx->protocol == 0 || salt == NULL)
14592        return BAD_FUNC_ARG;
14593
14594    if (sz > EXCHANGE_SALT_SZ)
14595        sz = EXCHANGE_SALT_SZ;
14596    saltBuffer = (ctx->protocol == REQ_RESP_CLIENT) ?
14597        ctx->clientSalt :
14598        ctx->serverSalt;
14599    XMEMSET(saltBuffer, 0, EXCHANGE_SALT_SZ);
14600    XMEMCPY(saltBuffer, salt, sz);
14601
14602    return 0;
14603}
14604
14605
14606static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags)
14607{
14608    byte* saltBuffer;
14609
14610    if (ctx == NULL || flags == 0)
14611        return BAD_FUNC_ARG;
14612
14613    saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt;
14614
14615    return wc_RNG_GenerateBlock(ctx->rng, saltBuffer, EXCHANGE_SALT_SZ);
14616}
14617
14618static void ecc_ctx_init(ecEncCtx* ctx, int flags, WC_RNG* rng)
14619{
14620    if (ctx) {
14621        XMEMSET(ctx, 0, sizeof(ecEncCtx));
14622
14623    #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14624        #ifdef WOLFSSL_AES_128
14625            ctx->encAlgo  = ecAES_128_CBC;
14626        #else
14627            ctx->encAlgo  = ecAES_256_CBC;
14628        #endif
14629    #elif !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14630        #ifdef WOLFSSL_AES_256
14631            ctx->encAlgo  = ecAES_256_CTR;
14632        #else
14633            ctx->encAlgo  = ecAES_128_CTR;
14634        #endif
14635    #else
14636        #error "No valid encryption algorithm for ECIES configured."
14637    #endif
14638        ctx->kdfAlgo  = ecHKDF_SHA256;
14639        ctx->macAlgo  = ecHMAC_SHA256;
14640        ctx->protocol = (byte)flags;
14641        ctx->rng      = rng;
14642
14643        if (flags == REQ_RESP_CLIENT)
14644            ctx->cliSt = ecCLI_INIT;
14645        if (flags == REQ_RESP_SERVER)
14646            ctx->srvSt = ecSRV_INIT;
14647    }
14648}
14649
14650
14651/* allow ecc context reset so user doesn't have to init/free for reuse */
14652WOLFSSL_ABI
14653int wc_ecc_ctx_reset(ecEncCtx* ctx, WC_RNG* rng)
14654{
14655    if (ctx == NULL || rng == NULL)
14656        return BAD_FUNC_ARG;
14657
14658    ecc_ctx_init(ctx, ctx->protocol, rng);
14659    return ecc_ctx_set_salt(ctx, ctx->protocol);
14660}
14661
14662
14663ecEncCtx* wc_ecc_ctx_new_ex(int flags, WC_RNG* rng, void* heap)
14664{
14665    int       ret = 0;
14666    ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), heap,
14667                                                              DYNAMIC_TYPE_ECC);
14668
14669    if (ctx) {
14670        ctx->protocol = (byte)flags;
14671        ctx->heap     = heap;
14672    }
14673
14674    ret = wc_ecc_ctx_reset(ctx, rng);
14675    if (ret != 0) {
14676        wc_ecc_ctx_free(ctx);
14677        ctx = NULL;
14678    }
14679
14680    return ctx;
14681}
14682
14683
14684/* alloc/init and set defaults, return new Context  */
14685WOLFSSL_ABI
14686ecEncCtx* wc_ecc_ctx_new(int flags, WC_RNG* rng)
14687{
14688    return wc_ecc_ctx_new_ex(flags, rng, NULL);
14689}
14690
14691
14692/* free any resources, clear any keys */
14693WOLFSSL_ABI
14694void wc_ecc_ctx_free(ecEncCtx* ctx)
14695{
14696    if (ctx) {
14697        void* heap = ctx->heap;
14698        ForceZero(ctx, sizeof(ecEncCtx));
14699        XFREE(ctx, heap, DYNAMIC_TYPE_ECC);
14700        (void)heap;
14701    }
14702}
14703
14704static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz,
14705                             int* keysLen, word32* digestSz, word32* blockSz)
14706{
14707    if (ctx) {
14708        switch (ctx->encAlgo) {
14709        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14710            case ecAES_128_CBC:
14711                *encKeySz = KEY_SIZE_128;
14712                *ivSz     = IV_SIZE_128;
14713                *blockSz  = WC_AES_BLOCK_SIZE;
14714                break;
14715            case ecAES_256_CBC:
14716                *encKeySz = KEY_SIZE_256;
14717                *ivSz     = IV_SIZE_128;
14718                *blockSz  = WC_AES_BLOCK_SIZE;
14719                break;
14720        #endif
14721        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
14722            case ecAES_128_CTR:
14723                *encKeySz = KEY_SIZE_128;
14724                *ivSz     = 12;
14725                *blockSz  = 1;
14726                break;
14727            case ecAES_256_CTR:
14728                *encKeySz = KEY_SIZE_256;
14729                *ivSz     = 12;
14730                *blockSz  = 1;
14731                break;
14732        #endif
14733            default:
14734                return BAD_FUNC_ARG;
14735        }
14736
14737        switch (ctx->macAlgo) {
14738            case ecHMAC_SHA256:
14739                *digestSz = WC_SHA256_DIGEST_SIZE;
14740                break;
14741            default:
14742                return BAD_FUNC_ARG;
14743        }
14744    } else
14745        return BAD_FUNC_ARG;
14746
14747#ifdef WOLFSSL_ECIES_OLD
14748    *keysLen  = *encKeySz + *ivSz + (int)*digestSz;
14749#else
14750    *keysLen  = *encKeySz + (int)*digestSz;
14751#endif
14752
14753    return 0;
14754}
14755
14756
14757/* ecc encrypt with shared secret run through kdf
14758   ctx holds non default algos and inputs
14759   msgSz should be the right size for encAlgo, i.e., already padded
14760   return 0 on success */
14761int wc_ecc_encrypt_ex(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
14762    word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx, int compressed)
14763{
14764    int          ret = 0;
14765    word32       blockSz = 0;
14766#ifndef WOLFSSL_ECIES_OLD
14767#ifndef WOLFSSL_ECIES_GEN_IV
14768    byte         iv[ECC_MAX_IV_SIZE];
14769#endif
14770    word32       pubKeySz = 0;
14771#endif
14772    word32       digestSz = 0;
14773    ecEncCtx     localCtx;
14774#ifdef WOLFSSL_SMALL_STACK
14775    byte*        sharedSecret;
14776    byte*        keys;
14777#else
14778#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14779    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
14780#else
14781    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
14782#endif
14783    byte         keys[ECC_BUFSIZE];         /* max size */
14784#endif
14785#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
14786    word32       sharedSz = ECC_MAXSIZE;
14787#else
14788    /* 'Uncompressed' byte | public key x | public key y | secret */
14789    word32       sharedSz = 1 + ECC_MAXSIZE * 3;
14790#endif
14791    int          keysLen = 0;
14792    int          encKeySz = 0;
14793    int          ivSz = 0;
14794    int          offset = 0;         /* keys offset if doing msg exchange */
14795    byte*        encKey = NULL;
14796    byte*        encIv = NULL;
14797    byte*        macKey = NULL;
14798
14799    if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL ||
14800                           outSz  == NULL)
14801        return BAD_FUNC_ARG;
14802
14803    if (ctx == NULL) {  /* use defaults */
14804        ecc_ctx_init(&localCtx, 0, NULL);
14805        ctx = &localCtx;
14806    }
14807
14808    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
14809                            &blockSz);
14810    if (ret != 0)
14811        return ret;
14812
14813#ifndef WOLFSSL_ECIES_OLD
14814    if (!compressed) {
14815        pubKeySz = 1 + (word32)wc_ecc_size(privKey) * 2;
14816    }
14817    else {
14818        pubKeySz = 1 + (word32)wc_ecc_size(privKey);
14819    }
14820#else
14821    (void) compressed; /* avoid unused parameter if WOLFSSL_ECIES_OLD is defined */
14822#endif
14823
14824    if (ctx->protocol == REQ_RESP_SERVER) {
14825        offset = keysLen;
14826        keysLen *= 2;
14827
14828        if (ctx->srvSt != ecSRV_RECV_REQ)
14829            return BAD_STATE_E;
14830
14831        ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
14832    }
14833    else if (ctx->protocol == REQ_RESP_CLIENT) {
14834        if (ctx->cliSt != ecCLI_SALT_SET)
14835            return BAD_STATE_E;
14836
14837        ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */
14838    }
14839
14840    if (keysLen > ECC_BUFSIZE) /* keys size */
14841        return BUFFER_E;
14842
14843    if ((msgSz % blockSz) != 0)
14844        return BAD_PADDING_E;
14845
14846#ifdef WOLFSSL_ECIES_OLD
14847    if (*outSz < (msgSz + digestSz))
14848        return BUFFER_E;
14849#elif defined(WOLFSSL_ECIES_GEN_IV)
14850    if (*outSz < (pubKeySz + ivSz + msgSz + digestSz))
14851        return BUFFER_E;
14852#else
14853    if (*outSz < (pubKeySz + msgSz + digestSz))
14854        return BUFFER_E;
14855#endif
14856
14857#ifdef ECC_TIMING_RESISTANT
14858    if (ctx->rng != NULL && privKey->rng == NULL)
14859        privKey->rng = ctx->rng;
14860#endif
14861
14862#ifndef WOLFSSL_ECIES_OLD
14863    if (privKey->type == ECC_PRIVATEKEY_ONLY) {
14864#ifdef ECC_TIMING_RESISTANT
14865        ret = wc_ecc_make_pub_ex(privKey, NULL, privKey->rng);
14866#else
14867        ret = wc_ecc_make_pub_ex(privKey, NULL, NULL);
14868#endif
14869        if (ret != 0)
14870            return ret;
14871    }
14872    ret = wc_ecc_export_x963_ex(privKey, out, &pubKeySz, compressed);
14873    if (ret != 0)
14874        return ret;
14875    out += pubKeySz;
14876#endif
14877
14878#ifdef WOLFSSL_SMALL_STACK
14879    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14880    if (sharedSecret == NULL)
14881        return MEMORY_E;
14882
14883    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14884    if (keys == NULL) {
14885        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
14886        return MEMORY_E;
14887    }
14888#endif
14889
14890    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
14891
14892#ifdef WOLFSSL_ECIES_ISO18033
14893    XMEMCPY(sharedSecret, out - pubKeySz, pubKeySz);
14894    sharedSz -= pubKeySz;
14895#endif
14896
14897    do {
14898    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
14899        ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
14900        if (ret != 0)
14901            break;
14902    #endif
14903    #ifndef WOLFSSL_ECIES_ISO18033
14904        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz);
14905    #else
14906        ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret + pubKeySz,
14907                                                                     &sharedSz);
14908    #endif
14909    }
14910    while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
14911
14912    if (ret == 0) {
14913    #ifdef WOLFSSL_ECIES_ISO18033
14914        /* KDF data is encoded public key and secret. */
14915        sharedSz += pubKeySz;
14916    #endif
14917        switch (ctx->kdfAlgo) {
14918            case ecHKDF_SHA256 :
14919                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
14920                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14921                           keys, (word32)keysLen);
14922                break;
14923            case ecHKDF_SHA1 :
14924                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
14925                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
14926                           keys, (word32)keysLen);
14927                break;
14928#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
14929            case ecKDF_X963_SHA1 :
14930                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14931                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14932                break;
14933            case ecKDF_X963_SHA256 :
14934                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14935                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
14936                break;
14937            case ecKDF_SHA1 :
14938                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
14939                           NULL, 0, keys, (word32)keysLen);
14940                break;
14941            case ecKDF_SHA256 :
14942                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
14943                           NULL, 0, keys, (word32)keysLen);
14944                break;
14945#endif
14946
14947
14948            default:
14949                ret = BAD_FUNC_ARG;
14950                break;
14951        }
14952    }
14953
14954    if (ret == 0) {
14955    #ifdef WOLFSSL_ECIES_OLD
14956        encKey = keys + offset;
14957        encIv  = encKey + encKeySz;
14958        macKey = encKey + encKeySz + ivSz;
14959    #elif defined(WOLFSSL_ECIES_GEN_IV)
14960        encKey = keys + offset;
14961        encIv  = out;
14962        out += ivSz;
14963        macKey = encKey + encKeySz;
14964        ret = wc_RNG_GenerateBlock(privKey->rng, encIv, ivSz);
14965    #else
14966        XMEMSET(iv, 0, (size_t)ivSz);
14967        encKey = keys + offset;
14968        encIv  = iv;
14969        macKey = encKey + encKeySz;
14970    #endif
14971    }
14972
14973    if (ret == 0) {
14974       switch (ctx->encAlgo) {
14975            case ecAES_128_CBC:
14976            case ecAES_256_CBC:
14977            {
14978        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
14979            #ifdef WOLFSSL_SMALL_STACK
14980                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
14981                                          DYNAMIC_TYPE_AES);
14982                if (aes == NULL) {
14983                    ret = MEMORY_E;
14984                    break;
14985                }
14986            #else
14987                Aes aes[1];
14988            #endif
14989                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
14990                if (ret == 0) {
14991                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
14992                                                                AES_ENCRYPTION);
14993                    if (ret == 0) {
14994                        ret = wc_AesCbcEncrypt(aes, out, msg, msgSz);
14995                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
14996                                                    defined(WC_ASYNC_ENABLE_AES)
14997                        ret = wc_AsyncWait(ret, &aes->asyncDev,
14998                                            WC_ASYNC_FLAG_NONE);
14999                    #endif
15000                    }
15001                    wc_AesFree(aes);
15002                }
15003                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15004        #else
15005                ret = NOT_COMPILED_IN;
15006        #endif
15007                break;
15008            }
15009            case ecAES_128_CTR:
15010            case ecAES_256_CTR:
15011            {
15012        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15013                byte ctr_iv[WC_AES_BLOCK_SIZE];
15014            #ifndef WOLFSSL_SMALL_STACK
15015                Aes aes[1];
15016            #else
15017                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
15018                                            DYNAMIC_TYPE_AES);
15019                if (aes == NULL) {
15020                    ret = MEMORY_E;
15021                    break;
15022                }
15023            #endif
15024
15025                /* Include 4 byte counter starting at all zeros. */
15026                XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
15027                XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
15028                    WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
15029
15030                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15031                if (ret == 0) {
15032                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
15033                                                                AES_ENCRYPTION);
15034                    if (ret == 0) {
15035                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz);
15036                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
15037                                                    defined(WC_ASYNC_ENABLE_AES)
15038                        ret = wc_AsyncWait(ret, &aes->asyncDev,
15039                                            WC_ASYNC_FLAG_NONE);
15040                    #endif
15041                    }
15042                    wc_AesFree(aes);
15043                }
15044                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15045        #else
15046                ret = NOT_COMPILED_IN;
15047        #endif
15048                break;
15049            }
15050            default:
15051                ret = BAD_FUNC_ARG;
15052                break;
15053        }
15054    }
15055
15056    if (ret == 0) {
15057        switch (ctx->macAlgo) {
15058            case ecHMAC_SHA256:
15059            {
15060            #ifdef WOLFSSL_SMALL_STACK
15061                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
15062                                             DYNAMIC_TYPE_HMAC);
15063                if (hmac == NULL) {
15064                    ret = MEMORY_E;
15065                    break;
15066                }
15067            #else
15068                Hmac hmac[1];
15069            #endif
15070                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
15071                if (ret == 0) {
15072                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
15073                                                         WC_SHA256_DIGEST_SIZE);
15074                    if (ret == 0) {
15075                    #if !defined(WOLFSSL_ECIES_GEN_IV)
15076                        ret = wc_HmacUpdate(hmac, out, msgSz);
15077                    #else
15078                        /* IV is before encrypted message. */
15079                        ret = wc_HmacUpdate(hmac, encIv, ivSz + msgSz);
15080                    #endif
15081                    }
15082                    if (ret == 0)
15083                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
15084                    if (ret == 0)
15085                        ret = wc_HmacFinal(hmac, out+msgSz);
15086                    wc_HmacFree(hmac);
15087                }
15088                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
15089                break;
15090            }
15091
15092            default:
15093                ret = BAD_FUNC_ARG;
15094                break;
15095        }
15096    }
15097
15098    if (ret == 0) {
15099#ifdef WOLFSSL_ECIES_OLD
15100        *outSz = msgSz + digestSz;
15101#elif defined(WOLFSSL_ECIES_GEN_IV)
15102        *outSz = pubKeySz + ivSz + msgSz + digestSz;
15103#else
15104        *outSz = pubKeySz + msgSz + digestSz;
15105#endif
15106    }
15107
15108    RESTORE_VECTOR_REGISTERS();
15109
15110    ForceZero(sharedSecret, sharedSz);
15111    ForceZero(keys, (word32)keysLen);
15112    WC_FREE_VAR_EX(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15113    WC_FREE_VAR_EX(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15114
15115    return ret;
15116}
15117
15118/* ecc encrypt with shared secret run through kdf
15119   ctx holds non default algos and inputs
15120   msgSz should be the right size for encAlgo, i.e., already padded
15121   return 0 on success */
15122WOLFSSL_ABI
15123int wc_ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
15124                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
15125{
15126    return wc_ecc_encrypt_ex(privKey, pubKey, msg, msgSz, out, outSz, ctx, 0);
15127}
15128
15129/* ecc decrypt with shared secret run through kdf
15130   ctx holds non default algos and inputs
15131   return 0 on success */
15132WOLFSSL_ABI
15133int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
15134                word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx)
15135{
15136    int          ret = 0;
15137    word32       blockSz = 0;
15138#ifndef WOLFSSL_ECIES_OLD
15139#ifndef WOLFSSL_ECIES_GEN_IV
15140    byte         iv[ECC_MAX_IV_SIZE];
15141#endif
15142    word32       pubKeySz = 0;
15143    WC_DECLARE_VAR(peerKey, ecc_key, 1, 0);
15144#endif
15145    word32       digestSz = 0;
15146    ecEncCtx     localCtx;
15147#ifdef WOLFSSL_SMALL_STACK
15148    byte*        sharedSecret;
15149    byte*        keys;
15150#else
15151#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15152    byte         sharedSecret[ECC_MAXSIZE];  /* 521 max size */
15153#else
15154    byte         sharedSecret[ECC_MAXSIZE * 3 + 1]; /* Public key too */
15155#endif
15156    byte         keys[ECC_BUFSIZE];         /* max size */
15157#endif
15158#if defined(WOLFSSL_ECIES_OLD) || !defined(WOLFSSL_ECIES_ISO18033)
15159    word32       sharedSz = ECC_MAXSIZE;
15160#else
15161    word32       sharedSz = ECC_MAXSIZE * 3 + 1;
15162#endif
15163    int          keysLen = 0;
15164    int          encKeySz = 0;
15165    int          ivSz = 0;
15166    int          offset = 0;       /* in case using msg exchange */
15167    byte*        encKey = NULL;
15168    const byte*  encIv = NULL;
15169    byte*        macKey = NULL;
15170
15171
15172    if (privKey == NULL || msg == NULL || out == NULL || outSz  == NULL)
15173        return BAD_FUNC_ARG;
15174#ifdef WOLFSSL_ECIES_OLD
15175    if (pubKey == NULL)
15176        return BAD_FUNC_ARG;
15177#endif
15178
15179    if (ctx == NULL) {  /* use defaults */
15180        ecc_ctx_init(&localCtx, 0, NULL);
15181        ctx = &localCtx;
15182    }
15183
15184    ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz,
15185                            &blockSz);
15186    if (ret != 0)
15187        return ret;
15188
15189#ifndef WOLFSSL_ECIES_OLD
15190    ret = ecc_public_key_size(privKey, &pubKeySz);
15191    if (ret != 0)
15192        return ret;
15193#ifdef HAVE_COMP_KEY
15194    if ((msgSz > 1) && ((msg[0] == 0x02) || (msg[0] == 0x03))) {
15195        pubKeySz = (pubKeySz / 2) + 1;
15196    }
15197#endif /* HAVE_COMP_KEY */
15198#endif /* WOLFSSL_ECIES_OLD */
15199
15200    if (ctx->protocol == REQ_RESP_CLIENT) {
15201        offset = keysLen;
15202        keysLen *= 2;
15203
15204        if (ctx->cliSt != ecCLI_SENT_REQ)
15205            return BAD_STATE_E;
15206
15207        ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */
15208    }
15209    else if (ctx->protocol == REQ_RESP_SERVER) {
15210        if (ctx->srvSt != ecSRV_SALT_SET)
15211            return BAD_STATE_E;
15212
15213        ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */
15214    }
15215
15216    if (keysLen > ECC_BUFSIZE) /* keys size */
15217        return BUFFER_E;
15218
15219#ifdef WOLFSSL_ECIES_OLD
15220    if (((msgSz - digestSz) % blockSz) != 0)
15221        return BAD_PADDING_E;
15222
15223    if (*outSz < (msgSz - digestSz))
15224        return BUFFER_E;
15225#elif defined(WOLFSSL_ECIES_GEN_IV)
15226    if (((msgSz - ivSz - digestSz - pubKeySz) % blockSz) != 0)
15227        return BAD_PADDING_E;
15228
15229    if (msgSz < pubKeySz + ivSz + blockSz + digestSz)
15230        return BAD_FUNC_ARG;
15231    if (*outSz < (msgSz - ivSz - digestSz - pubKeySz))
15232        return BUFFER_E;
15233#else
15234    if (((msgSz - digestSz - pubKeySz) % blockSz) != 0)
15235        return BAD_PADDING_E;
15236
15237    if (msgSz < pubKeySz + blockSz + digestSz)
15238        return BAD_FUNC_ARG;
15239    if (*outSz < (msgSz - digestSz - pubKeySz))
15240        return BUFFER_E;
15241#endif
15242
15243#ifdef ECC_TIMING_RESISTANT
15244    if (ctx->rng != NULL && privKey->rng == NULL)
15245        privKey->rng = ctx->rng;
15246#endif
15247
15248#ifdef WOLFSSL_SMALL_STACK
15249    sharedSecret = (byte*)XMALLOC(sharedSz, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15250    if (sharedSecret == NULL) {
15251    #ifndef WOLFSSL_ECIES_OLD
15252        if (pubKey == peerKey)
15253            wc_ecc_free(peerKey);
15254    #endif
15255        return MEMORY_E;
15256    }
15257
15258    keys = (byte*)XMALLOC(ECC_BUFSIZE, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15259    if (keys == NULL) {
15260        XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15261    #ifndef WOLFSSL_ECIES_OLD
15262        if (pubKey == peerKey)
15263            wc_ecc_free(peerKey);
15264    #endif
15265        return MEMORY_E;
15266    }
15267#endif
15268
15269    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
15270
15271#ifndef WOLFSSL_ECIES_OLD
15272    if (pubKey == NULL) {
15273        WC_ALLOC_VAR_EX(peerKey, ecc_key, 1, ctx->heap,
15274            DYNAMIC_TYPE_ECC_BUFFER, ret=MEMORY_E);
15275        pubKey = peerKey;
15276    }
15277    else {
15278        /* if a public key was passed in we should free it here before init
15279         * and import */
15280        wc_ecc_free(pubKey);
15281    }
15282    if (ret == 0) {
15283        ret = wc_ecc_init_ex(pubKey, privKey->heap, INVALID_DEVID);
15284    }
15285    if (ret == 0) {
15286        ret = wc_ecc_import_x963_ex(msg, pubKeySz, pubKey, privKey->dp->id);
15287    }
15288    if (ret == 0) {
15289        /* Point is not MACed. */
15290        msg += pubKeySz;
15291        msgSz -= pubKeySz;
15292    }
15293#endif
15294
15295    if (ret == 0) {
15296    #ifdef WOLFSSL_ECIES_ISO18033
15297        XMEMCPY(sharedSecret, msg - pubKeySz, pubKeySz);
15298        sharedSz -= pubKeySz;
15299    #endif
15300
15301        do {
15302        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
15303            ret = wc_AsyncWait(ret, &privKey->asyncDev,
15304                                                     WC_ASYNC_FLAG_CALL_AGAIN);
15305            if (ret != 0)
15306                break;
15307        #endif
15308        #ifndef WOLFSSL_ECIES_ISO18033
15309            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret,
15310                                                                    &sharedSz);
15311        #else
15312            ret = wc_ecc_shared_secret(privKey, pubKey, sharedSecret +
15313                                                          pubKeySz, &sharedSz);
15314        #endif
15315        } while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
15316    }
15317    if (ret == 0) {
15318    #ifdef WOLFSSL_ECIES_ISO18033
15319        /* KDF data is encoded public key and secret. */
15320        sharedSz += pubKeySz;
15321    #endif
15322        switch (ctx->kdfAlgo) {
15323            case ecHKDF_SHA256 :
15324                ret = wc_HKDF(WC_SHA256, sharedSecret, sharedSz, ctx->kdfSalt,
15325                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
15326                           keys, (word32)keysLen);
15327                break;
15328            case ecHKDF_SHA1 :
15329                ret = wc_HKDF(WC_SHA, sharedSecret, sharedSz, ctx->kdfSalt,
15330                           ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz,
15331                           keys, (word32)keysLen);
15332                break;
15333#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
15334            case ecKDF_X963_SHA1 :
15335                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
15336                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
15337                break;
15338            case ecKDF_X963_SHA256 :
15339                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
15340                           ctx->kdfInfo, ctx->kdfInfoSz, keys, (word32)keysLen);
15341                break;
15342            case ecKDF_SHA1 :
15343                ret = wc_X963_KDF(WC_HASH_TYPE_SHA, sharedSecret, sharedSz,
15344                           NULL, 0, keys, (word32)keysLen);
15345                break;
15346            case ecKDF_SHA256 :
15347                ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, sharedSecret, sharedSz,
15348                           NULL, 0, keys, (word32)keysLen);
15349                break;
15350#endif
15351
15352            default:
15353                ret = BAD_FUNC_ARG;
15354                break;
15355         }
15356    }
15357
15358    if (ret == 0) {
15359    #ifdef WOLFSSL_ECIES_OLD
15360        encKey = keys + offset;
15361        encIv  = encKey + encKeySz;
15362        macKey = encKey + encKeySz + ivSz;
15363    #elif defined(WOLFSSL_ECIES_GEN_IV)
15364        encKey = keys + offset;
15365        encIv  = msg;
15366        msg   += ivSz;
15367        msgSz -= ivSz;
15368        macKey = encKey + encKeySz;
15369    #else
15370        XMEMSET(iv, 0, (size_t)ivSz);
15371        encKey = keys + offset;
15372        encIv  = iv;
15373        macKey = encKey + encKeySz;
15374    #endif
15375
15376        switch (ctx->macAlgo) {
15377            case ecHMAC_SHA256:
15378            {
15379                byte verify[WC_SHA256_DIGEST_SIZE];
15380            #ifdef WOLFSSL_SMALL_STACK
15381                Hmac *hmac = (Hmac *)XMALLOC(sizeof *hmac, ctx->heap,
15382                                             DYNAMIC_TYPE_HMAC);
15383                if (hmac == NULL) {
15384                    ret = MEMORY_E;
15385                    break;
15386                }
15387            #else
15388                Hmac hmac[1];
15389            #endif
15390                ret = wc_HmacInit(hmac, NULL, INVALID_DEVID);
15391                if (ret == 0) {
15392                    ret = wc_HmacSetKey(hmac, WC_SHA256, macKey,
15393                                                         WC_SHA256_DIGEST_SIZE);
15394                    if (ret == 0)
15395                    #if !defined(WOLFSSL_ECIES_GEN_IV)
15396                        ret = wc_HmacUpdate(hmac, msg, msgSz-digestSz);
15397                    #else
15398                        /* IV is before encrypted message. */
15399                        ret = wc_HmacUpdate(hmac, encIv, ivSz+msgSz-digestSz);
15400                    #endif
15401                    if (ret == 0)
15402                        ret = wc_HmacUpdate(hmac, ctx->macSalt, ctx->macSaltSz);
15403
15404                    if (ret == 0)
15405                        ret = wc_HmacFinal(hmac, verify);
15406                    if ((ret == 0) && (ConstantCompare(verify, msg + msgSz - digestSz,
15407                                                             (int)digestSz) != 0)) {
15408                        ret = HASH_TYPE_E;
15409                        WOLFSSL_MSG("ECC Decrypt HMAC Check failed!");
15410                    }
15411
15412                    wc_HmacFree(hmac);
15413                }
15414                WC_FREE_VAR_EX(hmac, ctx->heap, DYNAMIC_TYPE_HMAC);
15415                break;
15416            }
15417
15418            default:
15419                ret = BAD_FUNC_ARG;
15420                break;
15421        }
15422    }
15423
15424    if (ret == 0) {
15425        switch (ctx->encAlgo) {
15426        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
15427            case ecAES_128_CBC:
15428            case ecAES_256_CBC:
15429            {
15430            #ifdef WOLFSSL_SMALL_STACK
15431                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
15432                                          DYNAMIC_TYPE_AES);
15433                if (aes == NULL) {
15434                    ret = MEMORY_E;
15435                    break;
15436                }
15437            #else
15438                Aes aes[1];
15439            #endif
15440                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15441                if (ret == 0) {
15442                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, encIv,
15443                                                                AES_DECRYPTION);
15444                    if (ret == 0) {
15445                        ret = wc_AesCbcDecrypt(aes, out, msg, msgSz-digestSz);
15446                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
15447                                                    defined(WC_ASYNC_ENABLE_AES)
15448                        ret = wc_AsyncWait(ret, &aes->asyncDev,
15449                                                            WC_ASYNC_FLAG_NONE);
15450                    #endif
15451                    }
15452                    wc_AesFree(aes);
15453                }
15454                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15455                break;
15456            }
15457        #endif
15458        #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
15459            case ecAES_128_CTR:
15460            case ecAES_256_CTR:
15461            {
15462            #ifdef WOLFSSL_SMALL_STACK
15463                Aes *aes = (Aes *)XMALLOC(sizeof *aes, ctx->heap,
15464                                          DYNAMIC_TYPE_AES);
15465                if (aes == NULL) {
15466                    ret = MEMORY_E;
15467                    break;
15468                }
15469             #else
15470                Aes aes[1];
15471             #endif
15472                ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15473                if (ret == 0) {
15474                    byte ctr_iv[WC_AES_BLOCK_SIZE];
15475                    /* Make a 16 byte IV from the bytes passed in. */
15476                    XMEMCPY(ctr_iv, encIv, WOLFSSL_ECIES_GEN_IV_SIZE);
15477                    XMEMSET(ctr_iv + WOLFSSL_ECIES_GEN_IV_SIZE, 0,
15478                        WC_AES_BLOCK_SIZE - WOLFSSL_ECIES_GEN_IV_SIZE);
15479                    ret = wc_AesSetKey(aes, encKey, (word32)encKeySz, ctr_iv,
15480                                                                AES_ENCRYPTION);
15481                    if (ret == 0) {
15482                        ret = wc_AesCtrEncrypt(aes, out, msg, msgSz-digestSz);
15483                    #if defined(WOLFSSL_ASYNC_CRYPT) && \
15484                                                    defined(WC_ASYNC_ENABLE_AES)
15485                        ret = wc_AsyncWait(ret, &aes->asyncDev,
15486                                                            WC_ASYNC_FLAG_NONE);
15487                    #endif
15488                    }
15489                    wc_AesFree(aes);
15490                }
15491                WC_FREE_VAR_EX(aes, ctx->heap, DYNAMIC_TYPE_AES);
15492                break;
15493            }
15494        #endif
15495            default:
15496                ret = BAD_FUNC_ARG;
15497                break;
15498        }
15499    }
15500
15501    if (ret == 0)
15502       *outSz = msgSz - digestSz;
15503
15504    RESTORE_VECTOR_REGISTERS();
15505
15506#ifndef WOLFSSL_ECIES_OLD
15507    if (pubKey == peerKey)
15508        wc_ecc_free(peerKey);
15509#endif
15510    ForceZero(sharedSecret, sharedSz);
15511    ForceZero(keys, (word32)keysLen);
15512#ifdef WOLFSSL_SMALL_STACK
15513#ifndef WOLFSSL_ECIES_OLD
15514    XFREE(peerKey, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15515#endif
15516    XFREE(sharedSecret, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15517    XFREE(keys, ctx->heap, DYNAMIC_TYPE_ECC_BUFFER);
15518#endif
15519
15520    return ret;
15521}
15522
15523
15524#endif /* HAVE_ECC_ENCRYPT */
15525
15526
15527#ifdef HAVE_COMP_KEY
15528#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
15529    !defined(WOLFSSL_MICROCHIP_TA100) && \
15530    !defined(WOLFSSL_CRYPTOCELL)
15531
15532#ifndef WOLFSSL_SP_MATH
15533#if !defined(SQRTMOD_USE_MOD_EXP)
15534/* computes the jacobi c = (a | n) (or Legendre if n is prime)
15535 */
15536static int mp_jacobi(mp_int* a, mp_int* n, int* c)
15537{
15538#ifdef WOLFSSL_SMALL_STACK
15539    mp_int*  a1 = NULL;
15540    mp_int*  n1 = NULL;
15541#else
15542    mp_int   a1[1], n1[1];
15543#endif
15544    int      res;
15545    int      s = 1;
15546    int      k;
15547    mp_int*  t[2];
15548    mp_int*  ts;
15549    mp_digit residue;
15550
15551    if (mp_isneg(a) == MP_YES) {
15552        return MP_VAL;
15553    }
15554    if (mp_isneg(n) == MP_YES) {
15555        return MP_VAL;
15556    }
15557    if (mp_iseven(n) == MP_YES) {
15558        return MP_VAL;
15559    }
15560
15561#ifdef WOLFSSL_SMALL_STACK
15562    a1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
15563    if (a1 == NULL) {
15564        return MP_MEM;
15565    }
15566    n1 = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
15567    if (n1 == NULL) {
15568        XFREE(a1, NULL, DYNAMIC_TYPE_BIGINT);
15569        return MP_MEM;
15570    }
15571#endif
15572
15573    if ((res = mp_init_multi(a1, n1, NULL, NULL, NULL, NULL)) != MP_OKAY) {
15574        WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
15575        WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
15576        return res;
15577    }
15578
15579    SAVE_VECTOR_REGISTERS(return _svr_ret;);
15580
15581    if ((res = mp_mod(a, n, a1)) != MP_OKAY) {
15582        goto done;
15583    }
15584
15585    if ((res = mp_copy(n, n1)) != MP_OKAY) {
15586        goto done;
15587    }
15588
15589    t[0] = a1;
15590    t[1] = n1;
15591
15592    /* Keep reducing until first number is 0. */
15593    while (!mp_iszero(t[0])) {
15594        /* Divide by 2 until odd. */
15595        k = mp_cnt_lsb(t[0]);
15596        if (k > 0) {
15597            mp_rshb(t[0], k);
15598
15599            /* Negate s each time we divide by 2 if t[1] mod 8 == 3 or 5.
15600             * Odd number of divides results in a negate.
15601             */
15602            residue = t[1]->dp[0] & 7;
15603            if ((k & 1) && ((residue == 3) || (residue == 5))) {
15604                s = -s;
15605            }
15606        }
15607
15608        /* Swap t[0] and t[1]. */
15609        ts   = t[0];
15610        t[0] = t[1];
15611        t[1] = ts;
15612
15613        /* Negate s if both numbers == 3 mod 4. */
15614        if (((t[0]->dp[0] & 3) == 3) && ((t[1]->dp[0] & 3) == 3)) {
15615             s = -s;
15616        }
15617
15618        /* Reduce first number modulo second. */
15619        if ((k == 0) && (mp_count_bits(t[0]) == mp_count_bits(t[1]))) {
15620            res = mp_sub(t[0], t[1], t[0]);
15621        }
15622        else {
15623            res = mp_mod(t[0], t[1], t[0]);
15624        }
15625        if (res != MP_OKAY) {
15626            goto done;
15627        }
15628    }
15629
15630    /* When the two numbers have divisors in common. */
15631    if (!mp_isone(t[1])) {
15632        s = 0;
15633    }
15634    *c = s;
15635
15636done:
15637
15638    RESTORE_VECTOR_REGISTERS();
15639
15640    /* cleanup */
15641    mp_clear(n1);
15642    mp_clear(a1);
15643
15644    WC_FREE_VAR_EX(a1, NULL, DYNAMIC_TYPE_BIGINT);
15645    WC_FREE_VAR_EX(n1, NULL, DYNAMIC_TYPE_BIGINT);
15646
15647  return res;
15648}
15649#endif /* !SQRTMOD_USE_MOD_EXP */
15650
15651
15652/* Solves the modular equation x^2 = n (mod p)
15653 * where prime number is greater than 2 (odd prime).
15654 * The result is returned in the third argument x
15655 * the function returns MP_OKAY on success, MP_VAL or another error on failure
15656 */
15657static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
15658{
15659#if defined(SQRTMOD_USE_MOD_EXP)
15660  int res;
15661  mp_digit i;
15662  mp_int e;
15663
15664  /* first handle the simple cases n = 0 or n = 1 */
15665  if (mp_cmp_d(n, 0) == MP_EQ) {
15666      mp_zero(ret);
15667      return MP_OKAY;
15668  }
15669  if (mp_cmp_d(n, 1) == MP_EQ) {
15670      return mp_set(ret, 1);
15671  }
15672
15673  if (mp_iseven(prime)) {
15674      return MP_VAL;
15675  }
15676
15677  SAVE_VECTOR_REGISTERS(return _svr_ret;);
15678
15679  res = mp_init(&e);
15680  if (res == MP_OKAY)
15681      res = mp_mod_d(prime, 8, &i);
15682  if (res == MP_OKAY && i == 1) {
15683      return MP_VAL;
15684  }
15685  /* prime mod 8 = 5 */
15686  else if (res == MP_OKAY && i == 5) {
15687      res = mp_sub_d(prime, 1, &e);
15688      if (res == MP_OKAY)
15689          res = mp_div_2d(&e, 2, &e, NULL);
15690  }
15691  /* prime mod 4 = 3 */
15692  else if (res == MP_OKAY && ((i == 3) || (i == 7))) {
15693      res = mp_add_d(prime, 1, &e);
15694      if (res == MP_OKAY)
15695          res = mp_div_2d(&e, 2, &e, NULL);
15696  }
15697  if (res == MP_OKAY)
15698      res = mp_exptmod(n, &e, prime, ret);
15699
15700  mp_clear(&e);
15701
15702  RESTORE_VECTOR_REGISTERS();
15703
15704  return res;
15705#else
15706  int res, legendre, done = 0;
15707  mp_digit i;
15708#ifdef WOLFSSL_SMALL_STACK
15709  mp_int *t1 = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15710  mp_int *C = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15711  mp_int *Q = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15712  mp_int *S = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15713  mp_int *Z = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15714  mp_int *M = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15715  mp_int *T = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15716  mp_int *R = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15717  mp_int *N = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15718  mp_int *two = (mp_int *)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC_BUFFER);
15719#else
15720  mp_int t1[1], C[1], Q[1], S[1], Z[1], M[1], T[1], R[1], N[1], two[1];
15721#endif
15722
15723  SAVE_VECTOR_REGISTERS(res = _svr_ret; goto out;);
15724
15725  if ((mp_init_multi(t1, C, Q, S, Z, M) != MP_OKAY) ||
15726      (mp_init_multi(T, R, N, two, NULL, NULL) != MP_OKAY)) {
15727    res = MP_INIT_E;
15728    goto out;
15729  }
15730
15731#ifdef WOLFSSL_SMALL_STACK
15732  if ((t1 == NULL) ||
15733      (C == NULL) ||
15734      (Q == NULL) ||
15735      (S == NULL) ||
15736      (Z == NULL) ||
15737      (M == NULL) ||
15738      (T == NULL) ||
15739      (R == NULL) ||
15740      (N == NULL) ||
15741      (two == NULL)) {
15742    res = MP_MEM;
15743    goto out;
15744  }
15745#endif
15746
15747  /* first handle the simple cases n = 0 or n = 1 */
15748  if (mp_cmp_d(n, 0) == MP_EQ) {
15749    mp_zero(ret);
15750    res = MP_OKAY;
15751    goto out;
15752  }
15753  if (mp_cmp_d(n, 1) == MP_EQ) {
15754    res = mp_set(ret, 1);
15755    goto out;
15756  }
15757
15758  /* prime must be odd */
15759  if (mp_cmp_d(prime, 2) == MP_EQ) {
15760    res = MP_VAL;
15761    goto out;
15762  }
15763
15764  /* reduce n to less than prime */
15765  res = mp_mod(n, prime, N);
15766  if (res != MP_OKAY) {
15767    goto out;
15768  }
15769  /* when N is zero, sqrt is zero */
15770  if (mp_iszero(N)) {
15771    mp_set(ret, 0);
15772    goto out;
15773  }
15774
15775  /* is quadratic non-residue mod prime */
15776  if ((res = mp_jacobi(N, prime, &legendre)) != MP_OKAY) {
15777    goto out;
15778  }
15779  if (legendre == -1) {
15780    res = MP_VAL;
15781    goto out;
15782  }
15783
15784  /* SPECIAL CASE: if prime mod 4 == 3
15785   * compute directly: res = n^(prime+1)/4 mod prime
15786   * Handbook of Applied Cryptography algorithm 3.36
15787   */
15788  res = mp_mod_d(prime, 4, &i);
15789  if (res == MP_OKAY && i == 3) {
15790    res = mp_add_d(prime, 1, t1);
15791
15792    if (res == MP_OKAY)
15793      res = mp_div_2(t1, t1);
15794    if (res == MP_OKAY)
15795      res = mp_div_2(t1, t1);
15796    if (res == MP_OKAY)
15797      res = mp_exptmod(N, t1, prime, ret);
15798
15799    done = 1;
15800  }
15801
15802  /* NOW: TonelliShanks algorithm */
15803  if (res == MP_OKAY && done == 0) {
15804
15805    /* factor out powers of 2 from prime-1, defining Q and S
15806    *                                      as: prime-1 = Q*2^S */
15807    /* Q = prime - 1 */
15808    res = mp_copy(prime, Q);
15809    if (res == MP_OKAY)
15810      res = mp_sub_d(Q, 1, Q);
15811
15812    /* S = 0 */
15813    if (res == MP_OKAY)
15814      mp_zero(S);
15815
15816    while (res == MP_OKAY && mp_iseven(Q) == MP_YES) {
15817      /* Q = Q / 2 */
15818      res = mp_div_2(Q, Q);
15819
15820      /* S = S + 1 */
15821      if (res == MP_OKAY)
15822        res = mp_add_d(S, 1, S);
15823    }
15824
15825    /* find a Z such that the Legendre symbol (Z|prime) == -1 */
15826    /* Z = 2 */
15827    if (res == MP_OKAY)
15828      res = mp_set_int(Z, 2);
15829
15830    while (res == MP_OKAY) {
15831      res = mp_jacobi(Z, prime, &legendre);
15832      if (res == MP_OKAY && legendre == -1)
15833        break;
15834
15835#if defined(WOLFSSL_CUSTOM_CURVES)
15836      /* P224R1 succeeds with a value of 11. */
15837      if (mp_cmp_d(Z, 22) == MP_EQ) {
15838        /* This is to clamp the loop in case 'prime' is not really prime */
15839        res = MP_VAL;
15840        break;
15841      }
15842#endif
15843
15844      /* Z = Z + 1 */
15845      if (res == MP_OKAY)
15846        res = mp_add_d(Z, 1, Z);
15847
15848      if ((res == MP_OKAY) && (mp_cmp(Z,prime) == MP_EQ)) {
15849        /* This is to clamp the loop in case 'prime' is not really prime */
15850        res = MP_VAL;
15851        break;
15852      }
15853    }
15854
15855    /* C = Z ^ Q mod prime */
15856    if (res == MP_OKAY)
15857      res = mp_exptmod(Z, Q, prime, C);
15858
15859    /* t1 = (Q + 1) / 2 */
15860    if (res == MP_OKAY)
15861      res = mp_add_d(Q, 1, t1);
15862    if (res == MP_OKAY)
15863      res = mp_div_2(t1, t1);
15864
15865    /* R = n ^ ((Q + 1) / 2) mod prime */
15866    if (res == MP_OKAY)
15867      res = mp_exptmod(N, t1, prime, R);
15868
15869    /* T = n ^ Q mod prime */
15870    if (res == MP_OKAY)
15871      res = mp_exptmod(N, Q, prime, T);
15872
15873    /* M = S */
15874    if (res == MP_OKAY)
15875      res = mp_copy(S, M);
15876
15877    if (res == MP_OKAY)
15878      res = mp_set_int(two, 2);
15879
15880    while (res == MP_OKAY && done == 0) {
15881      res = mp_copy(T, t1);
15882
15883      /* reduce to 1 and count */
15884      i = 0;
15885      while (res == MP_OKAY) {
15886        if (mp_cmp_d(t1, 1) == MP_EQ)
15887            break;
15888        res = mp_exptmod(t1, two, prime, t1);
15889        if ((res == MP_OKAY) && (mp_cmp_d(M,i) == MP_EQ)) {
15890          /* This is to clamp the loop in case 'prime' is not really prime */
15891          res = MP_VAL;
15892          break;
15893        }
15894        if (res == MP_OKAY)
15895          i++;
15896      }
15897      if (res == MP_OKAY && i == 0) {
15898        res = mp_copy(R, ret);
15899        done = 1;
15900      }
15901
15902      if (done == 0) {
15903        /* t1 = 2 ^ (M - i - 1) */
15904        if (res == MP_OKAY)
15905          res = mp_sub_d(M, i, t1);
15906        if (res == MP_OKAY)
15907          res = mp_sub_d(t1, 1, t1);
15908        if (res == MP_OKAY)
15909          res = mp_exptmod(two, t1, prime, t1);
15910
15911        /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
15912        if (res == MP_OKAY)
15913          res = mp_exptmod(C, t1, prime, t1);
15914
15915        /* C = (t1 * t1) mod prime */
15916        if (res == MP_OKAY)
15917          res = mp_sqrmod(t1, prime, C);
15918
15919        /* R = (R * t1) mod prime */
15920        if (res == MP_OKAY)
15921          res = mp_mulmod(R, t1, prime, R);
15922
15923        /* T = (T * C) mod prime */
15924        if (res == MP_OKAY)
15925          res = mp_mulmod(T, C, prime, T);
15926
15927        /* M = i */
15928        if (res == MP_OKAY)
15929          res = mp_set(M, i);
15930      }
15931    }
15932  }
15933
15934  out:
15935
15936  RESTORE_VECTOR_REGISTERS();
15937
15938#ifdef WOLFSSL_SMALL_STACK
15939  if (t1) {
15940    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15941      mp_clear(t1);
15942    XFREE(t1, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15943  }
15944  if (C) {
15945    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15946      mp_clear(C);
15947    XFREE(C, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15948  }
15949  if (Q) {
15950    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15951      mp_clear(Q);
15952    XFREE(Q, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15953  }
15954  if (S) {
15955    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15956      mp_clear(S);
15957    XFREE(S, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15958  }
15959  if (Z) {
15960    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15961      mp_clear(Z);
15962    XFREE(Z, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15963  }
15964  if (M) {
15965    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15966      mp_clear(M);
15967    XFREE(M, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15968  }
15969  if (T) {
15970    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15971      mp_clear(T);
15972    XFREE(T, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15973  }
15974  if (R) {
15975    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15976      mp_clear(R);
15977    XFREE(R, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15978  }
15979  if (N) {
15980    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15981      mp_clear(N);
15982    XFREE(N, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15983  }
15984  if (two) {
15985    if (res != WC_NO_ERR_TRACE(MP_INIT_E))
15986      mp_clear(two);
15987    XFREE(two, NULL, DYNAMIC_TYPE_ECC_BUFFER);
15988  }
15989#else
15990  if (res != WC_NO_ERR_TRACE(MP_INIT_E)) {
15991    mp_clear(t1);
15992    mp_clear(C);
15993    mp_clear(Q);
15994    mp_clear(S);
15995    mp_clear(Z);
15996    mp_clear(M);
15997    mp_clear(T);
15998    mp_clear(R);
15999    mp_clear(N);
16000    mp_clear(two);
16001  }
16002#endif
16003
16004  return res;
16005#endif
16006}
16007#endif /* !WOLFSSL_SP_MATH */
16008#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && !WOLFSSL_CRYPTOCELL */
16009
16010#ifdef HAVE_ECC_KEY_EXPORT
16011/* export public ECC key in ANSI X9.63 format compressed */
16012static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
16013{
16014   word32 numlen;
16015   int    ret = MP_OKAY;
16016
16017   if (key == NULL || outLen == NULL)
16018       return BAD_FUNC_ARG;
16019
16020   if (key->type == ECC_PRIVATEKEY_ONLY)
16021       return ECC_PRIVATEONLY_E;
16022
16023   if (key->type == 0 || wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL){
16024       return ECC_BAD_ARG_E;
16025   }
16026
16027   numlen = (word32)key->dp->size;
16028
16029   if (*outLen < (1 + numlen)) {
16030      *outLen = 1 + numlen;
16031      return WC_NO_ERR_TRACE(LENGTH_ONLY_E);
16032   }
16033
16034   if (out == NULL)
16035       return BAD_FUNC_ARG;
16036
16037   if (mp_unsigned_bin_size(key->pubkey.x) > (int)numlen)
16038       return ECC_BAD_ARG_E;
16039
16040   /* store first byte */
16041   out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
16042
16043   /* pad and store x */
16044   XMEMSET(out+1, 0, numlen);
16045   ret = mp_to_unsigned_bin(
16046       key->pubkey.x,
16047       out+1 + (numlen - (word32)mp_unsigned_bin_size(key->pubkey.x)));
16048   *outLen = 1 + numlen;
16049
16050   return ret;
16051}
16052#endif /* HAVE_ECC_KEY_EXPORT */
16053#endif /* HAVE_COMP_KEY */
16054
16055#ifdef HAVE_OID_ENCODING
16056int wc_ecc_oid_cache_init(void)
16057{
16058    int ret = 0;
16059#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
16060    ret = wc_InitMutex(&ecc_oid_cache_lock);
16061#endif
16062    return ret;
16063}
16064
16065void wc_ecc_oid_cache_free(void)
16066{
16067#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_MUTEX_INITIALIZER)
16068    wc_FreeMutex(&ecc_oid_cache_lock);
16069#endif
16070}
16071#endif /* HAVE_OID_ENCODING */
16072
16073int wc_ecc_get_oid(word32 oidSum, const byte** oid, word32* oidSz)
16074{
16075    int x;
16076    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
16077#ifdef HAVE_OID_ENCODING
16078    oid_cache_t* o = NULL;
16079#endif
16080
16081    if (oidSum == 0) {
16082        return BAD_FUNC_ARG;
16083    }
16084
16085#ifdef HAVE_OID_ENCODING
16086    #ifndef WOLFSSL_MUTEX_INITIALIZER
16087        /* extra sanity check if wolfCrypt_Init not called */
16088        if (eccOidLockInit == 0) {
16089            wc_InitMutex(&ecc_oid_cache_lock);
16090            eccOidLockInit = 1;
16091        }
16092    #endif
16093
16094    if (wc_LockMutex(&ecc_oid_cache_lock) != 0) {
16095        return BAD_MUTEX_E;
16096    }
16097#endif
16098
16099    /* find matching OID sum (based on encoded value) */
16100    for (x = 0; ecc_sets[x].size != 0; x++) {
16101        if (ecc_sets[x].oidSum == oidSum) {
16102        #ifdef HAVE_OID_ENCODING
16103            /* check cache */
16104            ret = 0;
16105            o = &ecc_oid_cache[x];
16106            if (o->oidSz == 0) {
16107                o->oidSz = sizeof(o->oid);
16108                ret = EncodeObjectId(ecc_sets[x].oid, ecc_sets[x].oidSz,
16109                                                            o->oid, &o->oidSz);
16110            }
16111            if (oidSz) {
16112                *oidSz = o->oidSz;
16113            }
16114            if (oid) {
16115                *oid = o->oid;
16116            }
16117
16118            /* on success return curve id */
16119            if (ret == 0) {
16120                ret = ecc_sets[x].id;
16121            }
16122            break;
16123        #else
16124            if (oidSz) {
16125                *oidSz = ecc_sets[x].oidSz;
16126            }
16127            if (oid) {
16128                *oid = ecc_sets[x].oid;
16129            }
16130            ret = ecc_sets[x].id;
16131            break;
16132        #endif
16133        }
16134    }
16135
16136#ifdef HAVE_OID_ENCODING
16137    wc_UnLockMutex(&ecc_oid_cache_lock);
16138#endif
16139
16140    return ret;
16141}
16142
16143#ifdef WOLFSSL_CUSTOM_CURVES
16144int wc_ecc_set_custom_curve(ecc_key* key, const ecc_set_type* dp)
16145{
16146    if (key == NULL || dp == NULL) {
16147        return BAD_FUNC_ARG;
16148    }
16149
16150    key->idx = ECC_CUSTOM_IDX;
16151    key->dp = dp;
16152
16153    return 0;
16154}
16155#endif /* WOLFSSL_CUSTOM_CURVES */
16156
16157#if defined(HAVE_X963_KDF) && !defined(NO_HASH_WRAPPER)
16158
16159static WC_INLINE void IncrementX963KdfCounter(byte* inOutCtr)
16160{
16161    int i;
16162
16163    /* in network byte order so start at end and work back */
16164    for (i = 3; i >= 0; i--) {
16165        if (++inOutCtr[i])  /* we're done unless we overflow */
16166            return;
16167    }
16168}
16169
16170/* ASN X9.63 Key Derivation Function (SEC1) */
16171int wc_X963_KDF(enum wc_HashType type, const byte* secret, word32 secretSz,
16172                const byte* sinfo, word32 sinfoSz, byte* out, word32 outSz)
16173{
16174    int ret;
16175    word32 digestSz, copySz, remaining = outSz;
16176    byte* outIdx;
16177    byte  counter[4];
16178    byte  tmp[WC_MAX_DIGEST_SIZE];
16179
16180    WC_DECLARE_VAR(hash, wc_HashAlg, 1, 0);
16181
16182    if (secret == NULL || secretSz == 0 || out == NULL)
16183        return BAD_FUNC_ARG;
16184
16185    /* X9.63 allowed algos only */
16186    if (type != WC_HASH_TYPE_SHA    && type != WC_HASH_TYPE_SHA224 &&
16187        type != WC_HASH_TYPE_SHA256 && type != WC_HASH_TYPE_SHA384 &&
16188        type != WC_HASH_TYPE_SHA512)
16189        return BAD_FUNC_ARG;
16190
16191    ret = wc_HashGetDigestSize(type);
16192    if (ret < 0)
16193        return ret;
16194    digestSz = (word32)ret;
16195
16196    WC_ALLOC_VAR_EX(hash, wc_HashAlg, 1, NULL, DYNAMIC_TYPE_HASHES,
16197        return MEMORY_E);
16198
16199    ret = wc_HashInit(hash, type);
16200    if (ret != 0) {
16201        WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
16202        return ret;
16203    }
16204
16205    outIdx = out;
16206    XMEMSET(counter, 0, sizeof(counter));
16207
16208    while (remaining > 0) {
16209
16210        IncrementX963KdfCounter(counter);
16211
16212        ret = wc_HashUpdate(hash, type, secret, secretSz);
16213        if (ret != 0) {
16214            break;
16215        }
16216
16217        ret = wc_HashUpdate(hash, type, counter, sizeof(counter));
16218        if (ret != 0) {
16219            break;
16220        }
16221
16222        if (sinfo) {
16223            ret = wc_HashUpdate(hash, type, sinfo, sinfoSz);
16224            if (ret != 0) {
16225                break;
16226            }
16227        }
16228
16229        ret = wc_HashFinal(hash, type, tmp);
16230        if (ret != 0) {
16231            break;
16232        }
16233
16234        copySz = min(remaining, digestSz);
16235        XMEMCPY(outIdx, tmp, copySz);
16236
16237        remaining -= copySz;
16238        outIdx += copySz;
16239    }
16240
16241    wc_HashFree(hash, type);
16242
16243     WC_FREE_VAR_EX(hash, NULL, DYNAMIC_TYPE_HASHES);
16244
16245    return ret;
16246}
16247#endif /* HAVE_X963_KDF && !NO_HASH_WRAPPER */
16248
16249#ifdef WOLFSSL_SE050
16250/* Use specified hardware key ID with ecc_key operations. Unlike devId,
16251 * keyId is a word32, can be used for key IDs larger than an int.
16252 *
16253 * key    initialized ecc_key struct
16254 * keyId  hardware key ID which stores ECC key
16255 * flags  optional flags, currently unused
16256 *
16257 * Return 0 on success, negative on error */
16258int wc_ecc_use_key_id(ecc_key* key, word32 keyId, word32 flags)
16259{
16260    (void)flags;
16261
16262    if (key == NULL) {
16263        return BAD_FUNC_ARG;
16264    }
16265
16266    return se050_ecc_use_key_id(key, keyId);
16267}
16268
16269/* Get hardware key ID associated with this ecc_key structure.
16270 *
16271 * key    initialized ecc_key struct
16272 * keyId  [OUT] output for key ID associated with this structure
16273 *
16274 * Returns 0 on success, negative on error.
16275 */
16276int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
16277{
16278    if (key == NULL || keyId == NULL) {
16279        return BAD_FUNC_ARG;
16280    }
16281
16282    return se050_ecc_get_key_id(key, keyId);
16283}
16284#endif /* WOLFSSL_SE050 */
16285
16286
16287#ifdef WC_ECC_NONBLOCK
16288/* Enable ECC support for non-blocking operations */
16289int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
16290{
16291    if (key == NULL) {
16292        return BAD_FUNC_ARG;
16293    }
16294    /* If a different context is already set, clear it before replacing.
16295     * The caller is responsible for freeing any heap-allocated context. */
16296    if (key->nb_ctx != NULL && key->nb_ctx != ctx) {
16297        XMEMSET(key->nb_ctx, 0, sizeof(ecc_nb_ctx_t));
16298    }
16299    if (ctx != NULL) {
16300        XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
16301    }
16302    key->nb_ctx = ctx;
16303    return 0;
16304}
16305#endif /* WC_ECC_NONBLOCK */
16306
16307#endif /* HAVE_ECC */