cjson
fuzzing
inputs
test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9library_config
cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmaketests
inputs
test1 test1.expected test10 test10.expected test11 test11.expected test2 test2.expected test3 test3.expected test4 test4.expected test5 test5.expected test6 test7 test7.expected test8 test8.expected test9 test9.expectedjson-patch-tests
.editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.jsonunity
auto
colour_prompt.rb colour_reporter.rb generate_config.yml generate_module.rb generate_test_runner.rb parse_output.rb stylize_as_junit.rb test_file_filter.rb type_sanitizer.rb unity_test_summary.py unity_test_summary.rb unity_to_junit.pydocs
ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txtexamples
unity_config.hcurl
.github
scripts
cleancmd.pl cmp-config.pl cmp-pkg-config.sh codespell-ignore.words codespell.sh distfiles.sh pyspelling.words pyspelling.yaml randcurl.pl requirements-docs.txt requirements-proselint.txt requirements.txt shellcheck-ci.sh shellcheck.sh spellcheck.curl trimmarkdownheader.pl typos.sh typos.toml verify-examples.pl verify-synopsis.pl yamlcheck.sh yamlcheck.yamlworkflows
appveyor-status.yml checkdocs.yml checksrc.yml checkurls.yml codeql.yml configure-vs-cmake.yml curl-for-win.yml distcheck.yml fuzz.yml http3-linux.yml label.yml linux-old.yml linux.yml macos.yml non-native.yml windows.ymlCMake
CurlSymbolHiding.cmake CurlTests.c FindBrotli.cmake FindCares.cmake FindGSS.cmake FindGnuTLS.cmake FindLDAP.cmake FindLibbacktrace.cmake FindLibgsasl.cmake FindLibidn2.cmake FindLibpsl.cmake FindLibssh.cmake FindLibssh2.cmake FindLibuv.cmake FindMbedTLS.cmake FindNGHTTP2.cmake FindNGHTTP3.cmake FindNGTCP2.cmake FindNettle.cmake FindQuiche.cmake FindRustls.cmake FindWolfSSL.cmake FindZstd.cmake Macros.cmake OtherTests.cmake PickyWarnings.cmake Utilities.cmake cmake_uninstall.in.cmake curl-config.in.cmake unix-cache.cmake win32-cache.cmakedocs
cmdline-opts
.gitignore CMakeLists.txt MANPAGE.md Makefile.am Makefile.inc _AUTHORS.md _BUGS.md _DESCRIPTION.md _ENVIRONMENT.md _EXITCODES.md _FILES.md _GLOBBING.md _NAME.md _OPTIONS.md _OUTPUT.md _PROGRESS.md _PROTOCOLS.md _PROXYPREFIX.md _SEEALSO.md _SYNOPSIS.md _URL.md _VARIABLES.md _VERSION.md _WWW.md abstract-unix-socket.md alt-svc.md anyauth.md append.md aws-sigv4.md basic.md ca-native.md cacert.md capath.md cert-status.md cert-type.md cert.md ciphers.md compressed-ssh.md compressed.md config.md connect-timeout.md connect-to.md continue-at.md cookie-jar.md cookie.md create-dirs.md create-file-mode.md crlf.md crlfile.md curves.md data-ascii.md data-binary.md data-raw.md data-urlencode.md data.md delegation.md digest.md disable-eprt.md disable-epsv.md disable.md disallow-username-in-url.md dns-interface.md dns-ipv4-addr.md dns-ipv6-addr.md dns-servers.md doh-cert-status.md doh-insecure.md doh-url.md dump-ca-embed.md dump-header.md ech.md egd-file.md engine.md etag-compare.md etag-save.md expect100-timeout.md fail-early.md fail-with-body.md fail.md false-start.md follow.md form-escape.md form-string.md form.md ftp-account.md ftp-alternative-to-user.md ftp-create-dirs.md ftp-method.md ftp-pasv.md ftp-port.md ftp-pret.md ftp-skip-pasv-ip.md ftp-ssl-ccc-mode.md ftp-ssl-ccc.md ftp-ssl-control.md get.md globoff.md happy-eyeballs-timeout-ms.md haproxy-clientip.md haproxy-protocol.md head.md header.md help.md hostpubmd5.md hostpubsha256.md hsts.md http0.9.md http1.0.md http1.1.md http2-prior-knowledge.md http2.md http3-only.md http3.md ignore-content-length.md insecure.md interface.md ip-tos.md ipfs-gateway.md ipv4.md ipv6.md json.md junk-session-cookies.md keepalive-cnt.md keepalive-time.md key-type.md key.md knownhosts.md krb.md libcurl.md limit-rate.md list-only.md local-port.md location-trusted.md location.md login-options.md mail-auth.md mail-from.md mail-rcpt-allowfails.md mail-rcpt.md mainpage.idx manual.md max-filesize.md max-redirs.md max-time.md metalink.md mptcp.md negotiate.md netrc-file.md netrc-optional.md netrc.md next.md no-alpn.md no-buffer.md no-clobber.md no-keepalive.md no-npn.md no-progress-meter.md no-sessionid.md noproxy.md ntlm-wb.md ntlm.md oauth2-bearer.md out-null.md output-dir.md output.md parallel-immediate.md parallel-max-host.md parallel-max.md parallel.md pass.md path-as-is.md pinnedpubkey.md post301.md post302.md post303.md preproxy.md progress-bar.md proto-default.md proto-redir.md proto.md proxy-anyauth.md proxy-basic.md proxy-ca-native.md proxy-cacert.md proxy-capath.md proxy-cert-type.md proxy-cert.md proxy-ciphers.md proxy-crlfile.md proxy-digest.md proxy-header.md proxy-http2.md proxy-insecure.md proxy-key-type.md proxy-key.md proxy-negotiate.md proxy-ntlm.md proxy-pass.md proxy-pinnedpubkey.md proxy-service-name.md proxy-ssl-allow-beast.md proxy-ssl-auto-client-cert.md proxy-tls13-ciphers.md proxy-tlsauthtype.md proxy-tlspassword.md proxy-tlsuser.md proxy-tlsv1.md proxy-user.md proxy.md proxy1.0.md proxytunnel.md pubkey.md quote.md random-file.md range.md rate.md raw.md referer.md remote-header-name.md remote-name-all.md remote-name.md remote-time.md remove-on-error.md request-target.md request.md resolve.md retry-all-errors.md retry-connrefused.md retry-delay.md retry-max-time.md retry.md sasl-authzid.md sasl-ir.md service-name.md show-error.md show-headers.md sigalgs.md silent.md skip-existing.md socks4.md socks4a.md socks5-basic.md socks5-gssapi-nec.md socks5-gssapi-service.md socks5-gssapi.md socks5-hostname.md socks5.md speed-limit.md speed-time.md ssl-allow-beast.md ssl-auto-client-cert.md ssl-no-revoke.md ssl-reqd.md ssl-revoke-best-effort.md ssl-sessions.md ssl.md sslv2.md sslv3.md stderr.md styled-output.md suppress-connect-headers.md tcp-fastopen.md tcp-nodelay.md telnet-option.md tftp-blksize.md tftp-no-options.md time-cond.md tls-earlydata.md tls-max.md tls13-ciphers.md tlsauthtype.md tlspassword.md tlsuser.md tlsv1.0.md tlsv1.1.md tlsv1.2.md tlsv1.3.md tlsv1.md tr-encoding.md trace-ascii.md trace-config.md trace-ids.md trace-time.md trace.md unix-socket.md upload-file.md upload-flags.md url-query.md url.md use-ascii.md user-agent.md user.md variable.md verbose.md version.md vlan-priority.md write-out.md xattr.mdexamples
.checksrc .gitignore 10-at-a-time.c CMakeLists.txt Makefile.am Makefile.example Makefile.inc README.md adddocsref.pl address-scope.c altsvc.c anyauthput.c block_ip.c cacertinmem.c certinfo.c chkspeed.c connect-to.c cookie_interface.c crawler.c debug.c default-scheme.c ephiperfifo.c evhiperfifo.c externalsocket.c fileupload.c ftp-delete.c ftp-wildcard.c ftpget.c ftpgetinfo.c ftpgetresp.c ftpsget.c ftpupload.c ftpuploadfrommem.c ftpuploadresume.c getinfo.c getinmemory.c getredirect.c getreferrer.c ghiper.c headerapi.c hiperfifo.c hsts-preload.c htmltidy.c htmltitle.cpp http-options.c http-post.c http2-download.c http2-pushinmemory.c http2-serverpush.c http2-upload.c http3-present.c http3.c httpcustomheader.c httpput-postfields.c httpput.c https.c imap-append.c imap-authzid.c imap-copy.c imap-create.c imap-delete.c imap-examine.c imap-fetch.c imap-list.c imap-lsub.c imap-multi.c imap-noop.c imap-search.c imap-ssl.c imap-store.c imap-tls.c interface.c ipv6.c keepalive.c localport.c log_failed_transfers.c maxconnects.c multi-app.c multi-debugcallback.c multi-double.c multi-event.c multi-formadd.c multi-legacy.c multi-post.c multi-single.c multi-uv.c netrc.c parseurl.c persistent.c pop3-authzid.c pop3-dele.c pop3-list.c pop3-multi.c pop3-noop.c pop3-retr.c pop3-ssl.c pop3-stat.c pop3-tls.c pop3-top.c pop3-uidl.c post-callback.c postinmemory.c postit2-formadd.c postit2.c progressfunc.c protofeats.c range.c resolve.c rtsp-options.c sendrecv.c sepheaders.c sessioninfo.c sftpget.c sftpuploadresume.c shared-connection-cache.c simple.c simplepost.c simplessl.c smooth-gtk-thread.c smtp-authzid.c smtp-expn.c smtp-mail.c smtp-mime.c smtp-multi.c smtp-ssl.c smtp-tls.c smtp-vrfy.c sslbackend.c synctime.c threaded.c unixsocket.c url2file.c urlapi.c usercertinmem.c version-check.pl websocket-cb.c websocket-updown.c websocket.c xmlstream.cinternals
BUFQ.md BUFREF.md CHECKSRC.md CLIENT-READERS.md CLIENT-WRITERS.md CODE_STYLE.md CONNECTION-FILTERS.md CREDENTIALS.md CURLX.md DYNBUF.md HASH.md LLIST.md MID.md MQTT.md MULTI-EV.md NEW-PROTOCOL.md PEERS.md PORTING.md RATELIMITS.md README.md SCORECARD.md SPLAY.md STRPARSE.md THRDPOOL-AND-QUEUE.md TIME-KEEPING.md TLS-SESSIONS.md UINT_SETS.md WEBSOCKET.mdlibcurl
opts
CMakeLists.txt CURLINFO_ACTIVESOCKET.md CURLINFO_APPCONNECT_TIME.md CURLINFO_APPCONNECT_TIME_T.md CURLINFO_CAINFO.md CURLINFO_CAPATH.md CURLINFO_CERTINFO.md CURLINFO_CONDITION_UNMET.md CURLINFO_CONNECT_TIME.md CURLINFO_CONNECT_TIME_T.md CURLINFO_CONN_ID.md CURLINFO_CONTENT_LENGTH_DOWNLOAD.md CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md CURLINFO_CONTENT_LENGTH_UPLOAD.md CURLINFO_CONTENT_LENGTH_UPLOAD_T.md CURLINFO_CONTENT_TYPE.md CURLINFO_COOKIELIST.md CURLINFO_EARLYDATA_SENT_T.md CURLINFO_EFFECTIVE_METHOD.md CURLINFO_EFFECTIVE_URL.md CURLINFO_FILETIME.md CURLINFO_FILETIME_T.md CURLINFO_FTP_ENTRY_PATH.md CURLINFO_HEADER_SIZE.md CURLINFO_HTTPAUTH_AVAIL.md CURLINFO_HTTPAUTH_USED.md CURLINFO_HTTP_CONNECTCODE.md CURLINFO_HTTP_VERSION.md CURLINFO_LASTSOCKET.md CURLINFO_LOCAL_IP.md CURLINFO_LOCAL_PORT.md CURLINFO_NAMELOOKUP_TIME.md CURLINFO_NAMELOOKUP_TIME_T.md CURLINFO_NUM_CONNECTS.md CURLINFO_OS_ERRNO.md CURLINFO_POSTTRANSFER_TIME_T.md CURLINFO_PRETRANSFER_TIME.md CURLINFO_PRETRANSFER_TIME_T.md CURLINFO_PRIMARY_IP.md CURLINFO_PRIMARY_PORT.md CURLINFO_PRIVATE.md CURLINFO_PROTOCOL.md CURLINFO_PROXYAUTH_AVAIL.md CURLINFO_PROXYAUTH_USED.md CURLINFO_PROXY_ERROR.md CURLINFO_PROXY_SSL_VERIFYRESULT.md CURLINFO_QUEUE_TIME_T.md CURLINFO_REDIRECT_COUNT.md CURLINFO_REDIRECT_TIME.md CURLINFO_REDIRECT_TIME_T.md CURLINFO_REDIRECT_URL.md CURLINFO_REFERER.md CURLINFO_REQUEST_SIZE.md CURLINFO_RESPONSE_CODE.md CURLINFO_RETRY_AFTER.md CURLINFO_RTSP_CLIENT_CSEQ.md CURLINFO_RTSP_CSEQ_RECV.md CURLINFO_RTSP_SERVER_CSEQ.md CURLINFO_RTSP_SESSION_ID.md CURLINFO_SCHEME.md CURLINFO_SIZE_DELIVERED.md CURLINFO_SIZE_DOWNLOAD.md CURLINFO_SIZE_DOWNLOAD_T.md CURLINFO_SIZE_UPLOAD.md CURLINFO_SIZE_UPLOAD_T.md CURLINFO_SPEED_DOWNLOAD.md CURLINFO_SPEED_DOWNLOAD_T.md CURLINFO_SPEED_UPLOAD.md CURLINFO_SPEED_UPLOAD_T.md CURLINFO_SSL_ENGINES.md CURLINFO_SSL_VERIFYRESULT.md CURLINFO_STARTTRANSFER_TIME.md CURLINFO_STARTTRANSFER_TIME_T.md CURLINFO_TLS_SESSION.md CURLINFO_TLS_SSL_PTR.md CURLINFO_TOTAL_TIME.md CURLINFO_TOTAL_TIME_T.md CURLINFO_USED_PROXY.md CURLINFO_XFER_ID.md CURLMINFO_XFERS_ADDED.md CURLMINFO_XFERS_CURRENT.md CURLMINFO_XFERS_DONE.md CURLMINFO_XFERS_PENDING.md CURLMINFO_XFERS_RUNNING.md CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.md CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.md CURLMOPT_MAXCONNECTS.md CURLMOPT_MAX_CONCURRENT_STREAMS.md CURLMOPT_MAX_HOST_CONNECTIONS.md CURLMOPT_MAX_PIPELINE_LENGTH.md CURLMOPT_MAX_TOTAL_CONNECTIONS.md CURLMOPT_NETWORK_CHANGED.md CURLMOPT_NOTIFYDATA.md CURLMOPT_NOTIFYFUNCTION.md CURLMOPT_PIPELINING.md CURLMOPT_PIPELINING_SERVER_BL.md CURLMOPT_PIPELINING_SITE_BL.md CURLMOPT_PUSHDATA.md CURLMOPT_PUSHFUNCTION.md CURLMOPT_QUICK_EXIT.md CURLMOPT_RESOLVE_THREADS_MAX.md CURLMOPT_SOCKETDATA.md CURLMOPT_SOCKETFUNCTION.md CURLMOPT_TIMERDATA.md CURLMOPT_TIMERFUNCTION.md CURLOPT_ABSTRACT_UNIX_SOCKET.md CURLOPT_ACCEPTTIMEOUT_MS.md CURLOPT_ACCEPT_ENCODING.md CURLOPT_ADDRESS_SCOPE.md CURLOPT_ALTSVC.md CURLOPT_ALTSVC_CTRL.md CURLOPT_APPEND.md CURLOPT_AUTOREFERER.md CURLOPT_AWS_SIGV4.md CURLOPT_BUFFERSIZE.md CURLOPT_CAINFO.md CURLOPT_CAINFO_BLOB.md CURLOPT_CAPATH.md CURLOPT_CA_CACHE_TIMEOUT.md CURLOPT_CERTINFO.md CURLOPT_CHUNK_BGN_FUNCTION.md CURLOPT_CHUNK_DATA.md CURLOPT_CHUNK_END_FUNCTION.md CURLOPT_CLOSESOCKETDATA.md CURLOPT_CLOSESOCKETFUNCTION.md CURLOPT_CONNECTTIMEOUT.md CURLOPT_CONNECTTIMEOUT_MS.md CURLOPT_CONNECT_ONLY.md CURLOPT_CONNECT_TO.md CURLOPT_CONV_FROM_NETWORK_FUNCTION.md CURLOPT_CONV_FROM_UTF8_FUNCTION.md CURLOPT_CONV_TO_NETWORK_FUNCTION.md CURLOPT_COOKIE.md CURLOPT_COOKIEFILE.md CURLOPT_COOKIEJAR.md CURLOPT_COOKIELIST.md CURLOPT_COOKIESESSION.md CURLOPT_COPYPOSTFIELDS.md CURLOPT_CRLF.md CURLOPT_CRLFILE.md CURLOPT_CURLU.md CURLOPT_CUSTOMREQUEST.md CURLOPT_DEBUGDATA.md CURLOPT_DEBUGFUNCTION.md CURLOPT_DEFAULT_PROTOCOL.md CURLOPT_DIRLISTONLY.md CURLOPT_DISALLOW_USERNAME_IN_URL.md CURLOPT_DNS_CACHE_TIMEOUT.md CURLOPT_DNS_INTERFACE.md CURLOPT_DNS_LOCAL_IP4.md CURLOPT_DNS_LOCAL_IP6.md CURLOPT_DNS_SERVERS.md CURLOPT_DNS_SHUFFLE_ADDRESSES.md CURLOPT_DNS_USE_GLOBAL_CACHE.md CURLOPT_DOH_SSL_VERIFYHOST.md CURLOPT_DOH_SSL_VERIFYPEER.md CURLOPT_DOH_SSL_VERIFYSTATUS.md CURLOPT_DOH_URL.md CURLOPT_ECH.md CURLOPT_EGDSOCKET.md CURLOPT_ERRORBUFFER.md CURLOPT_EXPECT_100_TIMEOUT_MS.md CURLOPT_FAILONERROR.md CURLOPT_FILETIME.md CURLOPT_FNMATCH_DATA.md CURLOPT_FNMATCH_FUNCTION.md CURLOPT_FOLLOWLOCATION.md CURLOPT_FORBID_REUSE.md CURLOPT_FRESH_CONNECT.md CURLOPT_FTPPORT.md CURLOPT_FTPSSLAUTH.md CURLOPT_FTP_ACCOUNT.md CURLOPT_FTP_ALTERNATIVE_TO_USER.md CURLOPT_FTP_CREATE_MISSING_DIRS.md CURLOPT_FTP_FILEMETHOD.md CURLOPT_FTP_SKIP_PASV_IP.md CURLOPT_FTP_SSL_CCC.md CURLOPT_FTP_USE_EPRT.md CURLOPT_FTP_USE_EPSV.md CURLOPT_FTP_USE_PRET.md CURLOPT_GSSAPI_DELEGATION.md CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.md CURLOPT_HAPROXYPROTOCOL.md CURLOPT_HAPROXY_CLIENT_IP.md CURLOPT_HEADER.md CURLOPT_HEADERDATA.md CURLOPT_HEADERFUNCTION.md CURLOPT_HEADEROPT.md CURLOPT_HSTS.md CURLOPT_HSTSREADDATA.md CURLOPT_HSTSREADFUNCTION.md CURLOPT_HSTSWRITEDATA.md CURLOPT_HSTSWRITEFUNCTION.md CURLOPT_HSTS_CTRL.md CURLOPT_HTTP09_ALLOWED.md CURLOPT_HTTP200ALIASES.md CURLOPT_HTTPAUTH.md CURLOPT_HTTPGET.md CURLOPT_HTTPHEADER.md CURLOPT_HTTPPOST.md CURLOPT_HTTPPROXYTUNNEL.md CURLOPT_HTTP_CONTENT_DECODING.md CURLOPT_HTTP_TRANSFER_DECODING.md CURLOPT_HTTP_VERSION.md CURLOPT_IGNORE_CONTENT_LENGTH.md CURLOPT_INFILESIZE.md CURLOPT_INFILESIZE_LARGE.md CURLOPT_INTERFACE.md CURLOPT_INTERLEAVEDATA.md CURLOPT_INTERLEAVEFUNCTION.md CURLOPT_IOCTLDATA.md CURLOPT_IOCTLFUNCTION.md CURLOPT_IPRESOLVE.md CURLOPT_ISSUERCERT.md CURLOPT_ISSUERCERT_BLOB.md CURLOPT_KEEP_SENDING_ON_ERROR.md CURLOPT_KEYPASSWD.md CURLOPT_KRBLEVEL.md CURLOPT_LOCALPORT.md CURLOPT_LOCALPORTRANGE.md CURLOPT_LOGIN_OPTIONS.md CURLOPT_LOW_SPEED_LIMIT.md CURLOPT_LOW_SPEED_TIME.md CURLOPT_MAIL_AUTH.md CURLOPT_MAIL_FROM.md CURLOPT_MAIL_RCPT.md CURLOPT_MAIL_RCPT_ALLOWFAILS.md CURLOPT_MAXAGE_CONN.md CURLOPT_MAXCONNECTS.md CURLOPT_MAXFILESIZE.md CURLOPT_MAXFILESIZE_LARGE.md CURLOPT_MAXLIFETIME_CONN.md CURLOPT_MAXREDIRS.md CURLOPT_MAX_RECV_SPEED_LARGE.md CURLOPT_MAX_SEND_SPEED_LARGE.md CURLOPT_MIMEPOST.md CURLOPT_MIME_OPTIONS.md CURLOPT_NETRC.md CURLOPT_NETRC_FILE.md CURLOPT_NEW_DIRECTORY_PERMS.md CURLOPT_NEW_FILE_PERMS.md CURLOPT_NOBODY.md CURLOPT_NOPROGRESS.md CURLOPT_NOPROXY.md CURLOPT_NOSIGNAL.md CURLOPT_OPENSOCKETDATA.md CURLOPT_OPENSOCKETFUNCTION.md CURLOPT_PASSWORD.md CURLOPT_PATH_AS_IS.md CURLOPT_PINNEDPUBLICKEY.md CURLOPT_PIPEWAIT.md CURLOPT_PORT.md CURLOPT_POST.md CURLOPT_POSTFIELDS.md CURLOPT_POSTFIELDSIZE.md CURLOPT_POSTFIELDSIZE_LARGE.md CURLOPT_POSTQUOTE.md CURLOPT_POSTREDIR.md CURLOPT_PREQUOTE.md CURLOPT_PREREQDATA.md CURLOPT_PREREQFUNCTION.md CURLOPT_PRE_PROXY.md CURLOPT_PRIVATE.md CURLOPT_PROGRESSDATA.md CURLOPT_PROGRESSFUNCTION.md CURLOPT_PROTOCOLS.md CURLOPT_PROTOCOLS_STR.md CURLOPT_PROXY.md CURLOPT_PROXYAUTH.md CURLOPT_PROXYHEADER.md CURLOPT_PROXYPASSWORD.md CURLOPT_PROXYPORT.md CURLOPT_PROXYTYPE.md CURLOPT_PROXYUSERNAME.md CURLOPT_PROXYUSERPWD.md CURLOPT_PROXY_CAINFO.md CURLOPT_PROXY_CAINFO_BLOB.md CURLOPT_PROXY_CAPATH.md CURLOPT_PROXY_CRLFILE.md CURLOPT_PROXY_ISSUERCERT.md CURLOPT_PROXY_ISSUERCERT_BLOB.md CURLOPT_PROXY_KEYPASSWD.md CURLOPT_PROXY_PINNEDPUBLICKEY.md CURLOPT_PROXY_SERVICE_NAME.md CURLOPT_PROXY_SSLCERT.md CURLOPT_PROXY_SSLCERTTYPE.md CURLOPT_PROXY_SSLCERT_BLOB.md CURLOPT_PROXY_SSLKEY.md CURLOPT_PROXY_SSLKEYTYPE.md CURLOPT_PROXY_SSLKEY_BLOB.md CURLOPT_PROXY_SSLVERSION.md CURLOPT_PROXY_SSL_CIPHER_LIST.md CURLOPT_PROXY_SSL_OPTIONS.md CURLOPT_PROXY_SSL_VERIFYHOST.md CURLOPT_PROXY_SSL_VERIFYPEER.md CURLOPT_PROXY_TLS13_CIPHERS.md CURLOPT_PROXY_TLSAUTH_PASSWORD.md CURLOPT_PROXY_TLSAUTH_TYPE.md CURLOPT_PROXY_TLSAUTH_USERNAME.md CURLOPT_PROXY_TRANSFER_MODE.md CURLOPT_PUT.md CURLOPT_QUICK_EXIT.md CURLOPT_QUOTE.md CURLOPT_RANDOM_FILE.md CURLOPT_RANGE.md CURLOPT_READDATA.md CURLOPT_READFUNCTION.md CURLOPT_REDIR_PROTOCOLS.md CURLOPT_REDIR_PROTOCOLS_STR.md CURLOPT_REFERER.md CURLOPT_REQUEST_TARGET.md CURLOPT_RESOLVE.md CURLOPT_RESOLVER_START_DATA.md CURLOPT_RESOLVER_START_FUNCTION.md CURLOPT_RESUME_FROM.md CURLOPT_RESUME_FROM_LARGE.md CURLOPT_RTSP_CLIENT_CSEQ.md CURLOPT_RTSP_REQUEST.md CURLOPT_RTSP_SERVER_CSEQ.md CURLOPT_RTSP_SESSION_ID.md CURLOPT_RTSP_STREAM_URI.md CURLOPT_RTSP_TRANSPORT.md CURLOPT_SASL_AUTHZID.md CURLOPT_SASL_IR.md CURLOPT_SEEKDATA.md CURLOPT_SEEKFUNCTION.md CURLOPT_SERVER_RESPONSE_TIMEOUT.md CURLOPT_SERVER_RESPONSE_TIMEOUT_MS.md CURLOPT_SERVICE_NAME.md CURLOPT_SHARE.md CURLOPT_SOCKOPTDATA.md CURLOPT_SOCKOPTFUNCTION.md CURLOPT_SOCKS5_AUTH.md CURLOPT_SOCKS5_GSSAPI_NEC.md CURLOPT_SOCKS5_GSSAPI_SERVICE.md CURLOPT_SSH_AUTH_TYPES.md CURLOPT_SSH_COMPRESSION.md CURLOPT_SSH_HOSTKEYDATA.md CURLOPT_SSH_HOSTKEYFUNCTION.md CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md CURLOPT_SSH_KEYDATA.md CURLOPT_SSH_KEYFUNCTION.md CURLOPT_SSH_KNOWNHOSTS.md CURLOPT_SSH_PRIVATE_KEYFILE.md CURLOPT_SSH_PUBLIC_KEYFILE.md CURLOPT_SSLCERT.md CURLOPT_SSLCERTTYPE.md CURLOPT_SSLCERT_BLOB.md CURLOPT_SSLENGINE.md CURLOPT_SSLENGINE_DEFAULT.md CURLOPT_SSLKEY.md CURLOPT_SSLKEYTYPE.md CURLOPT_SSLKEY_BLOB.md CURLOPT_SSLVERSION.md CURLOPT_SSL_CIPHER_LIST.md CURLOPT_SSL_CTX_DATA.md CURLOPT_SSL_CTX_FUNCTION.md CURLOPT_SSL_EC_CURVES.md CURLOPT_SSL_ENABLE_ALPN.md CURLOPT_SSL_ENABLE_NPN.md CURLOPT_SSL_FALSESTART.md CURLOPT_SSL_OPTIONS.md CURLOPT_SSL_SESSIONID_CACHE.md CURLOPT_SSL_SIGNATURE_ALGORITHMS.md CURLOPT_SSL_VERIFYHOST.md CURLOPT_SSL_VERIFYPEER.md CURLOPT_SSL_VERIFYSTATUS.md CURLOPT_STDERR.md CURLOPT_STREAM_DEPENDS.md CURLOPT_STREAM_DEPENDS_E.md CURLOPT_STREAM_WEIGHT.md CURLOPT_SUPPRESS_CONNECT_HEADERS.md CURLOPT_TCP_FASTOPEN.md CURLOPT_TCP_KEEPALIVE.md CURLOPT_TCP_KEEPCNT.md CURLOPT_TCP_KEEPIDLE.md CURLOPT_TCP_KEEPINTVL.md CURLOPT_TCP_NODELAY.md CURLOPT_TELNETOPTIONS.md CURLOPT_TFTP_BLKSIZE.md CURLOPT_TFTP_NO_OPTIONS.md CURLOPT_TIMECONDITION.md CURLOPT_TIMEOUT.md CURLOPT_TIMEOUT_MS.md CURLOPT_TIMEVALUE.md CURLOPT_TIMEVALUE_LARGE.md CURLOPT_TLS13_CIPHERS.md CURLOPT_TLSAUTH_PASSWORD.md CURLOPT_TLSAUTH_TYPE.md CURLOPT_TLSAUTH_USERNAME.md CURLOPT_TRAILERDATA.md CURLOPT_TRAILERFUNCTION.md CURLOPT_TRANSFERTEXT.md CURLOPT_TRANSFER_ENCODING.md CURLOPT_UNIX_SOCKET_PATH.md CURLOPT_UNRESTRICTED_AUTH.md CURLOPT_UPKEEP_INTERVAL_MS.md CURLOPT_UPLOAD.md CURLOPT_UPLOAD_BUFFERSIZE.md CURLOPT_UPLOAD_FLAGS.md CURLOPT_URL.md CURLOPT_USERAGENT.md CURLOPT_USERNAME.md CURLOPT_USERPWD.md CURLOPT_USE_SSL.md CURLOPT_VERBOSE.md CURLOPT_WILDCARDMATCH.md CURLOPT_WRITEDATA.md CURLOPT_WRITEFUNCTION.md CURLOPT_WS_OPTIONS.md CURLOPT_XFERINFODATA.md CURLOPT_XFERINFOFUNCTION.md CURLOPT_XOAUTH2_BEARER.md CURLSHOPT_LOCKFUNC.md CURLSHOPT_SHARE.md CURLSHOPT_UNLOCKFUNC.md CURLSHOPT_UNSHARE.md CURLSHOPT_USERDATA.md Makefile.am Makefile.incinclude
curl
Makefile.am curl.h curlver.h easy.h header.h mprintf.h multi.h options.h stdcheaders.h system.h typecheck-gcc.h urlapi.h websockets.hlib
curlx
base64.c base64.h basename.c basename.h dynbuf.c dynbuf.h fopen.c fopen.h inet_ntop.c inet_ntop.h inet_pton.c inet_pton.h multibyte.c multibyte.h nonblock.c nonblock.h snprintf.c snprintf.h strcopy.c strcopy.h strdup.c strdup.h strerr.c strerr.h strparse.c strparse.h timediff.c timediff.h timeval.c timeval.h version_win32.c version_win32.h wait.c wait.h warnless.c warnless.h winapi.c winapi.hvauth
cleartext.c cram.c digest.c digest.h digest_sspi.c gsasl.c krb5_gssapi.c krb5_sspi.c ntlm.c ntlm_sspi.c oauth2.c spnego_gssapi.c spnego_sspi.c vauth.c vauth.hvquic
curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.hvtls
apple.c apple.h cipher_suite.c cipher_suite.h gtls.c gtls.h hostcheck.c hostcheck.h keylog.c keylog.h mbedtls.c mbedtls.h openssl.c openssl.h rustls.c rustls.h schannel.c schannel.h schannel_int.h schannel_verify.c vtls.c vtls.h vtls_int.h vtls_scache.c vtls_scache.h vtls_spack.c vtls_spack.h wolfssl.c wolfssl.h x509asn1.c x509asn1.hm4
.gitignore curl-amissl.m4 curl-apple-sectrust.m4 curl-compilers.m4 curl-confopts.m4 curl-functions.m4 curl-gnutls.m4 curl-mbedtls.m4 curl-openssl.m4 curl-override.m4 curl-reentrant.m4 curl-rustls.m4 curl-schannel.m4 curl-sysconfig.m4 curl-wolfssl.m4 xc-am-iface.m4 xc-cc-check.m4 xc-lt-iface.m4 xc-val-flgs.m4 zz40-xc-ovr.m4 zz50-xc-ovr.m4projects
OS400
.checksrc README.OS400 ccsidcurl.c ccsidcurl.h config400.default curl.cmd curl.inc.in curlcl.c curlmain.c initscript.sh make-docs.sh make-include.sh make-lib.sh make-src.sh make-tests.sh makefile.sh os400sys.c os400sys.hWindows
tmpl
.gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filtersvms
Makefile.am backup_gnv_curl_src.com build_curl-config_script.com build_gnv_curl.com build_gnv_curl_pcsi_desc.com build_gnv_curl_pcsi_text.com build_gnv_curl_release_notes.com build_libcurl_pc.com build_vms.com clean_gnv_curl.com compare_curl_source.com config_h.com curl_crtl_init.c curl_gnv_build_steps.txt curl_release_note_start.txt curl_startup.com curlmsg.h curlmsg.msg curlmsg.sdl curlmsg_vms.h generate_config_vms_h_curl.com generate_vax_transfer.com gnv_conftest.c_first gnv_curl_configure.sh gnv_libcurl_symbols.opt gnv_link_curl.com macro32_exactcase.patch make_gnv_curl_install.sh make_pcsi_curl_kit_name.com pcsi_gnv_curl_file_list.txt pcsi_product_gnv_curl.com readme report_openssl_version.c setup_gnv_curl_build.com stage_curl_install.com vms_eco_level.hscripts
.checksrc CMakeLists.txt Makefile.am badwords badwords-all badwords.txt cd2cd cd2nroff cdall checksrc-all.pl checksrc.pl cmakelint.sh completion.pl contributors.sh contrithanks.sh coverage.sh delta dmaketgz extract-unit-protos firefox-db2pem.sh installcheck.sh maketgz managen mdlinkcheck mk-ca-bundle.pl mk-unity.pl nroff2cd perlcheck.sh pythonlint.sh randdisable release-notes.pl release-tools.sh schemetable.c singleuse.pl spacecheck.pl top-complexity top-length verify-release wcurlsrc
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc config2setopts.c config2setopts.h curl.rc curlinfo.c mk-file-embed.pl mkhelp.pl slist_wc.c slist_wc.h terminal.c terminal.h tool_cb_dbg.c tool_cb_dbg.h tool_cb_hdr.c tool_cb_hdr.h tool_cb_prg.c tool_cb_prg.h tool_cb_rea.c tool_cb_rea.h tool_cb_see.c tool_cb_see.h tool_cb_soc.c tool_cb_soc.h tool_cb_wrt.c tool_cb_wrt.h tool_cfgable.c tool_cfgable.h tool_dirhie.c tool_dirhie.h tool_doswin.c tool_doswin.h tool_easysrc.c tool_easysrc.h tool_filetime.c tool_filetime.h tool_findfile.c tool_findfile.h tool_formparse.c tool_formparse.h tool_getparam.c tool_getparam.h tool_getpass.c tool_getpass.h tool_help.c tool_help.h tool_helpers.c tool_helpers.h tool_hugehelp.h tool_ipfs.c tool_ipfs.h tool_libinfo.c tool_libinfo.h tool_listhelp.c tool_main.c tool_main.h tool_msgs.c tool_msgs.h tool_operate.c tool_operate.h tool_operhlp.c tool_operhlp.h tool_paramhlp.c tool_paramhlp.h tool_parsecfg.c tool_parsecfg.h tool_progress.c tool_progress.h tool_sdecls.h tool_setopt.c tool_setopt.h tool_setup.h tool_ssls.c tool_ssls.h tool_stderr.c tool_stderr.h tool_urlglob.c tool_urlglob.h tool_util.c tool_util.h tool_version.h tool_vms.c tool_vms.h tool_writeout.c tool_writeout.h tool_writeout_json.c tool_writeout_json.h tool_xattr.c tool_xattr.h var.c var.htests
certs
.gitignore CMakeLists.txt Makefile.am Makefile.inc genserv.pl srp-verifier-conf srp-verifier-db test-ca.cnf test-ca.prm test-client-cert.prm test-client-eku-only.prm test-localhost-san-first.prm test-localhost-san-last.prm test-localhost.nn.prm test-localhost.prm test-localhost0h.prmdata
.gitignore DISABLED Makefile.am data-xml1 data1400.c data1401.c data1402.c data1403.c data1404.c data1405.c data1406.c data1407.c data1420.c data1461.txt data1463.txt data1465.c data1481.c data1705-1.md data1705-2.md data1705-3.md data1705-4.md data1705-stdout.1 data1706-1.md data1706-2.md data1706-3.md data1706-4.md data1706-stdout.txt data320.html test1 test10 test100 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 test1008 test1009 test101 test1010 test1011 test1012 test1013 test1014 test1015 test1016 test1017 test1018 test1019 test102 test1020 test1021 test1022 test1023 test1024 test1025 test1026 test1027 test1028 test1029 test103 test1030 test1031 test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 test104 test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 test1048 test1049 test105 test1050 test1051 test1052 test1053 test1054 test1055 test1056 test1057 test1058 test1059 test106 test1060 test1061 test1062 test1063 test1064 test1065 test1066 test1067 test1068 test1069 test107 test1070 test1071 test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 test108 test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 test1088 test1089 test109 test1090 test1091 test1092 test1093 test1094 test1095 test1096 test1097 test1098 test1099 test11 test110 test1100 test1101 test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 test111 test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 test112 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 test1128 test1129 test113 test1130 test1131 test1132 test1133 test1134 test1135 test1136 test1137 test1138 test1139 test114 test1140 test1141 test1142 test1143 test1144 test1145 test1146 test1147 test1148 test1149 test115 test1150 test1151 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 test116 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 test1168 test1169 test117 test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 test1178 test1179 test118 test1180 test1181 test1182 test1183 test1184 test1185 test1186 test1187 test1188 test1189 test119 test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 test1199 test12 test120 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 test1208 test1209 test121 test1210 test1211 test1212 test1213 test1214 test1215 test1216 test1217 test1218 test1219 test122 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 test1228 test1229 test123 test1230 test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 test124 test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 test1248 test1249 test125 test1250 test1251 test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 test126 test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 test1268 test1269 test127 test1270 test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 test1279 test128 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 test1288 test1289 test129 test1290 test1291 test1292 test1293 test1294 test1295 test1296 test1297 test1298 test1299 test13 test130 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 test1309 test131 test1310 test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 test132 test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 test133 test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 test134 test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 test1348 test1349 test135 test1350 test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 test136 test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 test137 test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 test138 test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 test1388 test1389 test139 test1390 test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 test14 test140 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 test141 test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 test1418 test1419 test142 test1420 test1421 test1422 test1423 test1424 test1425 test1426 test1427 test1428 test1429 test143 test1430 test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 test144 test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 test145 test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 test146 test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 test1468 test1469 test147 test1470 test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 test1479 test148 test1480 test1481 test1482 test1483 test1484 test1485 test1486 test1487 test1488 test1489 test149 test1490 test1491 test1492 test1493 test1494 test1495 test1496 test1497 test1498 test1499 test15 test150 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 test1508 test1509 test151 test1510 test1511 test1512 test1513 test1514 test1515 test1516 test1517 test1518 test1519 test152 test1520 test1521 test1522 test1523 test1524 test1525 test1526 test1527 test1528 test1529 test153 test1530 test1531 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 test154 test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 test1548 test1549 test155 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 test1558 test1559 test156 test1560 test1561 test1562 test1563 test1564 test1565 test1566 test1567 test1568 test1569 test157 test1570 test1571 test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 test158 test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 test1589 test159 test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 test1598 test1599 test16 test160 test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 test1608 test1609 test161 test1610 test1611 test1612 test1613 test1614 test1615 test1616 test1617 test1618 test1619 test162 test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 test163 test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 test1638 test1639 test164 test1640 test1641 test1642 test1643 test1644 test1645 test165 test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 test1658 test1659 test166 test1660 test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 test1669 test167 test1670 test1671 test1672 test1673 test1674 test1675 test1676 test168 test1680 test1681 test1682 test1683 test1684 test1685 test169 test17 test170 test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 test1708 test1709 test171 test1710 test1711 test1712 test1713 test1714 test1715 test172 test1720 test1721 test173 test174 test175 test176 test177 test178 test179 test18 test180 test1800 test1801 test1802 test181 test182 test183 test184 test1847 test1848 test1849 test185 test1850 test1851 test186 test187 test188 test189 test19 test190 test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 test1908 test1909 test191 test1910 test1911 test1912 test1913 test1914 test1915 test1916 test1917 test1918 test1919 test192 test1920 test1921 test193 test1933 test1934 test1935 test1936 test1937 test1938 test1939 test194 test1940 test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 test195 test1955 test1956 test1957 test1958 test1959 test196 test1960 test1964 test1965 test1966 test197 test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 test1978 test1979 test198 test1980 test1981 test1982 test1983 test1984 test199 test2 test20 test200 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 test2008 test2009 test201 test2010 test2011 test2012 test2013 test2014 test202 test2023 test2024 test2025 test2026 test2027 test2028 test2029 test203 test2030 test2031 test2032 test2033 test2034 test2035 test2037 test2038 test2039 test204 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 test2048 test2049 test205 test2050 test2051 test2052 test2053 test2054 test2055 test2056 test2057 test2058 test2059 test206 test2060 test2061 test2062 test2063 test2064 test2065 test2066 test2067 test2068 test2069 test207 test2070 test2071 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 test208 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 test2088 test2089 test209 test2090 test2091 test2092 test21 test210 test2100 test2101 test2102 test2103 test2104 test211 test212 test213 test214 test215 test216 test217 test218 test219 test22 test220 test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 test221 test222 test223 test224 test225 test226 test227 test228 test229 test23 test230 test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 test2309 test231 test232 test233 test234 test235 test236 test237 test238 test239 test24 test240 test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 test2408 test2409 test241 test2410 test2411 test242 test243 test244 test245 test246 test247 test248 test249 test25 test250 test2500 test2501 test2502 test2503 test2504 test2505 test2506 test251 test252 test253 test254 test255 test256 test257 test258 test259 test26 test260 test2600 test2601 test2602 test2603 test2604 test2605 test261 test262 test263 test264 test265 test266 test267 test268 test269 test27 test270 test2700 test2701 test2702 test2703 test2704 test2705 test2706 test2707 test2708 test2709 test271 test2710 test2711 test2712 test2713 test2714 test2715 test2716 test2717 test2718 test2719 test272 test2720 test2721 test2722 test2723 test273 test274 test275 test276 test277 test278 test279 test28 test280 test281 test282 test283 test284 test285 test286 test287 test288 test289 test29 test290 test291 test292 test293 test294 test295 test296 test297 test298 test299 test3 test30 test300 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 test3008 test3009 test301 test3010 test3011 test3012 test3013 test3014 test3015 test3016 test3017 test3018 test3019 test302 test3020 test3021 test3022 test3023 test3024 test3025 test3026 test3027 test3028 test3029 test303 test3030 test3031 test3032 test3033 test3034 test3035 test3036 test304 test305 test306 test307 test308 test309 test31 test310 test3100 test3101 test3102 test3103 test3104 test3105 test3106 test311 test312 test313 test314 test315 test316 test317 test318 test319 test32 test320 test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 test3209 test321 test3210 test3211 test3212 test3213 test3214 test3215 test3216 test3217 test3218 test3219 test322 test3220 test323 test324 test325 test326 test327 test328 test329 test33 test330 test3300 test3301 test3302 test331 test332 test333 test334 test335 test336 test337 test338 test339 test34 test340 test341 test342 test343 test344 test345 test346 test347 test348 test349 test35 test350 test351 test352 test353 test354 test355 test356 test357 test358 test359 test36 test360 test361 test362 test363 test364 test365 test366 test367 test368 test369 test37 test370 test371 test372 test373 test374 test375 test376 test378 test379 test38 test380 test381 test383 test384 test385 test386 test387 test388 test389 test39 test390 test391 test392 test393 test394 test395 test396 test397 test398 test399 test4 test40 test400 test4000 test4001 test401 test402 test403 test404 test405 test406 test407 test408 test409 test41 test410 test411 test412 test413 test414 test415 test416 test417 test418 test419 test42 test420 test421 test422 test423 test424 test425 test426 test427 test428 test429 test43 test430 test431 test432 test433 test434 test435 test436 test437 test438 test439 test44 test440 test441 test442 test443 test444 test445 test446 test447 test448 test449 test45 test450 test451 test452 test453 test454 test455 test456 test457 test458 test459 test46 test460 test461 test462 test463 test467 test468 test469 test47 test470 test471 test472 test473 test474 test475 test476 test477 test478 test479 test48 test480 test481 test482 test483 test484 test485 test486 test487 test488 test489 test49 test490 test491 test492 test493 test494 test495 test496 test497 test498 test499 test5 test50 test500 test501 test502 test503 test504 test505 test506 test507 test508 test509 test51 test510 test511 test512 test513 test514 test515 test516 test517 test518 test519 test52 test520 test521 test522 test523 test524 test525 test526 test527 test528 test529 test53 test530 test531 test532 test533 test534 test535 test536 test537 test538 test539 test54 test540 test541 test542 test543 test544 test545 test546 test547 test548 test549 test55 test550 test551 test552 test553 test554 test555 test556 test557 test558 test559 test56 test560 test561 test562 test563 test564 test565 test566 test567 test568 test569 test57 test570 test571 test572 test573 test574 test575 test576 test577 test578 test579 test58 test580 test581 test582 test583 test584 test585 test586 test587 test588 test589 test59 test590 test591 test592 test593 test594 test595 test596 test597 test598 test599 test6 test60 test600 test601 test602 test603 test604 test605 test606 test607 test608 test609 test61 test610 test611 test612 test613 test614 test615 test616 test617 test618 test619 test62 test620 test621 test622 test623 test624 test625 test626 test627 test628 test629 test63 test630 test631 test632 test633 test634 test635 test636 test637 test638 test639 test64 test640 test641 test642 test643 test644 test645 test646 test647 test648 test649 test65 test650 test651 test652 test653 test654 test655 test656 test658 test659 test66 test660 test661 test662 test663 test664 test665 test666 test667 test668 test669 test67 test670 test671 test672 test673 test674 test675 test676 test677 test678 test679 test68 test680 test681 test682 test683 test684 test685 test686 test687 test688 test689 test69 test690 test691 test692 test693 test694 test695 test696 test697 test698 test699 test7 test70 test700 test701 test702 test703 test704 test705 test706 test707 test708 test709 test71 test710 test711 test712 test713 test714 test715 test716 test717 test718 test719 test72 test720 test721 test722 test723 test724 test725 test726 test727 test728 test729 test73 test730 test731 test732 test733 test734 test735 test736 test737 test738 test739 test74 test740 test741 test742 test743 test744 test745 test746 test747 test748 test749 test75 test750 test751 test752 test753 test754 test755 test756 test757 test758 test759 test76 test760 test761 test762 test763 test764 test765 test766 test767 test768 test769 test77 test770 test771 test772 test773 test774 test775 test776 test777 test778 test779 test78 test780 test781 test782 test783 test784 test785 test786 test787 test788 test789 test79 test790 test791 test792 test793 test794 test795 test796 test797 test798 test799 test8 test80 test800 test801 test802 test803 test804 test805 test806 test807 test808 test809 test81 test810 test811 test812 test813 test814 test815 test816 test817 test818 test819 test82 test820 test821 test822 test823 test824 test825 test826 test827 test828 test829 test83 test830 test831 test832 test833 test834 test835 test836 test837 test838 test839 test84 test840 test841 test842 test843 test844 test845 test846 test847 test848 test849 test85 test850 test851 test852 test853 test854 test855 test856 test857 test858 test859 test86 test860 test861 test862 test863 test864 test865 test866 test867 test868 test869 test87 test870 test871 test872 test873 test874 test875 test876 test877 test878 test879 test88 test880 test881 test882 test883 test884 test885 test886 test887 test888 test889 test89 test890 test891 test892 test893 test894 test895 test896 test897 test898 test899 test9 test90 test900 test901 test902 test903 test904 test905 test906 test907 test908 test909 test91 test910 test911 test912 test913 test914 test915 test916 test917 test918 test919 test92 test920 test921 test922 test923 test924 test925 test926 test927 test928 test929 test93 test930 test931 test932 test933 test934 test935 test936 test937 test938 test939 test94 test940 test941 test942 test943 test944 test945 test946 test947 test948 test949 test95 test950 test951 test952 test953 test954 test955 test956 test957 test958 test959 test96 test960 test961 test962 test963 test964 test965 test966 test967 test968 test969 test97 test970 test971 test972 test973 test974 test975 test976 test977 test978 test979 test98 test980 test981 test982 test983 test984 test985 test986 test987 test988 test989 test99 test990 test991 test992 test993 test994 test995 test996 test997 test998 test999http
testenv
__init__.py caddy.py certs.py client.py curl.py dante.py dnsd.py env.py httpd.py nghttpx.py ports.py sshd.py vsftpd.py ws_echo_server.pylibtest
.gitignore CMakeLists.txt Makefile.am Makefile.inc cli_ftp_upload.c cli_h2_pausing.c cli_h2_serverpush.c cli_h2_upgrade_extreme.c cli_hx_download.c cli_hx_upload.c cli_tls_session_reuse.c cli_upload_pausing.c cli_ws_data.c cli_ws_pingpong.c first.c first.h lib1156.c lib1301.c lib1308.c lib1485.c lib1500.c lib1501.c lib1502.c lib1506.c lib1507.c lib1508.c lib1509.c lib1510.c lib1511.c lib1512.c lib1513.c lib1514.c lib1515.c lib1517.c lib1518.c lib1520.c lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c lib1545.c lib1549.c lib1550.c lib1551.c lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c lib1559.c lib1560.c lib1564.c lib1565.c lib1567.c lib1568.c lib1569.c lib1571.c lib1576.c lib1582.c lib1587.c lib1588.c lib1589.c lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c lib1598.c lib1599.c lib1662.c lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c lib1933.c lib1934.c lib1935.c lib1936.c lib1937.c lib1938.c lib1939.c lib1940.c lib1945.c lib1947.c lib1948.c lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c lib1964.c lib1965.c lib1970.c lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c lib2023.c lib2032.c lib2082.c lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c lib2402.c lib2404.c lib2405.c lib2502.c lib2504.c lib2505.c lib2506.c lib2700.c lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c lib3207.c lib3208.c lib500.c lib501.c lib502.c lib503.c lib504.c lib505.c lib506.c lib507.c lib508.c lib509.c lib510.c lib511.c lib512.c lib513.c lib514.c lib515.c lib516.c lib517.c lib518.c lib519.c lib520.c lib521.c lib523.c lib524.c lib525.c lib526.c lib530.c lib533.c lib536.c lib537.c lib539.c lib540.c lib541.c lib542.c lib543.c lib544.c lib547.c lib549.c lib552.c lib553.c lib554.c lib555.c lib556.c lib557.c lib558.c lib559.c lib560.c lib562.c lib564.c lib566.c lib567.c lib568.c lib569.c lib570.c lib571.c lib572.c lib573.c lib574.c lib575.c lib576.c lib578.c lib579.c lib582.c lib583.c lib586.c lib589.c lib590.c lib591.c lib597.c lib598.c lib599.c lib643.c lib650.c lib651.c lib652.c lib653.c lib654.c lib655.c lib658.c lib659.c lib661.c lib666.c lib667.c lib668.c lib670.c lib674.c lib676.c lib677.c lib678.c lib694.c lib695.c lib751.c lib753.c lib757.c lib758.c lib766.c memptr.c mk-lib1521.pl test1013.pl test1022.pl test307.pl test610.pl test613.pl testtrace.c testtrace.h testutil.c testutil.h unitcheck.hserver
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc dnsd.c first.c first.h getpart.c mqttd.c resolve.c rtspd.c sockfilt.c socksd.c sws.c tftpd.c util.ctunit
.gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.cunit
.gitignore CMakeLists.txt Makefile.am Makefile.inc README.md unit1300.c unit1302.c unit1303.c unit1304.c unit1305.c unit1307.c unit1309.c unit1323.c unit1330.c unit1395.c unit1396.c unit1397.c unit1398.c unit1399.c unit1600.c unit1601.c unit1602.c unit1603.c unit1605.c unit1606.c unit1607.c unit1608.c unit1609.c unit1610.c unit1611.c unit1612.c unit1614.c unit1615.c unit1616.c unit1620.c unit1625.c unit1626.c unit1627.c unit1636.c unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c unit1666.c unit1667.c unit1668.c unit1669.c unit1674.c unit1675.c unit1676.c unit1979.c unit1980.c unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c unit3200.c unit3205.c unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c unit3219.c unit3300.c unit3301.c unit3302.cexamples
.env config.ini crypto_test.lua env_test.lua fs_example.lua http_server.lua https_test.lua ini_example.lua json.lua log.lua path_fs_example.lua process_example.lua request_download.lua request_test.lua run_all.lua sqlite_example.lua sqlite_http_template.lua stash_test.lua template_test.lua timer.lua websocket.luainiparser
example
iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.initest
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.hjinjac
libjinjac
src
CMakeLists.txt ast.c ast.h block_statement.c block_statement.h buffer.c buffer.h buildin.c buildin.h common.h convert.c convert.h flex_decl.h jfunction.c jfunction.h jinja_expression.l jinja_expression.y jinjac_parse.c jinjac_parse.h jinjac_stream.c jinjac_stream.h jlist.c jlist.h jobject.c jobject.h parameter.c parameter.h str_obj.c str_obj.h trace.c trace.htest
.gitignore CMakeLists.txt autotest.rb test_01.expected test_01.jinja test_01b.expected test_01b.jinja test_01c.expected test_01c.jinja test_01d.expected test_01d.jinja test_02.expected test_02.jinja test_03.expected test_03.jinja test_04.expected test_04.jinja test_05.expected test_05.jinja test_06.expected test_06.jinja test_07.expected test_07.jinja test_08.expected test_08.jinja test_08b.expected test_08b.jinja test_09.expected test_09.jinja test_10.expected test_10.jinja test_11.expected test_11.jinja test_12.expected test_12.jinja test_13.expected test_13.jinja test_14.expected test_14.jinja test_15.expected test_15.jinja test_16.expected test_16.jinja test_17.expected test_17.jinja test_18.expected test_18.jinja test_18b.expected test_18b.jinja test_18c.expected test_18c.jinja test_19.expected test_19.jinja test_19b.expected test_19b.jinja test_19c.expected test_19c.jinja test_19d.expected test_19d.jinja test_19e.expected test_19e.jinja test_19f.expected test_19f.jinja test_20.expected test_20.jinja test_21.expected test_21.jinja test_22.expected test_22.jinja test_22a.expected test_22a.jinja test_22b.expected test_22b.jinja test_23.expected test_23.jinja test_24.expected test_24.jinjalibev
Changes LICENSE Makefile Makefile.am Makefile.in README Symbols.ev Symbols.event aclocal.m4 autogen.sh compile config.guess config.h config.h.in config.status config.sub configure configure.ac depcomp ev++.h ev.3 ev.c ev.h ev.pod ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_vars.h ev_win32.c ev_wrap.h event.c event.h install-sh libev.m4 libtool ltmain.sh missing mkinstalldirs stamp-h1luajit
doc
bluequad-print.css bluequad.css contact.html ext_buffer.html ext_c_api.html ext_ffi.html ext_ffi_api.html ext_ffi_semantics.html ext_ffi_tutorial.html ext_jit.html ext_profiler.html extensions.html install.html luajit.html running.htmldynasm
dasm_arm.h dasm_arm.lua dasm_arm64.h dasm_arm64.lua dasm_mips.h dasm_mips.lua dasm_mips64.lua dasm_ppc.h dasm_ppc.lua dasm_proto.h dasm_x64.lua dasm_x86.h dasm_x86.lua dynasm.luasrc
host
.gitignore README buildvm.c buildvm.h buildvm_asm.c buildvm_fold.c buildvm_lib.c buildvm_libbc.h buildvm_peobj.c genlibbc.lua genminilua.lua genversion.lua minilua.cjit
.gitignore bc.lua bcsave.lua dis_arm.lua dis_arm64.lua dis_arm64be.lua dis_mips.lua dis_mips64.lua dis_mips64el.lua dis_mips64r6.lua dis_mips64r6el.lua dis_mipsel.lua dis_ppc.lua dis_x64.lua dis_x86.lua dump.lua p.lua v.lua zone.luawolfssl
.github
workflows
ada.yml arduino.yml async-examples.yml async.yml atecc608-sim.yml bind.yml cmake-autoconf.yml cmake.yml codespell.yml coverity-scan-fixes.yml cryptocb-only.yml curl.yml cyrus-sasl.yml disable-pk-algs.yml docker-Espressif.yml docker-OpenWrt.yml emnet-nonblock.yml fil-c.yml freertos-mem-track.yml gencertbuf.yml grpc.yml haproxy.yml hostap-vm.yml intelasm-c-fallback.yml ipmitool.yml jwt-cpp.yml krb5.yml libspdm.yml libssh2.yml libvncserver.yml linuxkm.yml macos-apple-native-cert-validation.yml mbedtls.sh mbedtls.yml membrowse-comment.yml membrowse-onboard.yml membrowse-report.yml memcached.sh memcached.yml mono.yml mosquitto.yml msmtp.yml msys2.yml multi-arch.yml multi-compiler.yml net-snmp.yml nginx.yml no-malloc.yml no-tls.yml nss.sh nss.yml ntp.yml ocsp.yml openldap.yml openssh.yml openssl-ech.yml opensslcoexist.yml openvpn.yml os-check.yml packaging.yml pam-ipmi.yml pq-all.yml pr-commit-check.yml psk.yml puf.yml python.yml rng-tools.yml rust-wrapper.yml se050-sim.yml smallStackSize.yml socat.yml softhsm.yml sssd.yml stm32-sim.yml stsafe-a120-sim.yml stunnel.yml symbol-prefixes.yml threadx.yml tls-anvil.yml trackmemory.yml watcomc.yml win-csharp-test.yml wolfCrypt-Wconversion.yml wolfboot-integration.yml wolfsm.yml xcode.yml zephyr-4.x.yml zephyr.ymlIDE
ARDUINO
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.hECLIPSE
Espressif
ESP-IDF
examples
template
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266wolfssl_benchmark
VisualGDB
wolfssl_benchmark_IDF_v4.4_ESP32.sln wolfssl_benchmark_IDF_v4.4_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32.sln wolfssl_benchmark_IDF_v5_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32C3.sln wolfssl_benchmark_IDF_v5_ESP32C3.vgdbproj wolfssl_benchmark_IDF_v5_ESP32S3.sln wolfssl_benchmark_IDF_v5_ESP32S3.vgdbprojwolfssl_client
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbprojwolfssl_server
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbprojwolfssl_test
VisualGDB
wolfssl_test-IDF_v5_ESP32.sln wolfssl_test-IDF_v5_ESP32.vgdbproj wolfssl_test-IDF_v5_ESP32C3.sln wolfssl_test-IDF_v5_ESP32C3.vgdbproj wolfssl_test-IDF_v5_ESP32C6.sln wolfssl_test-IDF_v5_ESP32C6.vgdbproj wolfssl_test_IDF_v5_ESP32S3.sln wolfssl_test_IDF_v5_ESP32S3.vgdbprojGCC-ARM
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ldIAR-EWARM
embOS
SAMV71_XULT
embOS_SAMV71_XULT_user_settings
user_settings.h user_settings_simple_example.h user_settings_verbose_example.hembOS_wolfcrypt_benchmark_SAMV71_XULT
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewpINTIME-RTOS
Makefile README.md include.am libwolfssl.c libwolfssl.vcxproj user_settings.h wolfExamples.c wolfExamples.h wolfExamples.sln wolfExamples.vcxproj wolfssl-lib.sln wolfssl-lib.vcxprojMQX
Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.hMSVS-2019-AZSPHERE
wolfssl_new_azsphere
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.cNETOS
Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.cPlatformIO
examples
wolfssl_benchmark
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspaceROWLEY-CROSSWORKS-ARM
Kinetis_FlashPlacement.xml README.md arm_startup.c benchmark_main.c hw.h include.am kinetis_hw.c retarget.c test_main.c user_settings.h wolfssl.hzp wolfssl_ltc.hzpRenesas
e2studio
RA6M3
README.md README_APRA6M_en.md README_APRA6M_jp.md include.amRX72N
EnvisionKit
Simple
README_EN.md README_JP.mdwolfssl_demo
key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.cSTM32Cube
README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.hWIN
README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxprojWIN-SRTP-KDF-140-3
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojWIN10
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojXCODE
Benchmark
include.amXilinxSDK
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.capple-universal
wolfssl-multiplatform
iotsafe
Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.hmynewt
README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.shcerts
1024
ca-cert.der ca-cert.pem ca-key.der ca-key.pem client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der dh1024.der dh1024.pem dsa-pub-1024.pem dsa1024.der dsa1024.pem include.am rsa1024.der server-cert.der server-cert.pem server-key.der server-key.pemcrl
extra-crls
ca-int-cert-revoked.pem claim-root.pem crl_critical_entry.pem crlnum_57oct.pem crlnum_64oct.pem general-server-crl.pem large_crlnum.pem large_crlnum2.pemdilithium
bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.amecc
bp256r1-key.der bp256r1-key.pem ca-secp256k1-cert.pem ca-secp256k1-key.pem client-bp256r1-cert.der client-bp256r1-cert.pem client-secp256k1-cert.der client-secp256k1-cert.pem genecc.sh include.am secp256k1-key.der secp256k1-key.pem secp256k1-param.pem secp256k1-privkey.der secp256k1-privkey.pem server-bp256r1-cert.der server-bp256r1-cert.pem server-secp256k1-cert.der server-secp256k1-cert.pem server2-secp256k1-cert.der server2-secp256k1-cert.pem wolfssl.cnf wolfssl_384.cnfed25519
ca-ed25519-key.der ca-ed25519-key.pem ca-ed25519-priv.der ca-ed25519-priv.pem ca-ed25519.der ca-ed25519.pem client-ed25519-key.der client-ed25519-key.pem client-ed25519-priv.der client-ed25519-priv.pem client-ed25519.der client-ed25519.pem eddsa-ed25519.der eddsa-ed25519.pem gen-ed25519-certs.sh gen-ed25519-keys.sh gen-ed25519.sh include.am root-ed25519-key.der root-ed25519-key.pem root-ed25519-priv.der root-ed25519-priv.pem root-ed25519.der root-ed25519.pem server-ed25519-cert.pem server-ed25519-key.der server-ed25519-key.pem server-ed25519-priv.der server-ed25519-priv.pem server-ed25519.der server-ed25519.pemed448
ca-ed448-key.der ca-ed448-key.pem ca-ed448-priv.der ca-ed448-priv.pem ca-ed448.der ca-ed448.pem client-ed448-key.der client-ed448-key.pem client-ed448-priv.der client-ed448-priv.pem client-ed448.der client-ed448.pem gen-ed448-certs.sh gen-ed448-keys.sh include.am root-ed448-key.der root-ed448-key.pem root-ed448-priv.der root-ed448-priv.pem root-ed448.der root-ed448.pem server-ed448-cert.pem server-ed448-key.der server-ed448-key.pem server-ed448-priv.der server-ed448-priv.pem server-ed448.der server-ed448.pemexternal
DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.amintermediate
ca_false_intermediate
gentestcert.sh int_ca.key server.key test_ca.key test_ca.pem test_int_not_cacert.pem test_sign_bynoca_srv.pem wolfssl_base.conf wolfssl_srv.conflms
bc_hss_L2_H5_W8_root.der bc_hss_L3_H5_W4_root.der bc_lms_chain_ca.der bc_lms_chain_leaf.der bc_lms_native_bc_root.der bc_lms_sha256_h10_w8_root.der bc_lms_sha256_h5_w4_root.der include.ammldsa
README.txt include.am mldsa44-cert.der mldsa44-cert.pem mldsa44-key.pem mldsa44_bare-priv.der mldsa44_bare-seed.der mldsa44_oqskeypair.der mldsa44_priv-only.der mldsa44_pub-spki.der mldsa44_seed-only.der mldsa44_seed-priv.der mldsa65-cert.der mldsa65-cert.pem mldsa65-key.pem mldsa65_bare-priv.der mldsa65_bare-seed.der mldsa65_oqskeypair.der mldsa65_priv-only.der mldsa65_pub-spki.der mldsa65_seed-only.der mldsa65_seed-priv.der mldsa87-cert.der mldsa87-cert.pem mldsa87-key.pem mldsa87_bare-priv.der mldsa87_bare-seed.der mldsa87_oqskeypair.der mldsa87_priv-only.der mldsa87_pub-spki.der mldsa87_seed-only.der mldsa87_seed-priv.derocsp
imposter-root-ca-cert.der imposter-root-ca-cert.pem imposter-root-ca-key.der imposter-root-ca-key.pem include.am index-ca-and-intermediate-cas.txt index-ca-and-intermediate-cas.txt.attr index-intermediate1-ca-issued-certs.txt index-intermediate1-ca-issued-certs.txt.attr index-intermediate2-ca-issued-certs.txt index-intermediate2-ca-issued-certs.txt.attr index-intermediate3-ca-issued-certs.txt index-intermediate3-ca-issued-certs.txt.attr intermediate1-ca-cert.der intermediate1-ca-cert.pem intermediate1-ca-key.der intermediate1-ca-key.pem intermediate2-ca-cert.der intermediate2-ca-cert.pem intermediate2-ca-key.der intermediate2-ca-key.pem intermediate3-ca-cert.der intermediate3-ca-cert.pem intermediate3-ca-key.der intermediate3-ca-key.pem ocsp-responder-cert.der ocsp-responder-cert.pem ocsp-responder-key.der ocsp-responder-key.pem openssl.cnf renewcerts-for-test.sh renewcerts.sh root-ca-cert.der root-ca-cert.pem root-ca-crl.pem root-ca-key.der root-ca-key.pem server1-cert.der server1-cert.pem server1-chain-noroot.pem server1-key.der server1-key.pem server2-cert.der server2-cert.pem server2-key.der server2-key.pem server3-cert.der server3-cert.pem server3-key.der server3-key.pem server4-cert.der server4-cert.pem server4-key.der server4-key.pem server5-cert.der server5-cert.pem server5-key.der server5-key.pem test-leaf-response.der test-multi-response.der test-response-nointern.der test-response-rsapss.der test-response.derp521
ca-p521-key.der ca-p521-key.pem ca-p521-priv.der ca-p521-priv.pem ca-p521.der ca-p521.pem client-p521-key.der client-p521-key.pem client-p521-priv.der client-p521-priv.pem client-p521.der client-p521.pem gen-p521-certs.sh gen-p521-keys.sh include.am root-p521-key.der root-p521-key.pem root-p521-priv.der root-p521-priv.pem root-p521.der root-p521.pem server-p521-cert.pem server-p521-key.der server-p521-key.pem server-p521-priv.der server-p521-priv.pem server-p521.der server-p521.pemrpk
client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.derrsapss
ca-3072-rsapss-key.der ca-3072-rsapss-key.pem ca-3072-rsapss-priv.der ca-3072-rsapss-priv.pem ca-3072-rsapss.der ca-3072-rsapss.pem ca-rsapss-key.der ca-rsapss-key.pem ca-rsapss-priv.der ca-rsapss-priv.pem ca-rsapss.der ca-rsapss.pem client-3072-rsapss-key.der client-3072-rsapss-key.pem client-3072-rsapss-priv.der client-3072-rsapss-priv.pem client-3072-rsapss.der client-3072-rsapss.pem client-rsapss-key.der client-rsapss-key.pem client-rsapss-priv.der client-rsapss-priv.pem client-rsapss.der client-rsapss.pem gen-rsapss-keys.sh include.am renew-rsapss-certs.sh root-3072-rsapss-key.der root-3072-rsapss-key.pem root-3072-rsapss-priv.der root-3072-rsapss-priv.pem root-3072-rsapss.der root-3072-rsapss.pem root-rsapss-key.der root-rsapss-key.pem root-rsapss-priv.der root-rsapss-priv.pem root-rsapss.der root-rsapss.pem server-3072-rsapss-cert.pem server-3072-rsapss-key.der server-3072-rsapss-key.pem server-3072-rsapss-priv.der server-3072-rsapss-priv.pem server-3072-rsapss.der server-3072-rsapss.pem server-mix-rsapss-cert.pem server-rsapss-cert.pem server-rsapss-key.der server-rsapss-key.pem server-rsapss-priv.der server-rsapss-priv.pem server-rsapss.der server-rsapss.pemslhdsa
bench_slhdsa_sha2_128f_key.der bench_slhdsa_sha2_128s_key.der bench_slhdsa_sha2_192f_key.der bench_slhdsa_sha2_192s_key.der bench_slhdsa_sha2_256f_key.der bench_slhdsa_sha2_256s_key.der bench_slhdsa_shake128f_key.der bench_slhdsa_shake128s_key.der bench_slhdsa_shake192f_key.der bench_slhdsa_shake192s_key.der bench_slhdsa_shake256f_key.der bench_slhdsa_shake256s_key.der client-mldsa44-priv.pem client-mldsa44-sha2.der client-mldsa44-sha2.pem client-mldsa44-shake.der client-mldsa44-shake.pem gen-slhdsa-mldsa-certs.sh include.am root-slhdsa-sha2-128s-priv.der root-slhdsa-sha2-128s-priv.pem root-slhdsa-sha2-128s.der root-slhdsa-sha2-128s.pem root-slhdsa-shake-128s-priv.der root-slhdsa-shake-128s-priv.pem root-slhdsa-shake-128s.der root-slhdsa-shake-128s.pem server-mldsa44-priv.pem server-mldsa44-sha2.der server-mldsa44-sha2.pem server-mldsa44-shake.der server-mldsa44-shake.pemsm2
ca-sm2-key.der ca-sm2-key.pem ca-sm2-priv.der ca-sm2-priv.pem ca-sm2.der ca-sm2.pem client-sm2-key.der client-sm2-key.pem client-sm2-priv.der client-sm2-priv.pem client-sm2.der client-sm2.pem fix_sm2_spki.py gen-sm2-certs.sh gen-sm2-keys.sh include.am root-sm2-key.der root-sm2-key.pem root-sm2-priv.der root-sm2-priv.pem root-sm2.der root-sm2.pem self-sm2-cert.pem self-sm2-key.pem self-sm2-priv.pem server-sm2-cert.der server-sm2-cert.pem server-sm2-key.der server-sm2-key.pem server-sm2-priv.der server-sm2-priv.pem server-sm2.der server-sm2.pemstatickeys
dh-ffdhe2048-params.pem dh-ffdhe2048-pub.der dh-ffdhe2048-pub.pem dh-ffdhe2048.der dh-ffdhe2048.pem ecc-secp256r1.der ecc-secp256r1.pem gen-static.sh include.am x25519-pub.der x25519-pub.pem x25519.der x25519.pemtest
catalog.txt cert-bad-neg-int.der cert-bad-oid.der cert-bad-utf8.der cert-ext-ia.cfg cert-ext-ia.der cert-ext-ia.pem cert-ext-joi.cfg cert-ext-joi.der cert-ext-joi.pem cert-ext-mnc.der cert-ext-multiple.cfg cert-ext-multiple.der cert-ext-multiple.pem cert-ext-nc-combined.der cert-ext-nc-combined.pem cert-ext-nc.cfg cert-ext-nc.der cert-ext-nc.pem cert-ext-ncdns.der cert-ext-ncdns.pem cert-ext-ncip.der cert-ext-ncip.pem cert-ext-ncmixed.der cert-ext-ncmulti.der cert-ext-ncmulti.pem cert-ext-ncrid.der cert-ext-ncrid.pem cert-ext-nct.cfg cert-ext-nct.der cert-ext-nct.pem cert-ext-ndir-exc.cfg cert-ext-ndir-exc.der cert-ext-ndir-exc.pem cert-ext-ndir.cfg cert-ext-ndir.der cert-ext-ndir.pem cert-ext-ns.der cert-over-max-altnames.cfg cert-over-max-altnames.der cert-over-max-altnames.pem cert-over-max-nc.cfg cert-over-max-nc.der cert-over-max-nc.pem client-ecc-cert-ski.hex cn-ip-literal.der cn-ip-wildcard.der crit-cert.pem crit-key.pem dh1024.der dh1024.pem dh512.der dh512.pem digsigku.pem encrypteddata.msg gen-badsig.sh gen-ext-certs.sh gen-testcerts.sh include.am kari-keyid-cms.msg ktri-keyid-cms.msg ossl-trusted-cert.pem server-badaltname.der server-badaltname.pem server-badaltnull.der server-badaltnull.pem server-badcn.der server-badcn.pem server-badcnnull.der server-badcnnull.pem server-cert-ecc-badsig.der server-cert-ecc-badsig.pem server-cert-rsa-badsig.der server-cert-rsa-badsig.pem server-duplicate-policy.pem server-garbage.der server-garbage.pem server-goodalt.der server-goodalt.pem server-goodaltwild.der server-goodaltwild.pem server-goodcn.der server-goodcn.pem server-goodcnwild.der server-goodcnwild.pem server-localhost.der server-localhost.pem smime-test-canon.p7s smime-test-multipart-badsig.p7s smime-test-multipart.p7s smime-test.p7stest-pathlen
assemble-chains.sh chainA-ICA1-key.pem chainA-ICA1-pathlen0.pem chainA-assembled.pem chainA-entity-key.pem chainA-entity.pem chainB-ICA1-key.pem chainB-ICA1-pathlen0.pem chainB-ICA2-key.pem chainB-ICA2-pathlen1.pem chainB-assembled.pem chainB-entity-key.pem chainB-entity.pem chainC-ICA1-key.pem chainC-ICA1-pathlen1.pem chainC-assembled.pem chainC-entity-key.pem chainC-entity.pem chainD-ICA1-key.pem chainD-ICA1-pathlen127.pem chainD-assembled.pem chainD-entity-key.pem chainD-entity.pem chainE-ICA1-key.pem chainE-ICA1-pathlen128.pem chainE-assembled.pem chainE-entity-key.pem chainE-entity.pem chainF-ICA1-key.pem chainF-ICA1-pathlen1.pem chainF-ICA2-key.pem chainF-ICA2-pathlen0.pem chainF-assembled.pem chainF-entity-key.pem chainF-entity.pem chainG-ICA1-key.pem chainG-ICA1-pathlen0.pem chainG-ICA2-key.pem chainG-ICA2-pathlen1.pem chainG-ICA3-key.pem chainG-ICA3-pathlen99.pem chainG-ICA4-key.pem chainG-ICA4-pathlen5.pem chainG-ICA5-key.pem chainG-ICA5-pathlen20.pem chainG-ICA6-key.pem chainG-ICA6-pathlen10.pem chainG-ICA7-key.pem chainG-ICA7-pathlen100.pem chainG-assembled.pem chainG-entity-key.pem chainG-entity.pem chainH-ICA1-key.pem chainH-ICA1-pathlen0.pem chainH-ICA2-key.pem chainH-ICA2-pathlen2.pem chainH-ICA3-key.pem chainH-ICA3-pathlen2.pem chainH-ICA4-key.pem chainH-ICA4-pathlen2.pem chainH-assembled.pem chainH-entity-key.pem chainH-entity.pem chainI-ICA1-key.pem chainI-ICA1-no_pathlen.pem chainI-ICA2-key.pem chainI-ICA2-no_pathlen.pem chainI-ICA3-key.pem chainI-ICA3-pathlen2.pem chainI-assembled.pem chainI-entity-key.pem chainI-entity.pem chainJ-ICA1-key.pem chainJ-ICA1-no_pathlen.pem chainJ-ICA2-key.pem chainJ-ICA2-no_pathlen.pem chainJ-ICA3-key.pem chainJ-ICA3-no_pathlen.pem chainJ-ICA4-key.pem chainJ-ICA4-pathlen2.pem chainJ-assembled.pem chainJ-entity-key.pem chainJ-entity.pem include.am refreshkeys.shtest-serial0
ee_normal.pem ee_serial0.pem generate_certs.sh include.am intermediate_serial0.pem root_serial0.pem root_serial0_key.pem selfsigned_nonca_serial0.pemxmss
bc_xmss_chain_ca.der bc_xmss_chain_leaf.der bc_xmss_sha2_10_256_root.der bc_xmss_sha2_16_256_root.der bc_xmssmt_sha2_20_2_256_root.der bc_xmssmt_sha2_20_4_256_root.der bc_xmssmt_sha2_40_8_256_root.der include.amcmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.indebian
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.indoc
dox_comments
header_files
aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h puf.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wc_she.h wc_slhdsa.h wolfio.hheader_files-ja
aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wolfio.hexamples
async
Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.hconfigs
README.md include.am user_settings_EBSnet.h user_settings_all.h user_settings_arduino.h user_settings_baremetal.h user_settings_ca.h user_settings_curve25519nonblock.h user_settings_dtls13.h user_settings_eccnonblock.h user_settings_espressif.h user_settings_fipsv2.h user_settings_fipsv5.h user_settings_min_ecc.h user_settings_openssl_compat.h user_settings_pkcs7.h user_settings_platformio.h user_settings_pq.h user_settings_rsa_only.h user_settings_stm32.h user_settings_template.h user_settings_tls12.h user_settings_tls13.h user_settings_wolfboot_keytools.h user_settings_wolfssh.h user_settings_wolftpm.hechoclient
echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quitlinuxkm
Kbuild Makefile README.md get_thread_size.c include.am linuxkm-fips-hash-wrapper.sh linuxkm-fips-hash.c linuxkm_memory.c linuxkm_memory.h linuxkm_wc_port.h lkcapi_aes_glue.c lkcapi_dh_glue.c lkcapi_ecdh_glue.c lkcapi_ecdsa_glue.c lkcapi_glue.c lkcapi_rsa_glue.c lkcapi_sha_glue.c module_exports.c.template module_hooks.c pie_redirect_table.c wolfcrypt.lds x86_vector_register_glue.cm4
ax_add_am_macro.m4 ax_am_jobserver.m4 ax_am_macros.m4 ax_append_compile_flags.m4 ax_append_flag.m4 ax_append_link_flags.m4 ax_append_to_file.m4 ax_atomic.m4 ax_bsdkm.m4 ax_check_compile_flag.m4 ax_check_link_flag.m4 ax_compiler_version.m4 ax_count_cpus.m4 ax_create_generic_config.m4 ax_debug.m4 ax_file_escapes.m4 ax_harden_compiler_flags.m4 ax_linuxkm.m4 ax_print_to_file.m4 ax_pthread.m4 ax_require_defined.m4 ax_tls.m4 ax_vcs_checkout.m4 hexversion.m4 lib_socket_nsl.m4 visibility.m4mqx
wolfcrypt_benchmark
ReferencedRSESystems.xml wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchwolfcrypt_test
ReferencedRSESystems.xml wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchwolfssl_client
ReferencedRSESystems.xml wolfssl_client_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchscripts
aria-cmake-build-test.sh asn1_oid_sum.pl benchmark.test benchmark_compare.sh cleanup_testfiles.sh crl-gen-openssl.test crl-revoked.test dertoc.pl dtls.test dtlscid.test external.test google.test include.am makedistsmall.sh memtest.sh ocsp-responder-openssl-interop.test ocsp-stapling-with-ca-as-responder.test ocsp-stapling-with-wolfssl-responder.test ocsp-stapling.test ocsp-stapling2.test ocsp-stapling_tls13multi.test ocsp.test openssl.test openssl_srtp.test pem.test ping.test pkcallbacks.test psk.test resume.test rsapss.test sniffer-gen.sh sniffer-ipv6.pcap sniffer-static-rsa.pcap sniffer-testsuite.test sniffer-tls12-keylog.out sniffer-tls12-keylog.pcap sniffer-tls12-keylog.sslkeylog sniffer-tls13-dh-resume.pcap sniffer-tls13-dh.pcap sniffer-tls13-ecc-resume.pcap sniffer-tls13-ecc.pcap sniffer-tls13-hrr.pcap sniffer-tls13-keylog.out sniffer-tls13-keylog.pcap sniffer-tls13-keylog.sslkeylog sniffer-tls13-x25519-resume.pcap sniffer-tls13-x25519.pcap stm32l4-v4_0_1_build.sh tls13.test trusted_peer.test unit.test.in user_settings_asm.shsrc
bio.c conf.c crl.c dtls.c dtls13.c include.am internal.c keys.c ocsp.c pk.c pk_ec.c pk_rsa.c quic.c sniffer.c ssl.c ssl_api_cert.c ssl_api_crl_ocsp.c ssl_api_pk.c ssl_asn1.c ssl_bn.c ssl_certman.c ssl_crypto.c ssl_ech.c ssl_load.c ssl_misc.c ssl_p7p12.c ssl_sess.c ssl_sk.c tls.c tls13.c wolfio.c x509.c x509_str.ctests
api
api.h api_decl.h create_ocsp_test_blobs.py include.am test_aes.c test_aes.h test_arc4.c test_arc4.h test_ascon.c test_ascon.h test_ascon_kats.h test_asn.c test_asn.h test_blake2.c test_blake2.h test_camellia.c test_camellia.h test_certman.c test_certman.h test_chacha.c test_chacha.h test_chacha20_poly1305.c test_chacha20_poly1305.h test_cmac.c test_cmac.h test_curve25519.c test_curve25519.h test_curve448.c test_curve448.h test_des3.c test_des3.h test_dh.c test_dh.h test_digest.h test_dsa.c test_dsa.h test_dtls.c test_dtls.h test_ecc.c test_ecc.h test_ed25519.c test_ed25519.h test_ed448.c test_ed448.h test_evp.c test_evp.h test_evp_cipher.c test_evp_cipher.h test_evp_digest.c test_evp_digest.h test_evp_pkey.c test_evp_pkey.h test_hash.c test_hash.h test_hmac.c test_hmac.h test_md2.c test_md2.h test_md4.c test_md4.h test_md5.c test_md5.h test_mldsa.c test_mldsa.h test_mlkem.c test_mlkem.h test_ocsp.c test_ocsp.h test_ocsp_test_blobs.h test_ossl_asn1.c test_ossl_asn1.h test_ossl_bio.c test_ossl_bio.h test_ossl_bn.c test_ossl_bn.h test_ossl_cipher.c test_ossl_cipher.h test_ossl_dgst.c test_ossl_dgst.h test_ossl_dh.c test_ossl_dh.h test_ossl_dsa.c test_ossl_dsa.h test_ossl_ec.c test_ossl_ec.h test_ossl_ecx.c test_ossl_ecx.h test_ossl_mac.c test_ossl_mac.h test_ossl_obj.c test_ossl_obj.h test_ossl_p7p12.c test_ossl_p7p12.h test_ossl_pem.c test_ossl_pem.h test_ossl_rand.c test_ossl_rand.h test_ossl_rsa.c test_ossl_rsa.h test_ossl_sk.c test_ossl_sk.h test_ossl_x509.c test_ossl_x509.h test_ossl_x509_acert.c test_ossl_x509_acert.h test_ossl_x509_crypto.c test_ossl_x509_crypto.h test_ossl_x509_ext.c test_ossl_x509_ext.h test_ossl_x509_info.c test_ossl_x509_info.h test_ossl_x509_io.c test_ossl_x509_io.h test_ossl_x509_lu.c test_ossl_x509_lu.h test_ossl_x509_name.c test_ossl_x509_name.h test_ossl_x509_pk.c test_ossl_x509_pk.h test_ossl_x509_str.c test_ossl_x509_str.h test_ossl_x509_vp.c test_ossl_x509_vp.h test_pkcs12.c test_pkcs12.h test_pkcs7.c test_pkcs7.h test_poly1305.c test_poly1305.h test_random.c test_random.h test_rc2.c test_rc2.h test_ripemd.c test_ripemd.h test_rsa.c test_rsa.h test_sha.c test_sha.h test_sha256.c test_sha256.h test_sha3.c test_sha3.h test_sha512.c test_sha512.h test_she.c test_she.h test_signature.c test_signature.h test_slhdsa.c test_slhdsa.h test_sm2.c test_sm2.h test_sm3.c test_sm3.h test_sm4.c test_sm4.h test_tls.c test_tls.h test_tls13.c test_tls13.h test_tls_ext.c test_tls_ext.h test_wc_encrypt.c test_wc_encrypt.h test_wolfmath.c test_wolfmath.h test_x509.c test_x509.hwolfcrypt
benchmark
README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.amsrc
port
Espressif
esp_crt_bundle
README.md cacrt_all.pem cacrt_deprecated.pem cacrt_local.pem esp_crt_bundle.c gen_crt_bundle.py pio_install_cryptography.pyRenesas
README.md renesas_common.c renesas_fspsm_aes.c renesas_fspsm_rsa.c renesas_fspsm_sha.c renesas_fspsm_util.c renesas_rx64_hw_sha.c renesas_rx64_hw_util.c renesas_tsip_aes.c renesas_tsip_rsa.c renesas_tsip_sha.c renesas_tsip_util.carm
armv8-32-aes-asm.S armv8-32-aes-asm_c.c armv8-32-chacha-asm.S armv8-32-chacha-asm_c.c armv8-32-curve25519.S armv8-32-curve25519_c.c armv8-32-mlkem-asm.S armv8-32-mlkem-asm_c.c armv8-32-poly1305-asm.S armv8-32-poly1305-asm_c.c armv8-32-sha256-asm.S armv8-32-sha256-asm_c.c armv8-32-sha3-asm.S armv8-32-sha3-asm_c.c armv8-32-sha512-asm.S armv8-32-sha512-asm_c.c armv8-aes-asm.S armv8-aes-asm_c.c armv8-aes.c armv8-chacha-asm.S armv8-chacha-asm_c.c armv8-curve25519.S armv8-curve25519_c.c armv8-mlkem-asm.S armv8-mlkem-asm_c.c armv8-poly1305-asm.S armv8-poly1305-asm_c.c armv8-sha256-asm.S armv8-sha256-asm_c.c armv8-sha256.c armv8-sha3-asm.S armv8-sha3-asm_c.c armv8-sha512-asm.S armv8-sha512-asm_c.c armv8-sha512.c cryptoCell.c cryptoCellHash.c thumb2-aes-asm.S thumb2-aes-asm_c.c thumb2-chacha-asm.S thumb2-chacha-asm_c.c thumb2-curve25519.S thumb2-curve25519_c.c thumb2-mlkem-asm.S thumb2-mlkem-asm_c.c thumb2-poly1305-asm.S thumb2-poly1305-asm_c.c thumb2-sha256-asm.S thumb2-sha256-asm_c.c thumb2-sha3-asm.S thumb2-sha3-asm_c.c thumb2-sha512-asm.S thumb2-sha512-asm_c.ccaam
README.md caam_aes.c caam_doc.pdf caam_driver.c caam_error.c caam_integrity.c caam_qnx.c caam_sha.c wolfcaam_aes.c wolfcaam_cmac.c wolfcaam_ecdsa.c wolfcaam_fsl_nxp.c wolfcaam_hash.c wolfcaam_hmac.c wolfcaam_init.c wolfcaam_qnx.c wolfcaam_rsa.c wolfcaam_seco.c wolfcaam_x25519.cdevcrypto
README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.criscv
riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.cwolfssl
openssl
aes.h asn1.h asn1t.h bio.h bn.h buffer.h camellia.h cmac.h cms.h compat_types.h conf.h crypto.h des.h dh.h dsa.h ec.h ec25519.h ec448.h ecdh.h ecdsa.h ed25519.h ed448.h engine.h err.h evp.h fips_rand.h hmac.h include.am kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pkcs12.h pkcs7.h rand.h rc4.h ripemd.h rsa.h safestack.h sha.h sha3.h srp.h ssl.h ssl23.h stack.h tls1.h txt_db.h ui.h x509.h x509_vfy.h x509v3.hwolfcrypt
port
Renesas
renesas-fspsm-crypt.h renesas-fspsm-types.h renesas-rx64-hw-crypt.h renesas-tsip-crypt.h renesas_cmn.h renesas_fspsm_internal.h renesas_sync.h renesas_tsip_internal.h renesas_tsip_types.hcaam
caam_driver.h caam_error.h caam_qnx.h wolfcaam.h wolfcaam_aes.h wolfcaam_cmac.h wolfcaam_ecdsa.h wolfcaam_fsl_nxp.h wolfcaam_hash.h wolfcaam_qnx.h wolfcaam_rsa.h wolfcaam_seco.h wolfcaam_sha.h wolfcaam_x25519.hwrapper
Ada
examples
src
aes_verify_main.adb rsa_verify_main.adb sha256_main.adb spark_sockets.adb spark_sockets.ads spark_terminal.adb spark_terminal.ads tls_client.adb tls_client.ads tls_client_main.adb tls_server.adb tls_server.ads tls_server_main.adbtests
src
aes_bindings_tests.adb aes_bindings_tests.ads rsa_verify_bindings_tests.adb rsa_verify_bindings_tests.ads sha256_bindings_tests.adb sha256_bindings_tests.ads tests.adbCSharp
wolfSSL-Example-IOCallbacks
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csprojwolfSSL-TLS-ServerThreaded
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csprojrust
wolfssl-wolfcrypt
src
aes.rs blake2.rs chacha20_poly1305.rs cmac.rs cmac_mac.rs curve25519.rs dh.rs dilithium.rs ecc.rs ecdsa.rs ed25519.rs ed448.rs fips.rs hkdf.rs hmac.rs hmac_mac.rs kdf.rs lib.rs lms.rs mlkem.rs mlkem_kem.rs pbkdf2_password_hash.rs prf.rs random.rs rsa.rs rsa_pkcs1v15.rs sha.rs sha_digest.rs sys.rstests
test_aes.rs test_blake2.rs test_chacha20_poly1305.rs test_cmac.rs test_cmac_mac.rs test_curve25519.rs test_dh.rs test_dilithium.rs test_ecc.rs test_ecdsa.rs test_ed25519.rs test_ed448.rs test_hkdf.rs test_hmac.rs test_hmac_mac.rs test_kdf.rs test_lms.rs test_mlkem.rs test_mlkem_kem.rs test_pbkdf2_password_hash.rs test_prf.rs test_random.rs test_rsa.rs test_rsa_pkcs1v15.rs test_sha.rs test_sha_digest.rs test_wolfcrypt.rszephyr
samples
wolfssl_benchmark
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.confwolfssl_test
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl/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 */