cjson
.github
workflows CI.yml ci-fuzz.yml
CONTRIBUTING.md
fuzzing
inputs test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9
.gitignore CMakeLists.txt afl-prepare-linux.sh afl.c afl.sh cjson_read_fuzzer.c fuzz_main.c json.dict ossfuzz.sh
library_config cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmake
tests
inputs test1 test1.expected test10 test10.expected test11 test11.expected test2 test2.expected test3 test3.expected test4 test4.expected test5 test5.expected test6 test7 test7.expected test8 test8.expected test9 test9.expected
json-patch-tests .editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.json
unity
auto colour_prompt.rb colour_reporter.rb generate_config.yml generate_module.rb generate_test_runner.rb parse_output.rb stylize_as_junit.rb test_file_filter.rb type_sanitizer.rb unity_test_summary.py unity_test_summary.rb unity_to_junit.py
docs ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txt
examples
example_1
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_2
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
makefile readme.txt
example_3
helper UnityHelper.c UnityHelper.h
src ProductionCode.c ProductionCode.h ProductionCode2.c ProductionCode2.h
rakefile.rb rakefile_helper.rb readme.txt target_gcc_32.yml
unity_config.h
extras
eclipse error_parsers.txt
fixture
src unity_fixture.c unity_fixture.h unity_fixture_internals.h unity_fixture_malloc_overrides.h
rakefile.rb rakefile_helper.rb readme.txt
release build.info version.info
src unity.c unity.h unity_internals.h
.gitattributes .gitignore .travis.yml README.md
CMakeLists.txt cjson_add.c common.h compare_tests.c json_patch_tests.c minify_tests.c misc_tests.c misc_utils_tests.c old_utils_tests.c parse_array.c parse_examples.c parse_hex4.c parse_number.c parse_object.c parse_string.c parse_value.c parse_with_opts.c print_array.c print_number.c print_object.c print_string.c print_value.c readme_examples.c unity_setup.c
.editorconfig .gitattributes .gitignore .travis.yml CHANGELOG.md CMakeLists.txt CONTRIBUTORS.md LICENSE Makefile README.md SECURITY.md appveyor.yml cJSON.c cJSON.h cJSON_Utils.c cJSON_Utils.h test.c valgrind.supp
curl
.circleci config.yml
.github
ISSUE_TEMPLATE bug_report.yml config.yml docs.yml
scripts cleancmd.pl cmp-config.pl cmp-pkg-config.sh codespell-ignore.words codespell.sh distfiles.sh pyspelling.words pyspelling.yaml randcurl.pl requirements-docs.txt requirements-proselint.txt requirements.txt shellcheck-ci.sh shellcheck.sh spellcheck.curl trimmarkdownheader.pl typos.sh typos.toml verify-examples.pl verify-synopsis.pl yamlcheck.sh yamlcheck.yaml
workflows appveyor-status.yml checkdocs.yml checksrc.yml checkurls.yml codeql.yml configure-vs-cmake.yml curl-for-win.yml distcheck.yml fuzz.yml http3-linux.yml label.yml linux-old.yml linux.yml macos.yml non-native.yml windows.yml
CODEOWNERS CONTRIBUTING.md FUNDING.yml dependabot.yml labeler.yml lock.yml stale.yml
CMake CurlSymbolHiding.cmake CurlTests.c FindBrotli.cmake FindCares.cmake FindGSS.cmake FindGnuTLS.cmake FindLDAP.cmake FindLibbacktrace.cmake FindLibgsasl.cmake FindLibidn2.cmake FindLibpsl.cmake FindLibssh.cmake FindLibssh2.cmake FindLibuv.cmake FindMbedTLS.cmake FindNGHTTP2.cmake FindNGHTTP3.cmake FindNGTCP2.cmake FindNettle.cmake FindQuiche.cmake FindRustls.cmake FindWolfSSL.cmake FindZstd.cmake Macros.cmake OtherTests.cmake PickyWarnings.cmake Utilities.cmake cmake_uninstall.in.cmake curl-config.in.cmake unix-cache.cmake win32-cache.cmake
LICENSES BSD-4-Clause-UC.txt ISC.txt curl.txt
docs
cmdline-opts .gitignore CMakeLists.txt MANPAGE.md Makefile.am Makefile.inc _AUTHORS.md _BUGS.md _DESCRIPTION.md _ENVIRONMENT.md _EXITCODES.md _FILES.md _GLOBBING.md _NAME.md _OPTIONS.md _OUTPUT.md _PROGRESS.md _PROTOCOLS.md _PROXYPREFIX.md _SEEALSO.md _SYNOPSIS.md _URL.md _VARIABLES.md _VERSION.md _WWW.md abstract-unix-socket.md alt-svc.md anyauth.md append.md aws-sigv4.md basic.md ca-native.md cacert.md capath.md cert-status.md cert-type.md cert.md ciphers.md compressed-ssh.md compressed.md config.md connect-timeout.md connect-to.md continue-at.md cookie-jar.md cookie.md create-dirs.md create-file-mode.md crlf.md crlfile.md curves.md data-ascii.md data-binary.md data-raw.md data-urlencode.md data.md delegation.md digest.md disable-eprt.md disable-epsv.md disable.md disallow-username-in-url.md dns-interface.md dns-ipv4-addr.md dns-ipv6-addr.md dns-servers.md doh-cert-status.md doh-insecure.md doh-url.md dump-ca-embed.md dump-header.md ech.md egd-file.md engine.md etag-compare.md etag-save.md expect100-timeout.md fail-early.md fail-with-body.md fail.md false-start.md follow.md form-escape.md form-string.md form.md ftp-account.md ftp-alternative-to-user.md ftp-create-dirs.md ftp-method.md ftp-pasv.md ftp-port.md ftp-pret.md ftp-skip-pasv-ip.md ftp-ssl-ccc-mode.md ftp-ssl-ccc.md ftp-ssl-control.md get.md globoff.md happy-eyeballs-timeout-ms.md haproxy-clientip.md haproxy-protocol.md head.md header.md help.md hostpubmd5.md hostpubsha256.md hsts.md http0.9.md http1.0.md http1.1.md http2-prior-knowledge.md http2.md http3-only.md http3.md ignore-content-length.md insecure.md interface.md ip-tos.md ipfs-gateway.md ipv4.md ipv6.md json.md junk-session-cookies.md keepalive-cnt.md keepalive-time.md key-type.md key.md knownhosts.md krb.md libcurl.md limit-rate.md list-only.md local-port.md location-trusted.md location.md login-options.md mail-auth.md mail-from.md mail-rcpt-allowfails.md mail-rcpt.md mainpage.idx manual.md max-filesize.md max-redirs.md max-time.md metalink.md mptcp.md negotiate.md netrc-file.md netrc-optional.md netrc.md next.md no-alpn.md no-buffer.md no-clobber.md no-keepalive.md no-npn.md no-progress-meter.md no-sessionid.md noproxy.md ntlm-wb.md ntlm.md oauth2-bearer.md out-null.md output-dir.md output.md parallel-immediate.md parallel-max-host.md parallel-max.md parallel.md pass.md path-as-is.md pinnedpubkey.md post301.md post302.md post303.md preproxy.md progress-bar.md proto-default.md proto-redir.md proto.md proxy-anyauth.md proxy-basic.md proxy-ca-native.md proxy-cacert.md proxy-capath.md proxy-cert-type.md proxy-cert.md proxy-ciphers.md proxy-crlfile.md proxy-digest.md proxy-header.md proxy-http2.md proxy-insecure.md proxy-key-type.md proxy-key.md proxy-negotiate.md proxy-ntlm.md proxy-pass.md proxy-pinnedpubkey.md proxy-service-name.md proxy-ssl-allow-beast.md proxy-ssl-auto-client-cert.md proxy-tls13-ciphers.md proxy-tlsauthtype.md proxy-tlspassword.md proxy-tlsuser.md proxy-tlsv1.md proxy-user.md proxy.md proxy1.0.md proxytunnel.md pubkey.md quote.md random-file.md range.md rate.md raw.md referer.md remote-header-name.md remote-name-all.md remote-name.md remote-time.md remove-on-error.md request-target.md request.md resolve.md retry-all-errors.md retry-connrefused.md retry-delay.md retry-max-time.md retry.md sasl-authzid.md sasl-ir.md service-name.md show-error.md show-headers.md sigalgs.md silent.md skip-existing.md socks4.md socks4a.md socks5-basic.md socks5-gssapi-nec.md socks5-gssapi-service.md socks5-gssapi.md socks5-hostname.md socks5.md speed-limit.md speed-time.md ssl-allow-beast.md ssl-auto-client-cert.md ssl-no-revoke.md ssl-reqd.md ssl-revoke-best-effort.md ssl-sessions.md ssl.md sslv2.md sslv3.md stderr.md styled-output.md suppress-connect-headers.md tcp-fastopen.md tcp-nodelay.md telnet-option.md tftp-blksize.md tftp-no-options.md time-cond.md tls-earlydata.md tls-max.md tls13-ciphers.md tlsauthtype.md tlspassword.md tlsuser.md tlsv1.0.md tlsv1.1.md tlsv1.2.md tlsv1.3.md tlsv1.md tr-encoding.md trace-ascii.md trace-config.md trace-ids.md trace-time.md trace.md unix-socket.md upload-file.md upload-flags.md url-query.md url.md use-ascii.md user-agent.md user.md variable.md verbose.md version.md vlan-priority.md write-out.md xattr.md
examples .checksrc .gitignore 10-at-a-time.c CMakeLists.txt Makefile.am Makefile.example Makefile.inc README.md adddocsref.pl address-scope.c altsvc.c anyauthput.c block_ip.c cacertinmem.c certinfo.c chkspeed.c connect-to.c cookie_interface.c crawler.c debug.c default-scheme.c ephiperfifo.c evhiperfifo.c externalsocket.c fileupload.c ftp-delete.c ftp-wildcard.c ftpget.c ftpgetinfo.c ftpgetresp.c ftpsget.c ftpupload.c ftpuploadfrommem.c ftpuploadresume.c getinfo.c getinmemory.c getredirect.c getreferrer.c ghiper.c headerapi.c hiperfifo.c hsts-preload.c htmltidy.c htmltitle.cpp http-options.c http-post.c http2-download.c http2-pushinmemory.c http2-serverpush.c http2-upload.c http3-present.c http3.c httpcustomheader.c httpput-postfields.c httpput.c https.c imap-append.c imap-authzid.c imap-copy.c imap-create.c imap-delete.c imap-examine.c imap-fetch.c imap-list.c imap-lsub.c imap-multi.c imap-noop.c imap-search.c imap-ssl.c imap-store.c imap-tls.c interface.c ipv6.c keepalive.c localport.c log_failed_transfers.c maxconnects.c multi-app.c multi-debugcallback.c multi-double.c multi-event.c multi-formadd.c multi-legacy.c multi-post.c multi-single.c multi-uv.c netrc.c parseurl.c persistent.c pop3-authzid.c pop3-dele.c pop3-list.c pop3-multi.c pop3-noop.c pop3-retr.c pop3-ssl.c pop3-stat.c pop3-tls.c pop3-top.c pop3-uidl.c post-callback.c postinmemory.c postit2-formadd.c postit2.c progressfunc.c protofeats.c range.c resolve.c rtsp-options.c sendrecv.c sepheaders.c sessioninfo.c sftpget.c sftpuploadresume.c shared-connection-cache.c simple.c simplepost.c simplessl.c smooth-gtk-thread.c smtp-authzid.c smtp-expn.c smtp-mail.c smtp-mime.c smtp-multi.c smtp-ssl.c smtp-tls.c smtp-vrfy.c sslbackend.c synctime.c threaded.c unixsocket.c url2file.c urlapi.c usercertinmem.c version-check.pl websocket-cb.c websocket-updown.c websocket.c xmlstream.c
internals BUFQ.md BUFREF.md CHECKSRC.md CLIENT-READERS.md CLIENT-WRITERS.md CODE_STYLE.md CONNECTION-FILTERS.md CREDENTIALS.md CURLX.md DYNBUF.md HASH.md LLIST.md MID.md MQTT.md MULTI-EV.md NEW-PROTOCOL.md PEERS.md PORTING.md RATELIMITS.md README.md SCORECARD.md SPLAY.md STRPARSE.md THRDPOOL-AND-QUEUE.md TIME-KEEPING.md TLS-SESSIONS.md UINT_SETS.md WEBSOCKET.md
libcurl
opts CMakeLists.txt CURLINFO_ACTIVESOCKET.md CURLINFO_APPCONNECT_TIME.md CURLINFO_APPCONNECT_TIME_T.md CURLINFO_CAINFO.md CURLINFO_CAPATH.md CURLINFO_CERTINFO.md CURLINFO_CONDITION_UNMET.md CURLINFO_CONNECT_TIME.md CURLINFO_CONNECT_TIME_T.md CURLINFO_CONN_ID.md CURLINFO_CONTENT_LENGTH_DOWNLOAD.md CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md CURLINFO_CONTENT_LENGTH_UPLOAD.md CURLINFO_CONTENT_LENGTH_UPLOAD_T.md CURLINFO_CONTENT_TYPE.md CURLINFO_COOKIELIST.md CURLINFO_EARLYDATA_SENT_T.md CURLINFO_EFFECTIVE_METHOD.md CURLINFO_EFFECTIVE_URL.md CURLINFO_FILETIME.md CURLINFO_FILETIME_T.md CURLINFO_FTP_ENTRY_PATH.md CURLINFO_HEADER_SIZE.md CURLINFO_HTTPAUTH_AVAIL.md CURLINFO_HTTPAUTH_USED.md CURLINFO_HTTP_CONNECTCODE.md CURLINFO_HTTP_VERSION.md CURLINFO_LASTSOCKET.md CURLINFO_LOCAL_IP.md CURLINFO_LOCAL_PORT.md CURLINFO_NAMELOOKUP_TIME.md CURLINFO_NAMELOOKUP_TIME_T.md CURLINFO_NUM_CONNECTS.md CURLINFO_OS_ERRNO.md CURLINFO_POSTTRANSFER_TIME_T.md CURLINFO_PRETRANSFER_TIME.md CURLINFO_PRETRANSFER_TIME_T.md CURLINFO_PRIMARY_IP.md CURLINFO_PRIMARY_PORT.md CURLINFO_PRIVATE.md CURLINFO_PROTOCOL.md CURLINFO_PROXYAUTH_AVAIL.md CURLINFO_PROXYAUTH_USED.md CURLINFO_PROXY_ERROR.md CURLINFO_PROXY_SSL_VERIFYRESULT.md CURLINFO_QUEUE_TIME_T.md CURLINFO_REDIRECT_COUNT.md CURLINFO_REDIRECT_TIME.md CURLINFO_REDIRECT_TIME_T.md CURLINFO_REDIRECT_URL.md CURLINFO_REFERER.md CURLINFO_REQUEST_SIZE.md CURLINFO_RESPONSE_CODE.md CURLINFO_RETRY_AFTER.md CURLINFO_RTSP_CLIENT_CSEQ.md CURLINFO_RTSP_CSEQ_RECV.md CURLINFO_RTSP_SERVER_CSEQ.md CURLINFO_RTSP_SESSION_ID.md CURLINFO_SCHEME.md CURLINFO_SIZE_DELIVERED.md CURLINFO_SIZE_DOWNLOAD.md CURLINFO_SIZE_DOWNLOAD_T.md CURLINFO_SIZE_UPLOAD.md CURLINFO_SIZE_UPLOAD_T.md CURLINFO_SPEED_DOWNLOAD.md CURLINFO_SPEED_DOWNLOAD_T.md CURLINFO_SPEED_UPLOAD.md CURLINFO_SPEED_UPLOAD_T.md CURLINFO_SSL_ENGINES.md CURLINFO_SSL_VERIFYRESULT.md CURLINFO_STARTTRANSFER_TIME.md CURLINFO_STARTTRANSFER_TIME_T.md CURLINFO_TLS_SESSION.md CURLINFO_TLS_SSL_PTR.md CURLINFO_TOTAL_TIME.md CURLINFO_TOTAL_TIME_T.md CURLINFO_USED_PROXY.md CURLINFO_XFER_ID.md CURLMINFO_XFERS_ADDED.md CURLMINFO_XFERS_CURRENT.md CURLMINFO_XFERS_DONE.md CURLMINFO_XFERS_PENDING.md CURLMINFO_XFERS_RUNNING.md CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.md CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.md CURLMOPT_MAXCONNECTS.md CURLMOPT_MAX_CONCURRENT_STREAMS.md CURLMOPT_MAX_HOST_CONNECTIONS.md CURLMOPT_MAX_PIPELINE_LENGTH.md CURLMOPT_MAX_TOTAL_CONNECTIONS.md CURLMOPT_NETWORK_CHANGED.md CURLMOPT_NOTIFYDATA.md CURLMOPT_NOTIFYFUNCTION.md CURLMOPT_PIPELINING.md CURLMOPT_PIPELINING_SERVER_BL.md CURLMOPT_PIPELINING_SITE_BL.md CURLMOPT_PUSHDATA.md CURLMOPT_PUSHFUNCTION.md CURLMOPT_QUICK_EXIT.md CURLMOPT_RESOLVE_THREADS_MAX.md CURLMOPT_SOCKETDATA.md CURLMOPT_SOCKETFUNCTION.md CURLMOPT_TIMERDATA.md CURLMOPT_TIMERFUNCTION.md CURLOPT_ABSTRACT_UNIX_SOCKET.md CURLOPT_ACCEPTTIMEOUT_MS.md CURLOPT_ACCEPT_ENCODING.md CURLOPT_ADDRESS_SCOPE.md CURLOPT_ALTSVC.md CURLOPT_ALTSVC_CTRL.md CURLOPT_APPEND.md CURLOPT_AUTOREFERER.md CURLOPT_AWS_SIGV4.md CURLOPT_BUFFERSIZE.md CURLOPT_CAINFO.md CURLOPT_CAINFO_BLOB.md CURLOPT_CAPATH.md CURLOPT_CA_CACHE_TIMEOUT.md CURLOPT_CERTINFO.md CURLOPT_CHUNK_BGN_FUNCTION.md CURLOPT_CHUNK_DATA.md CURLOPT_CHUNK_END_FUNCTION.md CURLOPT_CLOSESOCKETDATA.md CURLOPT_CLOSESOCKETFUNCTION.md CURLOPT_CONNECTTIMEOUT.md CURLOPT_CONNECTTIMEOUT_MS.md CURLOPT_CONNECT_ONLY.md CURLOPT_CONNECT_TO.md CURLOPT_CONV_FROM_NETWORK_FUNCTION.md CURLOPT_CONV_FROM_UTF8_FUNCTION.md CURLOPT_CONV_TO_NETWORK_FUNCTION.md CURLOPT_COOKIE.md CURLOPT_COOKIEFILE.md CURLOPT_COOKIEJAR.md CURLOPT_COOKIELIST.md CURLOPT_COOKIESESSION.md CURLOPT_COPYPOSTFIELDS.md CURLOPT_CRLF.md CURLOPT_CRLFILE.md CURLOPT_CURLU.md CURLOPT_CUSTOMREQUEST.md CURLOPT_DEBUGDATA.md CURLOPT_DEBUGFUNCTION.md CURLOPT_DEFAULT_PROTOCOL.md CURLOPT_DIRLISTONLY.md CURLOPT_DISALLOW_USERNAME_IN_URL.md CURLOPT_DNS_CACHE_TIMEOUT.md CURLOPT_DNS_INTERFACE.md CURLOPT_DNS_LOCAL_IP4.md CURLOPT_DNS_LOCAL_IP6.md CURLOPT_DNS_SERVERS.md CURLOPT_DNS_SHUFFLE_ADDRESSES.md CURLOPT_DNS_USE_GLOBAL_CACHE.md CURLOPT_DOH_SSL_VERIFYHOST.md CURLOPT_DOH_SSL_VERIFYPEER.md CURLOPT_DOH_SSL_VERIFYSTATUS.md CURLOPT_DOH_URL.md CURLOPT_ECH.md CURLOPT_EGDSOCKET.md CURLOPT_ERRORBUFFER.md CURLOPT_EXPECT_100_TIMEOUT_MS.md CURLOPT_FAILONERROR.md CURLOPT_FILETIME.md CURLOPT_FNMATCH_DATA.md CURLOPT_FNMATCH_FUNCTION.md CURLOPT_FOLLOWLOCATION.md CURLOPT_FORBID_REUSE.md CURLOPT_FRESH_CONNECT.md CURLOPT_FTPPORT.md CURLOPT_FTPSSLAUTH.md CURLOPT_FTP_ACCOUNT.md CURLOPT_FTP_ALTERNATIVE_TO_USER.md CURLOPT_FTP_CREATE_MISSING_DIRS.md CURLOPT_FTP_FILEMETHOD.md CURLOPT_FTP_SKIP_PASV_IP.md CURLOPT_FTP_SSL_CCC.md CURLOPT_FTP_USE_EPRT.md CURLOPT_FTP_USE_EPSV.md CURLOPT_FTP_USE_PRET.md CURLOPT_GSSAPI_DELEGATION.md CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.md CURLOPT_HAPROXYPROTOCOL.md CURLOPT_HAPROXY_CLIENT_IP.md CURLOPT_HEADER.md CURLOPT_HEADERDATA.md CURLOPT_HEADERFUNCTION.md CURLOPT_HEADEROPT.md CURLOPT_HSTS.md CURLOPT_HSTSREADDATA.md CURLOPT_HSTSREADFUNCTION.md CURLOPT_HSTSWRITEDATA.md CURLOPT_HSTSWRITEFUNCTION.md CURLOPT_HSTS_CTRL.md CURLOPT_HTTP09_ALLOWED.md CURLOPT_HTTP200ALIASES.md CURLOPT_HTTPAUTH.md CURLOPT_HTTPGET.md CURLOPT_HTTPHEADER.md CURLOPT_HTTPPOST.md CURLOPT_HTTPPROXYTUNNEL.md CURLOPT_HTTP_CONTENT_DECODING.md CURLOPT_HTTP_TRANSFER_DECODING.md CURLOPT_HTTP_VERSION.md CURLOPT_IGNORE_CONTENT_LENGTH.md CURLOPT_INFILESIZE.md CURLOPT_INFILESIZE_LARGE.md CURLOPT_INTERFACE.md CURLOPT_INTERLEAVEDATA.md CURLOPT_INTERLEAVEFUNCTION.md CURLOPT_IOCTLDATA.md CURLOPT_IOCTLFUNCTION.md CURLOPT_IPRESOLVE.md CURLOPT_ISSUERCERT.md CURLOPT_ISSUERCERT_BLOB.md CURLOPT_KEEP_SENDING_ON_ERROR.md CURLOPT_KEYPASSWD.md CURLOPT_KRBLEVEL.md CURLOPT_LOCALPORT.md CURLOPT_LOCALPORTRANGE.md CURLOPT_LOGIN_OPTIONS.md CURLOPT_LOW_SPEED_LIMIT.md CURLOPT_LOW_SPEED_TIME.md CURLOPT_MAIL_AUTH.md CURLOPT_MAIL_FROM.md CURLOPT_MAIL_RCPT.md CURLOPT_MAIL_RCPT_ALLOWFAILS.md CURLOPT_MAXAGE_CONN.md CURLOPT_MAXCONNECTS.md CURLOPT_MAXFILESIZE.md CURLOPT_MAXFILESIZE_LARGE.md CURLOPT_MAXLIFETIME_CONN.md CURLOPT_MAXREDIRS.md CURLOPT_MAX_RECV_SPEED_LARGE.md CURLOPT_MAX_SEND_SPEED_LARGE.md CURLOPT_MIMEPOST.md CURLOPT_MIME_OPTIONS.md CURLOPT_NETRC.md CURLOPT_NETRC_FILE.md CURLOPT_NEW_DIRECTORY_PERMS.md CURLOPT_NEW_FILE_PERMS.md CURLOPT_NOBODY.md CURLOPT_NOPROGRESS.md CURLOPT_NOPROXY.md CURLOPT_NOSIGNAL.md CURLOPT_OPENSOCKETDATA.md CURLOPT_OPENSOCKETFUNCTION.md CURLOPT_PASSWORD.md CURLOPT_PATH_AS_IS.md CURLOPT_PINNEDPUBLICKEY.md CURLOPT_PIPEWAIT.md CURLOPT_PORT.md CURLOPT_POST.md CURLOPT_POSTFIELDS.md CURLOPT_POSTFIELDSIZE.md CURLOPT_POSTFIELDSIZE_LARGE.md CURLOPT_POSTQUOTE.md CURLOPT_POSTREDIR.md CURLOPT_PREQUOTE.md CURLOPT_PREREQDATA.md CURLOPT_PREREQFUNCTION.md CURLOPT_PRE_PROXY.md CURLOPT_PRIVATE.md CURLOPT_PROGRESSDATA.md CURLOPT_PROGRESSFUNCTION.md CURLOPT_PROTOCOLS.md CURLOPT_PROTOCOLS_STR.md CURLOPT_PROXY.md CURLOPT_PROXYAUTH.md CURLOPT_PROXYHEADER.md CURLOPT_PROXYPASSWORD.md CURLOPT_PROXYPORT.md CURLOPT_PROXYTYPE.md CURLOPT_PROXYUSERNAME.md CURLOPT_PROXYUSERPWD.md CURLOPT_PROXY_CAINFO.md CURLOPT_PROXY_CAINFO_BLOB.md CURLOPT_PROXY_CAPATH.md CURLOPT_PROXY_CRLFILE.md CURLOPT_PROXY_ISSUERCERT.md CURLOPT_PROXY_ISSUERCERT_BLOB.md CURLOPT_PROXY_KEYPASSWD.md CURLOPT_PROXY_PINNEDPUBLICKEY.md CURLOPT_PROXY_SERVICE_NAME.md CURLOPT_PROXY_SSLCERT.md CURLOPT_PROXY_SSLCERTTYPE.md CURLOPT_PROXY_SSLCERT_BLOB.md CURLOPT_PROXY_SSLKEY.md CURLOPT_PROXY_SSLKEYTYPE.md CURLOPT_PROXY_SSLKEY_BLOB.md CURLOPT_PROXY_SSLVERSION.md CURLOPT_PROXY_SSL_CIPHER_LIST.md CURLOPT_PROXY_SSL_OPTIONS.md CURLOPT_PROXY_SSL_VERIFYHOST.md CURLOPT_PROXY_SSL_VERIFYPEER.md CURLOPT_PROXY_TLS13_CIPHERS.md CURLOPT_PROXY_TLSAUTH_PASSWORD.md CURLOPT_PROXY_TLSAUTH_TYPE.md CURLOPT_PROXY_TLSAUTH_USERNAME.md CURLOPT_PROXY_TRANSFER_MODE.md CURLOPT_PUT.md CURLOPT_QUICK_EXIT.md CURLOPT_QUOTE.md CURLOPT_RANDOM_FILE.md CURLOPT_RANGE.md CURLOPT_READDATA.md CURLOPT_READFUNCTION.md CURLOPT_REDIR_PROTOCOLS.md CURLOPT_REDIR_PROTOCOLS_STR.md CURLOPT_REFERER.md CURLOPT_REQUEST_TARGET.md CURLOPT_RESOLVE.md CURLOPT_RESOLVER_START_DATA.md CURLOPT_RESOLVER_START_FUNCTION.md CURLOPT_RESUME_FROM.md CURLOPT_RESUME_FROM_LARGE.md CURLOPT_RTSP_CLIENT_CSEQ.md CURLOPT_RTSP_REQUEST.md CURLOPT_RTSP_SERVER_CSEQ.md CURLOPT_RTSP_SESSION_ID.md CURLOPT_RTSP_STREAM_URI.md CURLOPT_RTSP_TRANSPORT.md CURLOPT_SASL_AUTHZID.md CURLOPT_SASL_IR.md CURLOPT_SEEKDATA.md CURLOPT_SEEKFUNCTION.md CURLOPT_SERVER_RESPONSE_TIMEOUT.md CURLOPT_SERVER_RESPONSE_TIMEOUT_MS.md CURLOPT_SERVICE_NAME.md CURLOPT_SHARE.md CURLOPT_SOCKOPTDATA.md CURLOPT_SOCKOPTFUNCTION.md CURLOPT_SOCKS5_AUTH.md CURLOPT_SOCKS5_GSSAPI_NEC.md CURLOPT_SOCKS5_GSSAPI_SERVICE.md CURLOPT_SSH_AUTH_TYPES.md CURLOPT_SSH_COMPRESSION.md CURLOPT_SSH_HOSTKEYDATA.md CURLOPT_SSH_HOSTKEYFUNCTION.md CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md CURLOPT_SSH_KEYDATA.md CURLOPT_SSH_KEYFUNCTION.md CURLOPT_SSH_KNOWNHOSTS.md CURLOPT_SSH_PRIVATE_KEYFILE.md CURLOPT_SSH_PUBLIC_KEYFILE.md CURLOPT_SSLCERT.md CURLOPT_SSLCERTTYPE.md CURLOPT_SSLCERT_BLOB.md CURLOPT_SSLENGINE.md CURLOPT_SSLENGINE_DEFAULT.md CURLOPT_SSLKEY.md CURLOPT_SSLKEYTYPE.md CURLOPT_SSLKEY_BLOB.md CURLOPT_SSLVERSION.md CURLOPT_SSL_CIPHER_LIST.md CURLOPT_SSL_CTX_DATA.md CURLOPT_SSL_CTX_FUNCTION.md CURLOPT_SSL_EC_CURVES.md CURLOPT_SSL_ENABLE_ALPN.md CURLOPT_SSL_ENABLE_NPN.md CURLOPT_SSL_FALSESTART.md CURLOPT_SSL_OPTIONS.md CURLOPT_SSL_SESSIONID_CACHE.md CURLOPT_SSL_SIGNATURE_ALGORITHMS.md CURLOPT_SSL_VERIFYHOST.md CURLOPT_SSL_VERIFYPEER.md CURLOPT_SSL_VERIFYSTATUS.md CURLOPT_STDERR.md CURLOPT_STREAM_DEPENDS.md CURLOPT_STREAM_DEPENDS_E.md CURLOPT_STREAM_WEIGHT.md CURLOPT_SUPPRESS_CONNECT_HEADERS.md CURLOPT_TCP_FASTOPEN.md CURLOPT_TCP_KEEPALIVE.md CURLOPT_TCP_KEEPCNT.md CURLOPT_TCP_KEEPIDLE.md CURLOPT_TCP_KEEPINTVL.md CURLOPT_TCP_NODELAY.md CURLOPT_TELNETOPTIONS.md CURLOPT_TFTP_BLKSIZE.md CURLOPT_TFTP_NO_OPTIONS.md CURLOPT_TIMECONDITION.md CURLOPT_TIMEOUT.md CURLOPT_TIMEOUT_MS.md CURLOPT_TIMEVALUE.md CURLOPT_TIMEVALUE_LARGE.md CURLOPT_TLS13_CIPHERS.md CURLOPT_TLSAUTH_PASSWORD.md CURLOPT_TLSAUTH_TYPE.md CURLOPT_TLSAUTH_USERNAME.md CURLOPT_TRAILERDATA.md CURLOPT_TRAILERFUNCTION.md CURLOPT_TRANSFERTEXT.md CURLOPT_TRANSFER_ENCODING.md CURLOPT_UNIX_SOCKET_PATH.md CURLOPT_UNRESTRICTED_AUTH.md CURLOPT_UPKEEP_INTERVAL_MS.md CURLOPT_UPLOAD.md CURLOPT_UPLOAD_BUFFERSIZE.md CURLOPT_UPLOAD_FLAGS.md CURLOPT_URL.md CURLOPT_USERAGENT.md CURLOPT_USERNAME.md CURLOPT_USERPWD.md CURLOPT_USE_SSL.md CURLOPT_VERBOSE.md CURLOPT_WILDCARDMATCH.md CURLOPT_WRITEDATA.md CURLOPT_WRITEFUNCTION.md CURLOPT_WS_OPTIONS.md CURLOPT_XFERINFODATA.md CURLOPT_XFERINFOFUNCTION.md CURLOPT_XOAUTH2_BEARER.md CURLSHOPT_LOCKFUNC.md CURLSHOPT_SHARE.md CURLSHOPT_UNLOCKFUNC.md CURLSHOPT_UNSHARE.md CURLSHOPT_USERDATA.md Makefile.am Makefile.inc
.gitignore ABI.md CMakeLists.txt Makefile.am Makefile.inc curl_easy_cleanup.md curl_easy_duphandle.md curl_easy_escape.md curl_easy_getinfo.md curl_easy_header.md curl_easy_init.md curl_easy_nextheader.md curl_easy_option_by_id.md curl_easy_option_by_name.md curl_easy_option_next.md curl_easy_pause.md curl_easy_perform.md curl_easy_recv.md curl_easy_reset.md curl_easy_send.md curl_easy_setopt.md curl_easy_ssls_export.md curl_easy_ssls_import.md curl_easy_strerror.md curl_easy_unescape.md curl_easy_upkeep.md curl_escape.md curl_formadd.md curl_formfree.md curl_formget.md curl_free.md curl_getdate.md curl_getenv.md curl_global_cleanup.md curl_global_init.md curl_global_init_mem.md curl_global_sslset.md curl_global_trace.md curl_mime_addpart.md curl_mime_data.md curl_mime_data_cb.md curl_mime_encoder.md curl_mime_filedata.md curl_mime_filename.md curl_mime_free.md curl_mime_headers.md curl_mime_init.md curl_mime_name.md curl_mime_subparts.md curl_mime_type.md curl_mprintf.md curl_multi_add_handle.md curl_multi_assign.md curl_multi_cleanup.md curl_multi_fdset.md curl_multi_get_handles.md curl_multi_get_offt.md curl_multi_info_read.md curl_multi_init.md curl_multi_notify_disable.md curl_multi_notify_enable.md curl_multi_perform.md curl_multi_poll.md curl_multi_remove_handle.md curl_multi_setopt.md curl_multi_socket.md curl_multi_socket_action.md curl_multi_socket_all.md curl_multi_strerror.md curl_multi_timeout.md curl_multi_wait.md curl_multi_waitfds.md curl_multi_wakeup.md curl_pushheader_byname.md curl_pushheader_bynum.md curl_share_cleanup.md curl_share_init.md curl_share_setopt.md curl_share_strerror.md curl_slist_append.md curl_slist_free_all.md curl_strequal.md curl_strnequal.md curl_unescape.md curl_url.md curl_url_cleanup.md curl_url_dup.md curl_url_get.md curl_url_set.md curl_url_strerror.md curl_version.md curl_version_info.md curl_ws_meta.md curl_ws_recv.md curl_ws_send.md curl_ws_start_frame.md libcurl-easy.md libcurl-env-dbg.md libcurl-env.md libcurl-errors.md libcurl-multi.md libcurl-security.md libcurl-share.md libcurl-thread.md libcurl-tutorial.md libcurl-url.md libcurl-ws.md libcurl.m4 libcurl.md mksymbolsmanpage.pl symbols-in-versions symbols.pl
tests CI.md FILEFORMAT.md HTTP.md TEST-SUITE.md
.gitignore ALTSVC.md BINDINGS.md BUG-BOUNTY.md BUGS.md CIPHERS-TLS12.md CIPHERS.md CMakeLists.txt CODE_OF_CONDUCT.md CODE_REVIEW.md CONTRIBUTE.md CURL-DISABLE.md CURLDOWN.md DEPRECATE.md DISTROS.md EARLY-RELEASE.md ECH.md EXPERIMENTAL.md FAQ.md FEATURES.md GOVERNANCE.md HELP-US.md HISTORY.md HSTS.md HTTP-COOKIES.md HTTP3.md HTTPSRR.md INFRASTRUCTURE.md INSTALL-CMAKE.md INSTALL.md INTERNALS.md IPFS.md KNOWN_BUGS.md KNOWN_RISKS.md MAIL-ETIQUETTE.md MANUAL.md Makefile.am README.md RELEASE-PROCEDURE.md ROADMAP.md RUSTLS.md SECURITY-ADVISORY.md SPONSORS.md SSL-PROBLEMS.md SSLCERTS.md THANKS THANKS-filter TODO.md TheArtOfHttpScripting.md URL-SYNTAX.md VERIFY.md VERSIONS.md VULN-DISCLOSURE-POLICY.md curl-config.md mk-ca-bundle.md options-in-versions runtests.md testcurl.md wcurl.md
include
curl Makefile.am curl.h curlver.h easy.h header.h mprintf.h multi.h options.h stdcheaders.h system.h typecheck-gcc.h urlapi.h websockets.h
Makefile.am README.md
lib
curlx base64.c base64.h basename.c basename.h dynbuf.c dynbuf.h fopen.c fopen.h inet_ntop.c inet_ntop.h inet_pton.c inet_pton.h multibyte.c multibyte.h nonblock.c nonblock.h snprintf.c snprintf.h strcopy.c strcopy.h strdup.c strdup.h strerr.c strerr.h strparse.c strparse.h timediff.c timediff.h timeval.c timeval.h version_win32.c version_win32.h wait.c wait.h warnless.c warnless.h winapi.c winapi.h
vauth cleartext.c cram.c digest.c digest.h digest_sspi.c gsasl.c krb5_gssapi.c krb5_sspi.c ntlm.c ntlm_sspi.c oauth2.c spnego_gssapi.c spnego_sspi.c vauth.c vauth.h
vquic curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.h
vssh libssh.c libssh2.c ssh.h vssh.c vssh.h
vtls apple.c apple.h cipher_suite.c cipher_suite.h gtls.c gtls.h hostcheck.c hostcheck.h keylog.c keylog.h mbedtls.c mbedtls.h openssl.c openssl.h rustls.c rustls.h schannel.c schannel.h schannel_int.h schannel_verify.c vtls.c vtls.h vtls_int.h vtls_scache.c vtls_scache.h vtls_spack.c vtls_spack.h wolfssl.c wolfssl.h x509asn1.c x509asn1.h
.gitignore CMakeLists.txt Makefile.am Makefile.inc Makefile.soname altsvc.c altsvc.h amigaos.c amigaos.h arpa_telnet.h asyn-ares.c asyn-base.c asyn-thrdd.c asyn.h bufq.c bufq.h bufref.c bufref.h cf-dns.c cf-dns.h cf-h1-proxy.c cf-h1-proxy.h cf-h2-proxy.c cf-h2-proxy.h cf-haproxy.c cf-haproxy.h cf-https-connect.c cf-https-connect.h cf-ip-happy.c cf-ip-happy.h cf-socket.c cf-socket.h cfilters.c cfilters.h config-mac.h config-os400.h config-riscos.h config-win32.h conncache.c conncache.h connect.c connect.h content_encoding.c content_encoding.h cookie.c cookie.h creds.c creds.h cshutdn.c cshutdn.h curl_addrinfo.c curl_addrinfo.h curl_config-cmake.h.in curl_ctype.h curl_endian.c curl_endian.h curl_fnmatch.c curl_fnmatch.h curl_fopen.c curl_fopen.h curl_get_line.c curl_get_line.h curl_gethostname.c curl_gethostname.h curl_gssapi.c curl_gssapi.h curl_hmac.h curl_ldap.h curl_md4.h curl_md5.h curl_memrchr.c curl_memrchr.h curl_ntlm_core.c curl_ntlm_core.h curl_printf.h curl_range.c curl_range.h curl_sasl.c curl_sasl.h curl_setup.h curl_sha256.h curl_sha512_256.c curl_sha512_256.h curl_share.c curl_share.h curl_sspi.c curl_sspi.h curl_threads.c curl_threads.h curl_trc.c curl_trc.h cw-out.c cw-out.h cw-pause.c cw-pause.h dict.c dict.h dllmain.c dnscache.c dnscache.h doh.c doh.h dynhds.c dynhds.h easy.c easy_lock.h easygetopt.c easyif.h easyoptions.c easyoptions.h escape.c escape.h fake_addrinfo.c fake_addrinfo.h file.c file.h fileinfo.c fileinfo.h formdata.c formdata.h ftp-int.h ftp.c ftp.h ftplistparser.c ftplistparser.h functypes.h getenv.c getinfo.c getinfo.h gopher.c gopher.h hash.c hash.h headers.c headers.h hmac.c hostip.c hostip.h hostip4.c hostip6.c hsts.c hsts.h http.c http.h http1.c http1.h http2.c http2.h http_aws_sigv4.c http_aws_sigv4.h http_chunks.c http_chunks.h http_digest.c http_digest.h http_negotiate.c http_negotiate.h http_ntlm.c http_ntlm.h http_proxy.c http_proxy.h httpsrr.c httpsrr.h idn.c idn.h if2ip.c if2ip.h imap.c imap.h ldap.c libcurl.def libcurl.rc libcurl.vers.in llist.c llist.h macos.c macos.h md4.c md5.c memdebug.c mime.c mime.h mprintf.c mqtt.c mqtt.h multi.c multi_ev.c multi_ev.h multi_ntfy.c multi_ntfy.h multihandle.h multiif.h netrc.c netrc.h noproxy.c noproxy.h openldap.c optiontable.pl parsedate.c parsedate.h peer.c peer.h pingpong.c pingpong.h pop3.c pop3.h progress.c progress.h protocol.c protocol.h psl.c psl.h rand.c rand.h ratelimit.c ratelimit.h request.c request.h rtsp.c rtsp.h select.c select.h sendf.c sendf.h setopt.c setopt.h setup-os400.h setup-vms.h setup-win32.h sha256.c sigpipe.h slist.c slist.h smb.c smb.h smtp.c smtp.h sockaddr.h socketpair.c socketpair.h socks.c socks.h socks_gssapi.c socks_sspi.c splay.c splay.h strcase.c strcase.h strequal.c strerror.c strerror.h system_win32.c system_win32.h telnet.c telnet.h tftp.c tftp.h thrdpool.c thrdpool.h thrdqueue.c thrdqueue.h transfer.c transfer.h uint-bset.c uint-bset.h uint-hash.c uint-hash.h uint-spbset.c uint-spbset.h uint-table.c uint-table.h url.c url.h urlapi-int.h urlapi.c urldata.h version.c ws.c ws.h
m4 .gitignore curl-amissl.m4 curl-apple-sectrust.m4 curl-compilers.m4 curl-confopts.m4 curl-functions.m4 curl-gnutls.m4 curl-mbedtls.m4 curl-openssl.m4 curl-override.m4 curl-reentrant.m4 curl-rustls.m4 curl-schannel.m4 curl-sysconfig.m4 curl-wolfssl.m4 xc-am-iface.m4 xc-cc-check.m4 xc-lt-iface.m4 xc-val-flgs.m4 zz40-xc-ovr.m4 zz50-xc-ovr.m4
projects
OS400
rpg-examples HEADERAPI HTTPPOST INMEMORY SIMPLE1 SIMPLE2 SMTPSRCMBR
.checksrc README.OS400 ccsidcurl.c ccsidcurl.h config400.default curl.cmd curl.inc.in curlcl.c curlmain.c initscript.sh make-docs.sh make-include.sh make-lib.sh make-src.sh make-tests.sh makefile.sh os400sys.c os400sys.h
Windows
tmpl .gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filters
.gitignore README.md generate.bat
vms Makefile.am backup_gnv_curl_src.com build_curl-config_script.com build_gnv_curl.com build_gnv_curl_pcsi_desc.com build_gnv_curl_pcsi_text.com build_gnv_curl_release_notes.com build_libcurl_pc.com build_vms.com clean_gnv_curl.com compare_curl_source.com config_h.com curl_crtl_init.c curl_gnv_build_steps.txt curl_release_note_start.txt curl_startup.com curlmsg.h curlmsg.msg curlmsg.sdl curlmsg_vms.h generate_config_vms_h_curl.com generate_vax_transfer.com gnv_conftest.c_first gnv_curl_configure.sh gnv_libcurl_symbols.opt gnv_link_curl.com macro32_exactcase.patch make_gnv_curl_install.sh make_pcsi_curl_kit_name.com pcsi_gnv_curl_file_list.txt pcsi_product_gnv_curl.com readme report_openssl_version.c setup_gnv_curl_build.com stage_curl_install.com vms_eco_level.h
Makefile.am README.md
scripts .checksrc CMakeLists.txt Makefile.am badwords badwords-all badwords.txt cd2cd cd2nroff cdall checksrc-all.pl checksrc.pl cmakelint.sh completion.pl contributors.sh contrithanks.sh coverage.sh delta dmaketgz extract-unit-protos firefox-db2pem.sh installcheck.sh maketgz managen mdlinkcheck mk-ca-bundle.pl mk-unity.pl nroff2cd perlcheck.sh pythonlint.sh randdisable release-notes.pl release-tools.sh schemetable.c singleuse.pl spacecheck.pl top-complexity top-length verify-release wcurl
src
toolx tool_time.c tool_time.h
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc config2setopts.c config2setopts.h curl.rc curlinfo.c mk-file-embed.pl mkhelp.pl slist_wc.c slist_wc.h terminal.c terminal.h tool_cb_dbg.c tool_cb_dbg.h tool_cb_hdr.c tool_cb_hdr.h tool_cb_prg.c tool_cb_prg.h tool_cb_rea.c tool_cb_rea.h tool_cb_see.c tool_cb_see.h tool_cb_soc.c tool_cb_soc.h tool_cb_wrt.c tool_cb_wrt.h tool_cfgable.c tool_cfgable.h tool_dirhie.c tool_dirhie.h tool_doswin.c tool_doswin.h tool_easysrc.c tool_easysrc.h tool_filetime.c tool_filetime.h tool_findfile.c tool_findfile.h tool_formparse.c tool_formparse.h tool_getparam.c tool_getparam.h tool_getpass.c tool_getpass.h tool_help.c tool_help.h tool_helpers.c tool_helpers.h tool_hugehelp.h tool_ipfs.c tool_ipfs.h tool_libinfo.c tool_libinfo.h tool_listhelp.c tool_main.c tool_main.h tool_msgs.c tool_msgs.h tool_operate.c tool_operate.h tool_operhlp.c tool_operhlp.h tool_paramhlp.c tool_paramhlp.h tool_parsecfg.c tool_parsecfg.h tool_progress.c tool_progress.h tool_sdecls.h tool_setopt.c tool_setopt.h tool_setup.h tool_ssls.c tool_ssls.h tool_stderr.c tool_stderr.h tool_urlglob.c tool_urlglob.h tool_util.c tool_util.h tool_version.h tool_vms.c tool_vms.h tool_writeout.c tool_writeout.h tool_writeout_json.c tool_writeout_json.h tool_xattr.c tool_xattr.h var.c var.h
tests
certs .gitignore CMakeLists.txt Makefile.am Makefile.inc genserv.pl srp-verifier-conf srp-verifier-db test-ca.cnf test-ca.prm test-client-cert.prm test-client-eku-only.prm test-localhost-san-first.prm test-localhost-san-last.prm test-localhost.nn.prm test-localhost.prm test-localhost0h.prm
cmake CMakeLists.txt test.c test.cpp test.sh
data .gitignore DISABLED Makefile.am data-xml1 data1400.c data1401.c data1402.c data1403.c data1404.c data1405.c data1406.c data1407.c data1420.c data1461.txt data1463.txt data1465.c data1481.c data1705-1.md data1705-2.md data1705-3.md data1705-4.md data1705-stdout.1 data1706-1.md data1706-2.md data1706-3.md data1706-4.md data1706-stdout.txt data320.html test1 test10 test100 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 test1008 test1009 test101 test1010 test1011 test1012 test1013 test1014 test1015 test1016 test1017 test1018 test1019 test102 test1020 test1021 test1022 test1023 test1024 test1025 test1026 test1027 test1028 test1029 test103 test1030 test1031 test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 test104 test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 test1048 test1049 test105 test1050 test1051 test1052 test1053 test1054 test1055 test1056 test1057 test1058 test1059 test106 test1060 test1061 test1062 test1063 test1064 test1065 test1066 test1067 test1068 test1069 test107 test1070 test1071 test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 test108 test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 test1088 test1089 test109 test1090 test1091 test1092 test1093 test1094 test1095 test1096 test1097 test1098 test1099 test11 test110 test1100 test1101 test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 test111 test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 test112 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 test1128 test1129 test113 test1130 test1131 test1132 test1133 test1134 test1135 test1136 test1137 test1138 test1139 test114 test1140 test1141 test1142 test1143 test1144 test1145 test1146 test1147 test1148 test1149 test115 test1150 test1151 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 test116 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 test1168 test1169 test117 test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 test1178 test1179 test118 test1180 test1181 test1182 test1183 test1184 test1185 test1186 test1187 test1188 test1189 test119 test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 test1199 test12 test120 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 test1208 test1209 test121 test1210 test1211 test1212 test1213 test1214 test1215 test1216 test1217 test1218 test1219 test122 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 test1228 test1229 test123 test1230 test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 test124 test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 test1248 test1249 test125 test1250 test1251 test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 test126 test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 test1268 test1269 test127 test1270 test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 test1279 test128 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 test1288 test1289 test129 test1290 test1291 test1292 test1293 test1294 test1295 test1296 test1297 test1298 test1299 test13 test130 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 test1309 test131 test1310 test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 test132 test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 test133 test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 test134 test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 test1348 test1349 test135 test1350 test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 test136 test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 test137 test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 test138 test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 test1388 test1389 test139 test1390 test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 test14 test140 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 test141 test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 test1418 test1419 test142 test1420 test1421 test1422 test1423 test1424 test1425 test1426 test1427 test1428 test1429 test143 test1430 test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 test144 test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 test145 test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 test146 test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 test1468 test1469 test147 test1470 test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 test1479 test148 test1480 test1481 test1482 test1483 test1484 test1485 test1486 test1487 test1488 test1489 test149 test1490 test1491 test1492 test1493 test1494 test1495 test1496 test1497 test1498 test1499 test15 test150 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 test1508 test1509 test151 test1510 test1511 test1512 test1513 test1514 test1515 test1516 test1517 test1518 test1519 test152 test1520 test1521 test1522 test1523 test1524 test1525 test1526 test1527 test1528 test1529 test153 test1530 test1531 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 test154 test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 test1548 test1549 test155 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 test1558 test1559 test156 test1560 test1561 test1562 test1563 test1564 test1565 test1566 test1567 test1568 test1569 test157 test1570 test1571 test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 test158 test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 test1589 test159 test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 test1598 test1599 test16 test160 test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 test1608 test1609 test161 test1610 test1611 test1612 test1613 test1614 test1615 test1616 test1617 test1618 test1619 test162 test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 test163 test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 test1638 test1639 test164 test1640 test1641 test1642 test1643 test1644 test1645 test165 test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 test1658 test1659 test166 test1660 test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 test1669 test167 test1670 test1671 test1672 test1673 test1674 test1675 test1676 test168 test1680 test1681 test1682 test1683 test1684 test1685 test169 test17 test170 test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 test1708 test1709 test171 test1710 test1711 test1712 test1713 test1714 test1715 test172 test1720 test1721 test173 test174 test175 test176 test177 test178 test179 test18 test180 test1800 test1801 test1802 test181 test182 test183 test184 test1847 test1848 test1849 test185 test1850 test1851 test186 test187 test188 test189 test19 test190 test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 test1908 test1909 test191 test1910 test1911 test1912 test1913 test1914 test1915 test1916 test1917 test1918 test1919 test192 test1920 test1921 test193 test1933 test1934 test1935 test1936 test1937 test1938 test1939 test194 test1940 test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 test195 test1955 test1956 test1957 test1958 test1959 test196 test1960 test1964 test1965 test1966 test197 test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 test1978 test1979 test198 test1980 test1981 test1982 test1983 test1984 test199 test2 test20 test200 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 test2008 test2009 test201 test2010 test2011 test2012 test2013 test2014 test202 test2023 test2024 test2025 test2026 test2027 test2028 test2029 test203 test2030 test2031 test2032 test2033 test2034 test2035 test2037 test2038 test2039 test204 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 test2048 test2049 test205 test2050 test2051 test2052 test2053 test2054 test2055 test2056 test2057 test2058 test2059 test206 test2060 test2061 test2062 test2063 test2064 test2065 test2066 test2067 test2068 test2069 test207 test2070 test2071 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 test208 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 test2088 test2089 test209 test2090 test2091 test2092 test21 test210 test2100 test2101 test2102 test2103 test2104 test211 test212 test213 test214 test215 test216 test217 test218 test219 test22 test220 test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 test221 test222 test223 test224 test225 test226 test227 test228 test229 test23 test230 test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 test2309 test231 test232 test233 test234 test235 test236 test237 test238 test239 test24 test240 test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 test2408 test2409 test241 test2410 test2411 test242 test243 test244 test245 test246 test247 test248 test249 test25 test250 test2500 test2501 test2502 test2503 test2504 test2505 test2506 test251 test252 test253 test254 test255 test256 test257 test258 test259 test26 test260 test2600 test2601 test2602 test2603 test2604 test2605 test261 test262 test263 test264 test265 test266 test267 test268 test269 test27 test270 test2700 test2701 test2702 test2703 test2704 test2705 test2706 test2707 test2708 test2709 test271 test2710 test2711 test2712 test2713 test2714 test2715 test2716 test2717 test2718 test2719 test272 test2720 test2721 test2722 test2723 test273 test274 test275 test276 test277 test278 test279 test28 test280 test281 test282 test283 test284 test285 test286 test287 test288 test289 test29 test290 test291 test292 test293 test294 test295 test296 test297 test298 test299 test3 test30 test300 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 test3008 test3009 test301 test3010 test3011 test3012 test3013 test3014 test3015 test3016 test3017 test3018 test3019 test302 test3020 test3021 test3022 test3023 test3024 test3025 test3026 test3027 test3028 test3029 test303 test3030 test3031 test3032 test3033 test3034 test3035 test3036 test304 test305 test306 test307 test308 test309 test31 test310 test3100 test3101 test3102 test3103 test3104 test3105 test3106 test311 test312 test313 test314 test315 test316 test317 test318 test319 test32 test320 test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 test3209 test321 test3210 test3211 test3212 test3213 test3214 test3215 test3216 test3217 test3218 test3219 test322 test3220 test323 test324 test325 test326 test327 test328 test329 test33 test330 test3300 test3301 test3302 test331 test332 test333 test334 test335 test336 test337 test338 test339 test34 test340 test341 test342 test343 test344 test345 test346 test347 test348 test349 test35 test350 test351 test352 test353 test354 test355 test356 test357 test358 test359 test36 test360 test361 test362 test363 test364 test365 test366 test367 test368 test369 test37 test370 test371 test372 test373 test374 test375 test376 test378 test379 test38 test380 test381 test383 test384 test385 test386 test387 test388 test389 test39 test390 test391 test392 test393 test394 test395 test396 test397 test398 test399 test4 test40 test400 test4000 test4001 test401 test402 test403 test404 test405 test406 test407 test408 test409 test41 test410 test411 test412 test413 test414 test415 test416 test417 test418 test419 test42 test420 test421 test422 test423 test424 test425 test426 test427 test428 test429 test43 test430 test431 test432 test433 test434 test435 test436 test437 test438 test439 test44 test440 test441 test442 test443 test444 test445 test446 test447 test448 test449 test45 test450 test451 test452 test453 test454 test455 test456 test457 test458 test459 test46 test460 test461 test462 test463 test467 test468 test469 test47 test470 test471 test472 test473 test474 test475 test476 test477 test478 test479 test48 test480 test481 test482 test483 test484 test485 test486 test487 test488 test489 test49 test490 test491 test492 test493 test494 test495 test496 test497 test498 test499 test5 test50 test500 test501 test502 test503 test504 test505 test506 test507 test508 test509 test51 test510 test511 test512 test513 test514 test515 test516 test517 test518 test519 test52 test520 test521 test522 test523 test524 test525 test526 test527 test528 test529 test53 test530 test531 test532 test533 test534 test535 test536 test537 test538 test539 test54 test540 test541 test542 test543 test544 test545 test546 test547 test548 test549 test55 test550 test551 test552 test553 test554 test555 test556 test557 test558 test559 test56 test560 test561 test562 test563 test564 test565 test566 test567 test568 test569 test57 test570 test571 test572 test573 test574 test575 test576 test577 test578 test579 test58 test580 test581 test582 test583 test584 test585 test586 test587 test588 test589 test59 test590 test591 test592 test593 test594 test595 test596 test597 test598 test599 test6 test60 test600 test601 test602 test603 test604 test605 test606 test607 test608 test609 test61 test610 test611 test612 test613 test614 test615 test616 test617 test618 test619 test62 test620 test621 test622 test623 test624 test625 test626 test627 test628 test629 test63 test630 test631 test632 test633 test634 test635 test636 test637 test638 test639 test64 test640 test641 test642 test643 test644 test645 test646 test647 test648 test649 test65 test650 test651 test652 test653 test654 test655 test656 test658 test659 test66 test660 test661 test662 test663 test664 test665 test666 test667 test668 test669 test67 test670 test671 test672 test673 test674 test675 test676 test677 test678 test679 test68 test680 test681 test682 test683 test684 test685 test686 test687 test688 test689 test69 test690 test691 test692 test693 test694 test695 test696 test697 test698 test699 test7 test70 test700 test701 test702 test703 test704 test705 test706 test707 test708 test709 test71 test710 test711 test712 test713 test714 test715 test716 test717 test718 test719 test72 test720 test721 test722 test723 test724 test725 test726 test727 test728 test729 test73 test730 test731 test732 test733 test734 test735 test736 test737 test738 test739 test74 test740 test741 test742 test743 test744 test745 test746 test747 test748 test749 test75 test750 test751 test752 test753 test754 test755 test756 test757 test758 test759 test76 test760 test761 test762 test763 test764 test765 test766 test767 test768 test769 test77 test770 test771 test772 test773 test774 test775 test776 test777 test778 test779 test78 test780 test781 test782 test783 test784 test785 test786 test787 test788 test789 test79 test790 test791 test792 test793 test794 test795 test796 test797 test798 test799 test8 test80 test800 test801 test802 test803 test804 test805 test806 test807 test808 test809 test81 test810 test811 test812 test813 test814 test815 test816 test817 test818 test819 test82 test820 test821 test822 test823 test824 test825 test826 test827 test828 test829 test83 test830 test831 test832 test833 test834 test835 test836 test837 test838 test839 test84 test840 test841 test842 test843 test844 test845 test846 test847 test848 test849 test85 test850 test851 test852 test853 test854 test855 test856 test857 test858 test859 test86 test860 test861 test862 test863 test864 test865 test866 test867 test868 test869 test87 test870 test871 test872 test873 test874 test875 test876 test877 test878 test879 test88 test880 test881 test882 test883 test884 test885 test886 test887 test888 test889 test89 test890 test891 test892 test893 test894 test895 test896 test897 test898 test899 test9 test90 test900 test901 test902 test903 test904 test905 test906 test907 test908 test909 test91 test910 test911 test912 test913 test914 test915 test916 test917 test918 test919 test92 test920 test921 test922 test923 test924 test925 test926 test927 test928 test929 test93 test930 test931 test932 test933 test934 test935 test936 test937 test938 test939 test94 test940 test941 test942 test943 test944 test945 test946 test947 test948 test949 test95 test950 test951 test952 test953 test954 test955 test956 test957 test958 test959 test96 test960 test961 test962 test963 test964 test965 test966 test967 test968 test969 test97 test970 test971 test972 test973 test974 test975 test976 test977 test978 test979 test98 test980 test981 test982 test983 test984 test985 test986 test987 test988 test989 test99 test990 test991 test992 test993 test994 test995 test996 test997 test998 test999
http
testenv
mod_curltest .gitignore mod_curltest.c
__init__.py caddy.py certs.py client.py curl.py dante.py dnsd.py env.py httpd.py nghttpx.py ports.py sshd.py vsftpd.py ws_echo_server.py
.gitignore CMakeLists.txt Makefile.am config.ini.in conftest.py requirements.txt scorecard.py test_01_basic.py test_02_download.py test_03_goaway.py test_04_stuttered.py test_05_errors.py test_06_eyeballs.py test_07_upload.py test_08_caddy.py test_09_push.py test_10_proxy.py test_11_unix.py test_12_reuse.py test_13_proxy_auth.py test_14_auth.py test_15_tracing.py test_16_info.py test_17_ssl_use.py test_18_methods.py test_19_shutdown.py test_20_websockets.py test_21_resolve.py test_22_httpsrr.py test_30_vsftpd.py test_31_vsftpds.py test_32_ftps_vsftpd.py test_40_socks.py test_50_scp.py test_51_sftp.py
libtest .gitignore CMakeLists.txt Makefile.am Makefile.inc cli_ftp_upload.c cli_h2_pausing.c cli_h2_serverpush.c cli_h2_upgrade_extreme.c cli_hx_download.c cli_hx_upload.c cli_tls_session_reuse.c cli_upload_pausing.c cli_ws_data.c cli_ws_pingpong.c first.c first.h lib1156.c lib1301.c lib1308.c lib1485.c lib1500.c lib1501.c lib1502.c lib1506.c lib1507.c lib1508.c lib1509.c lib1510.c lib1511.c lib1512.c lib1513.c lib1514.c lib1515.c lib1517.c lib1518.c lib1520.c lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c lib1545.c lib1549.c lib1550.c lib1551.c lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c lib1559.c lib1560.c lib1564.c lib1565.c lib1567.c lib1568.c lib1569.c lib1571.c lib1576.c lib1582.c lib1587.c lib1588.c lib1589.c lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c lib1598.c lib1599.c lib1662.c lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c lib1933.c lib1934.c lib1935.c lib1936.c lib1937.c lib1938.c lib1939.c lib1940.c lib1945.c lib1947.c lib1948.c lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c lib1964.c lib1965.c lib1970.c lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c lib2023.c lib2032.c lib2082.c lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c lib2402.c lib2404.c lib2405.c lib2502.c lib2504.c lib2505.c lib2506.c lib2700.c lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c lib3207.c lib3208.c lib500.c lib501.c lib502.c lib503.c lib504.c lib505.c lib506.c lib507.c lib508.c lib509.c lib510.c lib511.c lib512.c lib513.c lib514.c lib515.c lib516.c lib517.c lib518.c lib519.c lib520.c lib521.c lib523.c lib524.c lib525.c lib526.c lib530.c lib533.c lib536.c lib537.c lib539.c lib540.c lib541.c lib542.c lib543.c lib544.c lib547.c lib549.c lib552.c lib553.c lib554.c lib555.c lib556.c lib557.c lib558.c lib559.c lib560.c lib562.c lib564.c lib566.c lib567.c lib568.c lib569.c lib570.c lib571.c lib572.c lib573.c lib574.c lib575.c lib576.c lib578.c lib579.c lib582.c lib583.c lib586.c lib589.c lib590.c lib591.c lib597.c lib598.c lib599.c lib643.c lib650.c lib651.c lib652.c lib653.c lib654.c lib655.c lib658.c lib659.c lib661.c lib666.c lib667.c lib668.c lib670.c lib674.c lib676.c lib677.c lib678.c lib694.c lib695.c lib751.c lib753.c lib757.c lib758.c lib766.c memptr.c mk-lib1521.pl test1013.pl test1022.pl test307.pl test610.pl test613.pl testtrace.c testtrace.h testutil.c testutil.h unitcheck.h
server .checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc dnsd.c first.c first.h getpart.c mqttd.c resolve.c rtspd.c sockfilt.c socksd.c sws.c tftpd.c util.c
tunit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.c
unit .gitignore CMakeLists.txt Makefile.am Makefile.inc README.md unit1300.c unit1302.c unit1303.c unit1304.c unit1305.c unit1307.c unit1309.c unit1323.c unit1330.c unit1395.c unit1396.c unit1397.c unit1398.c unit1399.c unit1600.c unit1601.c unit1602.c unit1603.c unit1605.c unit1606.c unit1607.c unit1608.c unit1609.c unit1610.c unit1611.c unit1612.c unit1614.c unit1615.c unit1616.c unit1620.c unit1625.c unit1626.c unit1627.c unit1636.c unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c unit1666.c unit1667.c unit1668.c unit1669.c unit1674.c unit1675.c unit1676.c unit1979.c unit1980.c unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c unit3200.c unit3205.c unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c unit3219.c unit3300.c unit3301.c unit3302.c
.gitignore CMakeLists.txt Makefile.am allversions.pm appveyor.pm azure.pm config.in configurehelp.pm.in devtest.pl dictserver.py directories.pm ech_combos.py ech_tests.sh ftpserver.pl getpart.pm globalconfig.pm http-server.pl http2-server.pl http3-server.pl memanalyze.pl memanalyzer.pm negtelnetserver.py nghttpx.conf pathhelp.pm processhelp.pm requirements.txt rtspserver.pl runner.pm runtests.pl secureserver.pl serverhelp.pm servers.pm smbserver.py sshhelp.pm sshserver.pl test1119.pl test1135.pl test1139.pl test1140.pl test1165.pl test1167.pl test1173.pl test1175.pl test1177.pl test1222.pl test1275.pl test1276.pl test1477.pl test1486.pl test1488.pl test1544.pl test1707.pl test745.pl test971.pl testcurl.pl testutil.pm tftpserver.pl util.py valgrind.pm valgrind.supp
.clang-tidy.yml .dir-locals.el .editorconfig .git-blame-ignore-revs .gitattributes .gitignore .mailmap CHANGES.md CMakeLists.txt COPYING Dockerfile GIT-INFO.md Makefile.am README README.md RELEASE-NOTES REUSE.toml SECURITY.md acinclude.m4 appveyor.sh appveyor.yml configure.ac curl-config.in libcurl.pc.in renovate.json
examples .env config.ini crypto_test.lua env_test.lua fs_example.lua http_server.lua https_test.lua ini_example.lua json.lua log.lua path_fs_example.lua process_example.lua request_download.lua request_test.lua run_all.lua sqlite_example.lua sqlite_http_template.lua stash_test.lua template_test.lua timer.lua websocket.lua
iniparser
.github
ISSUE_TEMPLATE config.yml
workflows disable-pull-requests.yml trigger-gitlab-ci.yml
cmake JoinPaths.cmake config.cmake.in pc.in
example iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.ini
src dictionary.c dictionary.h iniparser.c iniparser.h
test
ressources
bad_ini ends_well.ini twisted-errors.ini twisted-ofkey.ini twisted-ofval.ini
good_ini empty.ini spaced.ini spaced2.ini twisted.ini
gruezi.ini old.ini quotes.ini utf8.ini
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.h
.cmake-format.py .gitignore .gitlab-ci.yml .gitmessage .travis.yml AUTHORS CMakeLists.txt FAQ-en.md FAQ-zhcn.md INSTALL LICENSE README.md compile_commands.json
jinjac
example CMakeLists.txt example.c
jinjac_test_app CMakeLists.txt jinjac_test_app.c
libjinjac
include jinjac.h
src CMakeLists.txt ast.c ast.h block_statement.c block_statement.h buffer.c buffer.h buildin.c buildin.h common.h convert.c convert.h flex_decl.h jfunction.c jfunction.h jinja_expression.l jinja_expression.y jinjac_parse.c jinjac_parse.h jinjac_stream.c jinjac_stream.h jlist.c jlist.h jobject.c jobject.h parameter.c parameter.h str_obj.c str_obj.h trace.c trace.h
CMakeLists.txt
test .gitignore CMakeLists.txt autotest.rb test_01.expected test_01.jinja test_01b.expected test_01b.jinja test_01c.expected test_01c.jinja test_01d.expected test_01d.jinja test_02.expected test_02.jinja test_03.expected test_03.jinja test_04.expected test_04.jinja test_05.expected test_05.jinja test_06.expected test_06.jinja test_07.expected test_07.jinja test_08.expected test_08.jinja test_08b.expected test_08b.jinja test_09.expected test_09.jinja test_10.expected test_10.jinja test_11.expected test_11.jinja test_12.expected test_12.jinja test_13.expected test_13.jinja test_14.expected test_14.jinja test_15.expected test_15.jinja test_16.expected test_16.jinja test_17.expected test_17.jinja test_18.expected test_18.jinja test_18b.expected test_18b.jinja test_18c.expected test_18c.jinja test_19.expected test_19.jinja test_19b.expected test_19b.jinja test_19c.expected test_19c.jinja test_19d.expected test_19d.jinja test_19e.expected test_19e.jinja test_19f.expected test_19f.jinja test_20.expected test_20.jinja test_21.expected test_21.jinja test_22.expected test_22.jinja test_22a.expected test_22a.jinja test_22b.expected test_22b.jinja test_23.expected test_23.jinja test_24.expected test_24.jinja
.gitignore CMakeLists.txt LICENSE.txt README.md build_coverage.sh build_debug.sh build_release.sh cppcheck_analysis.sh
libev Changes LICENSE Makefile Makefile.am Makefile.in README Symbols.ev Symbols.event aclocal.m4 autogen.sh compile config.guess config.h config.h.in config.status config.sub configure configure.ac depcomp ev++.h ev.3 ev.c ev.h ev.pod ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_vars.h ev_win32.c ev_wrap.h event.c event.h install-sh libev.m4 libtool ltmain.sh missing mkinstalldirs stamp-h1
luajit
doc
img contact.png
bluequad-print.css bluequad.css contact.html ext_buffer.html ext_c_api.html ext_ffi.html ext_ffi_api.html ext_ffi_semantics.html ext_ffi_tutorial.html ext_jit.html ext_profiler.html extensions.html install.html luajit.html running.html
dynasm dasm_arm.h dasm_arm.lua dasm_arm64.h dasm_arm64.lua dasm_mips.h dasm_mips.lua dasm_mips64.lua dasm_ppc.h dasm_ppc.lua dasm_proto.h dasm_x64.lua dasm_x86.h dasm_x86.lua dynasm.lua
etc luajit.1 luajit.pc
src
host .gitignore README buildvm.c buildvm.h buildvm_asm.c buildvm_fold.c buildvm_lib.c buildvm_libbc.h buildvm_peobj.c genlibbc.lua genminilua.lua genversion.lua minilua.c
jit .gitignore bc.lua bcsave.lua dis_arm.lua dis_arm64.lua dis_arm64be.lua dis_mips.lua dis_mips64.lua dis_mips64el.lua dis_mips64r6.lua dis_mips64r6el.lua dis_mipsel.lua dis_ppc.lua dis_x64.lua dis_x86.lua dump.lua p.lua v.lua zone.lua
.gitignore Makefile Makefile.dep lauxlib.h lib_aux.c lib_base.c lib_bit.c lib_buffer.c lib_debug.c lib_ffi.c lib_init.c lib_io.c lib_jit.c lib_math.c lib_os.c lib_package.c lib_string.c lib_table.c lj_alloc.c lj_alloc.h lj_api.c lj_arch.h lj_asm.c lj_asm.h lj_asm_arm.h lj_asm_arm64.h lj_asm_mips.h lj_asm_ppc.h lj_asm_x86.h lj_assert.c lj_bc.c lj_bc.h lj_bcdump.h lj_bcread.c lj_bcwrite.c lj_buf.c lj_buf.h lj_carith.c lj_carith.h lj_ccall.c lj_ccall.h lj_ccallback.c lj_ccallback.h lj_cconv.c lj_cconv.h lj_cdata.c lj_cdata.h lj_char.c lj_char.h lj_clib.c lj_clib.h lj_cparse.c lj_cparse.h lj_crecord.c lj_crecord.h lj_ctype.c lj_ctype.h lj_debug.c lj_debug.h lj_def.h lj_dispatch.c lj_dispatch.h lj_emit_arm.h lj_emit_arm64.h lj_emit_mips.h lj_emit_ppc.h lj_emit_x86.h lj_err.c lj_err.h lj_errmsg.h lj_ff.h lj_ffrecord.c lj_ffrecord.h lj_frame.h lj_func.c lj_func.h lj_gc.c lj_gc.h lj_gdbjit.c lj_gdbjit.h lj_ir.c lj_ir.h lj_ircall.h lj_iropt.h lj_jit.h lj_lex.c lj_lex.h lj_lib.c lj_lib.h lj_load.c lj_mcode.c lj_mcode.h lj_meta.c lj_meta.h lj_obj.c lj_obj.h lj_opt_dce.c lj_opt_fold.c lj_opt_loop.c lj_opt_mem.c lj_opt_narrow.c lj_opt_sink.c lj_opt_split.c lj_parse.c lj_parse.h lj_prng.c lj_prng.h lj_profile.c lj_profile.h lj_record.c lj_record.h lj_serialize.c lj_serialize.h lj_snap.c lj_snap.h lj_state.c lj_state.h lj_str.c lj_str.h lj_strfmt.c lj_strfmt.h lj_strfmt_num.c lj_strscan.c lj_strscan.h lj_tab.c lj_tab.h lj_target.h lj_target_arm.h lj_target_arm64.h lj_target_mips.h lj_target_ppc.h lj_target_x86.h lj_trace.c lj_trace.h lj_traceerr.h lj_udata.c lj_udata.h lj_vm.h lj_vmevent.c lj_vmevent.h lj_vmmath.c ljamalg.c lua.h lua.hpp luaconf.h luajit.c luajit_rolling.h lualib.h msvcbuild.bat nxbuild.bat ps4build.bat ps5build.bat psvitabuild.bat vm_arm.dasc vm_arm64.dasc vm_mips.dasc vm_mips64.dasc vm_ppc.dasc vm_x64.dasc vm_x86.dasc xb1build.bat xedkbuild.bat
.gitattributes .gitignore .relver COPYRIGHT Makefile README
sqlite shell.c sqlite3.c sqlite3.h sqlite3ext.h
wolfssl
.github
ISSUE_TEMPLATE bug_report.yaml other.yaml
actions
install-apt-deps action.yml
scripts
zephyr-4.x external_libc.conf zephyr-test.sh
openssl-ech.sh tls-anvil-test.sh
workflows
disabled haproxy.yml hitch.yml hostap.yml
hostap-files
configs
07c9f183ea744ac04585fb6dd10220c75a5e2e74 hostapd.config tests wpa_supplicant.config
b607d2723e927a3446d89aed813f1aa6068186bb hostapd.config tests wpa_supplicant.config
hostap_2_10 extra.patch hostapd.config tests wpa_supplicant.config
Makefile README dbus-wpa_supplicant.conf
ada.yml arduino.yml async-examples.yml async.yml atecc608-sim.yml bind.yml cmake-autoconf.yml cmake.yml codespell.yml coverity-scan-fixes.yml cryptocb-only.yml curl.yml cyrus-sasl.yml disable-pk-algs.yml docker-Espressif.yml docker-OpenWrt.yml emnet-nonblock.yml fil-c.yml freertos-mem-track.yml gencertbuf.yml grpc.yml haproxy.yml hostap-vm.yml intelasm-c-fallback.yml ipmitool.yml jwt-cpp.yml krb5.yml libspdm.yml libssh2.yml libvncserver.yml linuxkm.yml macos-apple-native-cert-validation.yml mbedtls.sh mbedtls.yml membrowse-comment.yml membrowse-onboard.yml membrowse-report.yml memcached.sh memcached.yml mono.yml mosquitto.yml msmtp.yml msys2.yml multi-arch.yml multi-compiler.yml net-snmp.yml nginx.yml no-malloc.yml no-tls.yml nss.sh nss.yml ntp.yml ocsp.yml openldap.yml openssh.yml openssl-ech.yml opensslcoexist.yml openvpn.yml os-check.yml packaging.yml pam-ipmi.yml pq-all.yml pr-commit-check.yml psk.yml puf.yml python.yml rng-tools.yml rust-wrapper.yml se050-sim.yml smallStackSize.yml socat.yml softhsm.yml sssd.yml stm32-sim.yml stsafe-a120-sim.yml stunnel.yml symbol-prefixes.yml threadx.yml tls-anvil.yml trackmemory.yml watcomc.yml win-csharp-test.yml wolfCrypt-Wconversion.yml wolfboot-integration.yml wolfsm.yml xcode.yml zephyr-4.x.yml zephyr.yml
PULL_REQUEST_TEMPLATE.md SECURITY.md membrowse-targets.json
Docker
OpenWrt Dockerfile README.md runTests.sh
packaging
debian Dockerfile
fedora Dockerfile
wolfCLU Dockerfile README.md
yocto Dockerfile buildAndPush.sh
Dockerfile Dockerfile.cross-compiler README.md buildAndPush.sh include.am run.sh
IDE
ARDUINO
sketches
wolfssl_client README.md
wolfssl_server README.md
wolfssl_version README.md
README.md
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.h
AURIX Cpu0_Main.c README.md include.am user_settings.h wolf_main.c
Android Android.bp README.md include.am user_settings.h
CRYPTOCELL README.md include.am main.c user_settings.h
CSBENCH include.am user_settings.h
ECLIPSE
DEOS
deos_wolfssl .options
README.md deos_malloc.c include.am tls_wolfssl.c tls_wolfssl.h user_settings.h
MICRIUM README.md client_wolfssl.c client_wolfssl.h include.am server_wolfssl.c server_wolfssl.h user_settings.h wolfsslRunTests.c
RTTHREAD README.md include.am user_settings.h wolfssl_test.c
SIFIVE README.md include.am
Espressif
ESP-IDF
examples
template
VisualGDB wolfssl_template_IDF_v5.1_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_benchmark
VisualGDB wolfssl_benchmark_IDF_v4.4_ESP32.sln wolfssl_benchmark_IDF_v4.4_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32.sln wolfssl_benchmark_IDF_v5_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32C3.sln wolfssl_benchmark_IDF_v5_ESP32C3.vgdbproj wolfssl_benchmark_IDF_v5_ESP32S3.sln wolfssl_benchmark_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266
wolfssl_client
VisualGDB README.md wolfssl_client_IDF_v5_ESP32.sln wolfssl_client_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include client-tls.h main.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild client-tls.c component.mk main.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbproj
wolfssl_server
VisualGDB README.md wolfssl_server_IDF_v5_ESP32.sln wolfssl_server_IDF_v5_ESP32.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h server-tls.h time_helper.h wifi_connect.h
CMakeLists.txt Kconfig.projbuild component.mk main.c server-tls.c time_helper.c wifi_connect.c
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbproj
wolfssl_test
VisualGDB wolfssl_test-IDF_v5_ESP32.sln wolfssl_test-IDF_v5_ESP32.vgdbproj wolfssl_test-IDF_v5_ESP32C3.sln wolfssl_test-IDF_v5_ESP32C3.vgdbproj wolfssl_test-IDF_v5_ESP32C6.sln wolfssl_test-IDF_v5_ESP32C6.vgdbproj wolfssl_test_IDF_v5_ESP32S3.sln wolfssl_test_IDF_v5_ESP32S3.vgdbproj
components
wolfssl
include user_settings.h
CMakeLists.txt Kconfig README.md component.mk
main
include main.h
CMakeLists.txt Kconfig.projbuild component.mk main.c
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32 sdkconfig.defaults.esp32c3 sdkconfig.defaults.esp32c6 sdkconfig.defaults.esp32h2 sdkconfig.defaults.esp32s2 sdkconfig.defaults.esp32s3 sdkconfig.defaults.esp8266 testAll.sh testMonitor.sh wolfssl_test_ESP8266.sln wolfssl_test_ESP8266.vgdbproj
wolfssl_test_idf
VisualGDB VisualGDB_wolfssl_test_idf.sln VisualGDB_wolfssl_test_idf.vgdbproj
main CMakeLists.txt Kconfig.projbuild component.mk main.c main_wip.c.ex time_helper.c time_helper.h
CMakeLists.txt Kconfig.projbuild README.md component.mk sdkconfig.defaults
README.md
libs CMakeLists.txt README.md component.mk tigard.cfg
test CMakeLists.txt README.md component.mk test_wolfssl.c
README.md README_32se.md UPDATE.md compileAllExamples.sh dummy_config_h dummy_test_paths.h setup.sh setup_win.bat user_settings.h
README.md include.am
GCC-ARM
Header user_settings.h
Source armtarget.c benchmark_main.c test_main.c tls_client.c tls_server.c wolf_main.c
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ld
Gaisler-BCC README.md include.am
HEXAGON
DSP Makefile wolfssl_dsp.idl
Makefile README.md build.sh ecc-verify-benchmark.c ecc-verify.c include.am user_settings.h
HEXIWEAR
wolfSSL_HW .cwGeneratedFileSetLog user_settings.h
IAR-EWARM
Projects
benchmark benchmark-main.c current_time.c wolfCrypt-benchmark.ewd wolfCrypt-benchmark.ewp
common minimum-startup.c wolfssl.icf
lib wolfSSL-Lib.ewd wolfSSL-Lib.ewp
test test-main.c wolfCrypt-test.ewd wolfCrypt-test.ewp
user_settings.h wolfssl.eww
embOS
SAMV71_XULT
embOS_SAMV71_XULT_Linker_Script samv71q21_wolfssl.icf
embOS_SAMV71_XULT_user_settings user_settings.h user_settings_simple_example.h user_settings_verbose_example.h
embOS_wolfcrypt_benchmark_SAMV71_XULT
Application runBenchmarks.c
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewp
embOS_wolfcrypt_lib_SAMV71_XULT README_wolfcrypt_lib wolfcrypt_lib.ewd wolfcrypt_lib.ewp
embOS_wolfcrypt_test_SAMV71_XULT
Application runWolfcryptTests.c
README_wolfcrypt_test wolfcrypt_test.ewd wolfcrypt_test.ewp
README_SAMV71
custom_port
custom_port_Linker_Script samv71q21_wolfssl.icf
custom_port_user_settings user_settings.h
wolfcrypt_benchmark_custom_port
Application runBenchmarks.c
wolfcrypt_test_custom_port
Application runWolfcryptTests.c
README_custom_port
extract_trial_here README_extract_trial_here
README
.gitignore README
IAR-MSP430 Makefile README.md include.am main.c user_settings.h
INTIME-RTOS Makefile README.md include.am libwolfssl.c libwolfssl.vcxproj user_settings.h wolfExamples.c wolfExamples.h wolfExamples.sln wolfExamples.vcxproj wolfssl-lib.sln wolfssl-lib.vcxproj
Infineon README.md include.am user_settings.h
KDS
config user_settings.h
include.am
LINUX-SGX README.md build.sh clean.sh include.am sgx_t_static.mk
LPCXPRESSO
lib_wolfssl lpc_18xx_port.c user_settings.h
wolf_example
src lpc_18xx_startup.c wolfssl_example.c
readme.txt
README.md
M68K
benchmark Makefile main.cpp
testwolfcrypt Makefile main.cpp
Makefile README.md include.am user_settings.h
MCUEXPRESSO
RT1170 fsl_caam_c.patch fsl_caam_h.patch user_settings.h
benchmark
source run_benchmark.c
wolfssl liblinks.xml
README.md include.am user_settings.h wolfcrypt_test.c
MDK-ARM
LPC43xx time-LCP43xx.c
MDK-ARM
wolfSSL Retarget.c cert_data.c cert_data.h config-BARE-METAL.h config-FS.h config-RTX-TCP-FS.h config-WOLFLIB.h main.c shell.c time-CortexM3-4.c time-dummy.c wolfssl_MDK_ARM.c wolfssl_MDK_ARM.h
STM32F2xx_StdPeriph_Lib time-STM32F2xx.c
MDK5-ARM
Conf user_settings.h
Inc wolfssl_MDK_ARM.h
Projects
CryptBenchmark Abstract.txt CryptBenchmark.sct CryptBenchmark.uvoptx CryptBenchmark.uvprojx main.c
CryptTest Abstract.txt CryptTest.sct CryptTest.uvoptx CryptTest.uvprojx main.c
EchoClient Abstract.txt EchoClient.uvoptx EchoClient.uvprojx main.c wolfssl-link.sct
EchoServer Abstract.txt EchoServer.uvoptx EchoServer.uvprojx main.c wolfssl-link.sct
SimpleClient Abstract.txt SimpleClient.uvoptx SimpleClient.uvprojx main.c wolfssl-link.sct
SimpleServer Abstract.txt SimpleServer.uvoptx SimpleServer.uvprojx main.c wolfssl-link.sct
wolfSSL-Full Abstract.txt main.c shell.c time-CortexM3-4.c wolfsslFull.uvoptx wolfsslFull.uvprojx
wolfSSL-Lib Abstract.txt wolfSSL-Lib.uvoptx wolfSSL-Lib.uvprojx
Src ssl-dummy.c
README.md include.am
MPLABX16
wolfcrypt_test.X
nbproject
private configurations.xml private.xml
configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
README.md include.am main.c user_settings.h
MQX Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.h
MSVS-2019-AZSPHERE
client client.c client.h
server server.c server.h
shared util.h
wolfssl_new_azsphere
HardwareDefinitions
avnet_mt3620_sk
inc
hw template_appliance.h
template_appliance.json
mt3620_rdb
inc
hw template_appliance.h
template_appliance.json
seeed_mt3620_mdb
inc
hw template_appliance.h
template_appliance.json
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.c
README.md include.am user_settings.h
MYSQL CMakeLists_wolfCrypt.txt CMakeLists_wolfSSL.txt do.sh
NDS README.md
NETOS Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.c
OPENSTM32 README.md
PlatformIO
examples
wolfssl_benchmark
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspace
wolfssl_test
include README main.h
lib README
src CMakeLists.txt main.c
test README
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_test.code-workspace
README.md wolfssl_platformio.code-workspace
README.md include.am
QNX
CAAM-DRIVER Makefile
example-client Makefile client-tls.c
example-cmac Makefile cmac-test.c
example-server Makefile server-tls.c
testwolfcrypt Makefile
wolfssl Makefile user_settings.h
README.md include.am
RISCV
SIFIVE-HIFIVE1 Makefile README.md include.am main.c user_settings.h
SIFIVE-UNLEASHED README.md include.am
include.am
ROWLEY-CROSSWORKS-ARM Kinetis_FlashPlacement.xml README.md arm_startup.c benchmark_main.c hw.h include.am kinetis_hw.c retarget.c test_main.c user_settings.h wolfssl.hzp wolfssl_ltc.hzp
Renesas
cs+
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
t4_demo README_en.txt README_jp.txt t4_demo.mtpj wolf_client.c wolf_demo.h wolf_main.c wolf_server.c
test test.mtpj test_main.c
wolfssl_lib wolfssl_lib.mtpj
README include.am
e2studio
DK-S7G2
benchmark-template
src app_entry.c
example_server-template
src app_entry.c
wolfcrypttest-template
src app_entry.c
wolfssl-template-project configuration.xml
README.md include.am user_settings.h
Projects
common strings.h unistd.h user_settings.h wolfssl_dummy.c
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
tools generate_rsa_keypair.sh genhexbuf.pl rsa_pss_sign.sh
wolfssl
src .gitkeep
wolfcrypt
src .gitkeep
README include.am
RA6M3
benchmark-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
client-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
common
ra6m3g README.md
src freertos_tcp_port.c
user_settings.h util.h
server-wolfssl
common
src .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl_thread_entry.h
test-wolfcrypt
common .gitkeep
script .gitkeep
src wolfssl_thread_entry.c
wolfssl
src .gitkeep
wolfcrypt .gitkeep
README.md README_APRA6M_en.md README_APRA6M_jp.md include.am
RA6M3G README.md
RA6M4
common user_settings.h wolfssl_demo.h
test
key_data key_data.h key_data_sce.c
src
SEGGER_RTT myprint.c
common .gitignore
test_main.c wolf_client.c wolfssl_sce_unit_test.c
test_RA6M4Debug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
README.md include.am
RX65N
GR-ROSE
common strings.h unistd.h user_settings.h wolfssl_dummy.c
smc smc.scfg
test
src key_data.c key_data.h test_main.c wolf_client.c wolf_server.c wolfssl_demo.h
test.rcpc test_HardwareDebug.launch
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
README_EN.md README_JP.md include.am
RSK
resource section.esi
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h
InstructionManualForExample_RSK+RX65N-2MB_EN.pdf InstructionManualForExample_RSK+RX65N-2MB_JP.pdf README_EN.md README_JP.md include.am
RX72N
EnvisionKit
Simple
common sectioninfo.esi wolfssl_dummy.c
test
src
client simple_tcp_client.c simple_tls_tsip_client.c
server simple_tcp_server.c simple_tls_server.c
test_main.c wolfssl_simple_demo.h
test.rcpc test.scfg test_HardwareDebug.launch
wolfssl wolfssl.rcpc
README_EN.md README_JP.md
resource section.esi
tools
example_keys generate_SignedCA.sh rsa_private.pem rsa_public.pem
README.md
wolfssl wolfssl.rcpc
wolfssl_demo key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.c
InstructionManualForExample_RX72N_EnvisonKit_EN.pdf InstructionManualForExample_RX72N_EnvisonKit_JP.pdf README_EN.md README_JP.md include.am
RZN2L
common user_settings.h wolfssl_demo.h
test
src
serial_io app_print.c
test wolf_client.c wolf_server.c wolfssl_rsip_unit_test.c
wolfCrypt .gitignore
wolfSSL .gitignore
local_system_init.c rzn2l_tst_thread_entry.c wolfssl_dummy.c
README.md include.am
SK-S7G2
common user_settings.h
wolfssl_lib configuration.xml
.gitignore README.md include.am
STARCORE README.txt include.am starcore_test.c user_settings.h
STM32Cube README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.h
SimplicityStudio README.md include.am test_wolf.c user_settings.h
TRUESTUDIO
wolfssl user_settings.h
README include.am
VS-ARM README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VS-AZURE-SPHERE
client app_manifest.json client.c client.h client.vcxproj
server app_manifest.json server.c server.h server.vcxproj
shared util.h
wolfcrypt_test app_manifest.json wolfcrypt_test.vcxproj
README.md include.am user_settings.h wolfssl.sln wolfssl.vcxproj
VisualDSP include.am user_settings.h wolf_tasks.c
WICED-STUDIO README include.am user_settings.h
WIN README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxproj
WIN-SGX ReadMe.txt include.am wolfSSL_SGX.edl wolfSSL_SGX.sln wolfSSL_SGX.vcxproj
WIN-SRTP-KDF-140-3 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WIN10 README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxproj
WINCE README.md include.am user_settings.h user_settings.h.140-2-deprecated
WORKBENCH README.md include.am
XCODE
Benchmark
wolfBench
Assets.xcassets
AppIcon.appiconset Contents.json
Base.lproj LaunchScreen.storyboard Main.storyboard
AppDelegate.h AppDelegate.m Info.plist ViewController.h ViewController.m main.m
wolfBench.xcodeproj project.pbxproj
include.am
wolfssl-FIPS.xcodeproj project.pbxproj
wolfssl.xcodeproj project.pbxproj
wolfssl_testsuite.xcodeproj project.pbxproj
README.md build-for-i386.sh include.am user_settings.h
XCODE-FIPSv2
macOS-C++
Intel user_settings.h
M1 user_settings.h
include.am user_settings.h
XCODE-FIPSv5 README include.am user_settings.h
XCODE-FIPSv6 README include.am user_settings.h
XilinxSDK
2018_2 lscript.ld
2019_2
wolfCrypt_example
src lscript.ld
wolfCrypt_example_system wolfCrypt_example_system.sprj
2022_1
wolfCrypt_FreeRTOS_example wolfCrypt_FreeRTOS_example.prj
wolfCrypt_FreeRTOS_example_system wolfCrypt_FreeRTOS_example_system.sprj
wolfCrypt_example wolfCrypt_example.prj
wolfCrypt_example_system wolfCrypt_example_system.sprj
.gitignore
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.c
apple-universal
wolfssl-multiplatform
wolfssl-multiplatform
Assets.xcassets
AccentColor.colorset Contents.json
AppIcon.appiconset Contents.json
Contents.json
ContentView.swift simple_client_example.c simple_client_example.h wolfssl-multiplatform-Bridging-Header.h wolfssl_multiplatform.entitlements wolfssl_multiplatformApp.swift wolfssl_test_driver.c wolfssl_test_driver.h
wolfssl-multiplatform.xcodeproj project.pbxproj
.gitignore README.md build-wolfssl-framework.sh include.am
iotsafe Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.h
iotsafe-raspberrypi Makefile README.md client-tls13.c include.am main.c
mynewt README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.sh
zephyr README.md include.am
include.am
RTOS
nuttx
wolfssl .gitignore Kconfig Make.defs Makefile README.md setup-wolfssl.sh user_settings.h
include.am
bsdkm Makefile README.md bsdkm_wc_port.h include.am wolfkmod.c wolfkmod_aes.c x86_vecreg.c
certs
1024 ca-cert.der ca-cert.pem ca-key.der ca-key.pem client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der dh1024.der dh1024.pem dsa-pub-1024.pem dsa1024.der dsa1024.pem include.am rsa1024.der server-cert.der server-cert.pem server-key.der server-key.pem
3072 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
4096 client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der include.am
acert
rsa_pss acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem
acert.pem acert_ietf.pem acert_ietf_pubkey.pem acert_pubkey.pem include.am
aia ca-issuers-cert.pem multi-aia-cert.pem overflow-aia-cert.pem
crl
extra-crls ca-int-cert-revoked.pem claim-root.pem crl_critical_entry.pem crlnum_57oct.pem crlnum_64oct.pem general-server-crl.pem large_crlnum.pem large_crlnum2.pem
hash_der 0fdb2da4.r0
hash_pem 0fdb2da4.r0
bad_time_fmt.pem ca-int-ecc.pem ca-int.pem ca-int2-ecc.pem ca-int2.pem caEcc384Crl.pem caEccCrl.der caEccCrl.pem cliCrl.pem client-int-ecc.pem client-int.pem crl.der crl.pem crl.revoked crl2.der crl2.pem crl_reason.pem crl_rsapss.pem eccCliCRL.pem eccSrvCRL.pem gencrls.sh include.am server-goodaltCrl.pem server-goodaltwildCrl.pem server-goodcnCrl.pem server-goodcnwildCrl.pem server-int-ecc.pem server-int.pem wolfssl.cnf
dilithium bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.am
ecc bp256r1-key.der bp256r1-key.pem ca-secp256k1-cert.pem ca-secp256k1-key.pem client-bp256r1-cert.der client-bp256r1-cert.pem client-secp256k1-cert.der client-secp256k1-cert.pem genecc.sh include.am secp256k1-key.der secp256k1-key.pem secp256k1-param.pem secp256k1-privkey.der secp256k1-privkey.pem server-bp256r1-cert.der server-bp256r1-cert.pem server-secp256k1-cert.der server-secp256k1-cert.pem server2-secp256k1-cert.der server2-secp256k1-cert.pem wolfssl.cnf wolfssl_384.cnf
ed25519 ca-ed25519-key.der ca-ed25519-key.pem ca-ed25519-priv.der ca-ed25519-priv.pem ca-ed25519.der ca-ed25519.pem client-ed25519-key.der client-ed25519-key.pem client-ed25519-priv.der client-ed25519-priv.pem client-ed25519.der client-ed25519.pem eddsa-ed25519.der eddsa-ed25519.pem gen-ed25519-certs.sh gen-ed25519-keys.sh gen-ed25519.sh include.am root-ed25519-key.der root-ed25519-key.pem root-ed25519-priv.der root-ed25519-priv.pem root-ed25519.der root-ed25519.pem server-ed25519-cert.pem server-ed25519-key.der server-ed25519-key.pem server-ed25519-priv.der server-ed25519-priv.pem server-ed25519.der server-ed25519.pem
ed448 ca-ed448-key.der ca-ed448-key.pem ca-ed448-priv.der ca-ed448-priv.pem ca-ed448.der ca-ed448.pem client-ed448-key.der client-ed448-key.pem client-ed448-priv.der client-ed448-priv.pem client-ed448.der client-ed448.pem gen-ed448-certs.sh gen-ed448-keys.sh include.am root-ed448-key.der root-ed448-key.pem root-ed448-priv.der root-ed448-priv.pem root-ed448.der root-ed448.pem server-ed448-cert.pem server-ed448-key.der server-ed448-key.pem server-ed448-priv.der server-ed448-priv.pem server-ed448.der server-ed448.pem
external DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.am
falcon bench_falcon_level1_key.der bench_falcon_level5_key.der include.am
intermediate
ca_false_intermediate gentestcert.sh int_ca.key server.key test_ca.key test_ca.pem test_int_not_cacert.pem test_sign_bynoca_srv.pem wolfssl_base.conf wolfssl_srv.conf
ca-ecc-bad-aki.der ca-ecc-bad-aki.pem ca-int-cert.der ca-int-cert.pem ca-int-ecc-cert.der ca-int-ecc-cert.pem ca-int-ecc-key.der ca-int-ecc-key.pem ca-int-key.der ca-int-key.pem ca-int2-cert.der ca-int2-cert.pem ca-int2-ecc-cert.der ca-int2-ecc-cert.pem ca-int2-ecc-key.der ca-int2-ecc-key.pem ca-int2-key.der ca-int2-key.pem client-chain-alt-ecc.pem client-chain-alt.pem client-chain-ecc.der client-chain-ecc.pem client-chain.der client-chain.pem client-int-cert.der client-int-cert.pem client-int-ecc-cert.der client-int-ecc-cert.pem genintcerts.sh include.am server-chain-alt-ecc.pem server-chain-alt.pem server-chain-ecc.der server-chain-ecc.pem server-chain-short.pem server-chain.der server-chain.pem server-int-cert.der server-int-cert.pem server-int-ecc-cert.der server-int-ecc-cert.pem
lms bc_hss_L2_H5_W8_root.der bc_hss_L3_H5_W4_root.der bc_lms_chain_ca.der bc_lms_chain_leaf.der bc_lms_native_bc_root.der bc_lms_sha256_h10_w8_root.der bc_lms_sha256_h5_w4_root.der include.am
mldsa README.txt include.am mldsa44-cert.der mldsa44-cert.pem mldsa44-key.pem mldsa44_bare-priv.der mldsa44_bare-seed.der mldsa44_oqskeypair.der mldsa44_priv-only.der mldsa44_pub-spki.der mldsa44_seed-only.der mldsa44_seed-priv.der mldsa65-cert.der mldsa65-cert.pem mldsa65-key.pem mldsa65_bare-priv.der mldsa65_bare-seed.der mldsa65_oqskeypair.der mldsa65_priv-only.der mldsa65_pub-spki.der mldsa65_seed-only.der mldsa65_seed-priv.der mldsa87-cert.der mldsa87-cert.pem mldsa87-key.pem mldsa87_bare-priv.der mldsa87_bare-seed.der mldsa87_oqskeypair.der mldsa87_priv-only.der mldsa87_pub-spki.der mldsa87_seed-only.der mldsa87_seed-priv.der
ocsp imposter-root-ca-cert.der imposter-root-ca-cert.pem imposter-root-ca-key.der imposter-root-ca-key.pem include.am index-ca-and-intermediate-cas.txt index-ca-and-intermediate-cas.txt.attr index-intermediate1-ca-issued-certs.txt index-intermediate1-ca-issued-certs.txt.attr index-intermediate2-ca-issued-certs.txt index-intermediate2-ca-issued-certs.txt.attr index-intermediate3-ca-issued-certs.txt index-intermediate3-ca-issued-certs.txt.attr intermediate1-ca-cert.der intermediate1-ca-cert.pem intermediate1-ca-key.der intermediate1-ca-key.pem intermediate2-ca-cert.der intermediate2-ca-cert.pem intermediate2-ca-key.der intermediate2-ca-key.pem intermediate3-ca-cert.der intermediate3-ca-cert.pem intermediate3-ca-key.der intermediate3-ca-key.pem ocsp-responder-cert.der ocsp-responder-cert.pem ocsp-responder-key.der ocsp-responder-key.pem openssl.cnf renewcerts-for-test.sh renewcerts.sh root-ca-cert.der root-ca-cert.pem root-ca-crl.pem root-ca-key.der root-ca-key.pem server1-cert.der server1-cert.pem server1-chain-noroot.pem server1-key.der server1-key.pem server2-cert.der server2-cert.pem server2-key.der server2-key.pem server3-cert.der server3-cert.pem server3-key.der server3-key.pem server4-cert.der server4-cert.pem server4-key.der server4-key.pem server5-cert.der server5-cert.pem server5-key.der server5-key.pem test-leaf-response.der test-multi-response.der test-response-nointern.der test-response-rsapss.der test-response.der
p521 ca-p521-key.der ca-p521-key.pem ca-p521-priv.der ca-p521-priv.pem ca-p521.der ca-p521.pem client-p521-key.der client-p521-key.pem client-p521-priv.der client-p521-priv.pem client-p521.der client-p521.pem gen-p521-certs.sh gen-p521-keys.sh include.am root-p521-key.der root-p521-key.pem root-p521-priv.der root-p521-priv.pem root-p521.der root-p521.pem server-p521-cert.pem server-p521-key.der server-p521-key.pem server-p521-priv.der server-p521-priv.pem server-p521.der server-p521.pem
renewcerts wolfssl.cnf
rpk client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.der
rsapss ca-3072-rsapss-key.der ca-3072-rsapss-key.pem ca-3072-rsapss-priv.der ca-3072-rsapss-priv.pem ca-3072-rsapss.der ca-3072-rsapss.pem ca-rsapss-key.der ca-rsapss-key.pem ca-rsapss-priv.der ca-rsapss-priv.pem ca-rsapss.der ca-rsapss.pem client-3072-rsapss-key.der client-3072-rsapss-key.pem client-3072-rsapss-priv.der client-3072-rsapss-priv.pem client-3072-rsapss.der client-3072-rsapss.pem client-rsapss-key.der client-rsapss-key.pem client-rsapss-priv.der client-rsapss-priv.pem client-rsapss.der client-rsapss.pem gen-rsapss-keys.sh include.am renew-rsapss-certs.sh root-3072-rsapss-key.der root-3072-rsapss-key.pem root-3072-rsapss-priv.der root-3072-rsapss-priv.pem root-3072-rsapss.der root-3072-rsapss.pem root-rsapss-key.der root-rsapss-key.pem root-rsapss-priv.der root-rsapss-priv.pem root-rsapss.der root-rsapss.pem server-3072-rsapss-cert.pem server-3072-rsapss-key.der server-3072-rsapss-key.pem server-3072-rsapss-priv.der server-3072-rsapss-priv.pem server-3072-rsapss.der server-3072-rsapss.pem server-mix-rsapss-cert.pem server-rsapss-cert.pem server-rsapss-key.der server-rsapss-key.pem server-rsapss-priv.der server-rsapss-priv.pem server-rsapss.der server-rsapss.pem
sia timestamping-sia-cert.pem
slhdsa bench_slhdsa_sha2_128f_key.der bench_slhdsa_sha2_128s_key.der bench_slhdsa_sha2_192f_key.der bench_slhdsa_sha2_192s_key.der bench_slhdsa_sha2_256f_key.der bench_slhdsa_sha2_256s_key.der bench_slhdsa_shake128f_key.der bench_slhdsa_shake128s_key.der bench_slhdsa_shake192f_key.der bench_slhdsa_shake192s_key.der bench_slhdsa_shake256f_key.der bench_slhdsa_shake256s_key.der client-mldsa44-priv.pem client-mldsa44-sha2.der client-mldsa44-sha2.pem client-mldsa44-shake.der client-mldsa44-shake.pem gen-slhdsa-mldsa-certs.sh include.am root-slhdsa-sha2-128s-priv.der root-slhdsa-sha2-128s-priv.pem root-slhdsa-sha2-128s.der root-slhdsa-sha2-128s.pem root-slhdsa-shake-128s-priv.der root-slhdsa-shake-128s-priv.pem root-slhdsa-shake-128s.der root-slhdsa-shake-128s.pem server-mldsa44-priv.pem server-mldsa44-sha2.der server-mldsa44-sha2.pem server-mldsa44-shake.der server-mldsa44-shake.pem
sm2 ca-sm2-key.der ca-sm2-key.pem ca-sm2-priv.der ca-sm2-priv.pem ca-sm2.der ca-sm2.pem client-sm2-key.der client-sm2-key.pem client-sm2-priv.der client-sm2-priv.pem client-sm2.der client-sm2.pem fix_sm2_spki.py gen-sm2-certs.sh gen-sm2-keys.sh include.am root-sm2-key.der root-sm2-key.pem root-sm2-priv.der root-sm2-priv.pem root-sm2.der root-sm2.pem self-sm2-cert.pem self-sm2-key.pem self-sm2-priv.pem server-sm2-cert.der server-sm2-cert.pem server-sm2-key.der server-sm2-key.pem server-sm2-priv.der server-sm2-priv.pem server-sm2.der server-sm2.pem
statickeys dh-ffdhe2048-params.pem dh-ffdhe2048-pub.der dh-ffdhe2048-pub.pem dh-ffdhe2048.der dh-ffdhe2048.pem ecc-secp256r1.der ecc-secp256r1.pem gen-static.sh include.am x25519-pub.der x25519-pub.pem x25519.der x25519.pem
test
expired expired-ca.der expired-ca.pem expired-cert.der expired-cert.pem
catalog.txt cert-bad-neg-int.der cert-bad-oid.der cert-bad-utf8.der cert-ext-ia.cfg cert-ext-ia.der cert-ext-ia.pem cert-ext-joi.cfg cert-ext-joi.der cert-ext-joi.pem cert-ext-mnc.der cert-ext-multiple.cfg cert-ext-multiple.der cert-ext-multiple.pem cert-ext-nc-combined.der cert-ext-nc-combined.pem cert-ext-nc.cfg cert-ext-nc.der cert-ext-nc.pem cert-ext-ncdns.der cert-ext-ncdns.pem cert-ext-ncip.der cert-ext-ncip.pem cert-ext-ncmixed.der cert-ext-ncmulti.der cert-ext-ncmulti.pem cert-ext-ncrid.der cert-ext-ncrid.pem cert-ext-nct.cfg cert-ext-nct.der cert-ext-nct.pem cert-ext-ndir-exc.cfg cert-ext-ndir-exc.der cert-ext-ndir-exc.pem cert-ext-ndir.cfg cert-ext-ndir.der cert-ext-ndir.pem cert-ext-ns.der cert-over-max-altnames.cfg cert-over-max-altnames.der cert-over-max-altnames.pem cert-over-max-nc.cfg cert-over-max-nc.der cert-over-max-nc.pem client-ecc-cert-ski.hex cn-ip-literal.der cn-ip-wildcard.der crit-cert.pem crit-key.pem dh1024.der dh1024.pem dh512.der dh512.pem digsigku.pem encrypteddata.msg gen-badsig.sh gen-ext-certs.sh gen-testcerts.sh include.am kari-keyid-cms.msg ktri-keyid-cms.msg ossl-trusted-cert.pem server-badaltname.der server-badaltname.pem server-badaltnull.der server-badaltnull.pem server-badcn.der server-badcn.pem server-badcnnull.der server-badcnnull.pem server-cert-ecc-badsig.der server-cert-ecc-badsig.pem server-cert-rsa-badsig.der server-cert-rsa-badsig.pem server-duplicate-policy.pem server-garbage.der server-garbage.pem server-goodalt.der server-goodalt.pem server-goodaltwild.der server-goodaltwild.pem server-goodcn.der server-goodcn.pem server-goodcnwild.der server-goodcnwild.pem server-localhost.der server-localhost.pem smime-test-canon.p7s smime-test-multipart-badsig.p7s smime-test-multipart.p7s smime-test.p7s
test-pathlen assemble-chains.sh chainA-ICA1-key.pem chainA-ICA1-pathlen0.pem chainA-assembled.pem chainA-entity-key.pem chainA-entity.pem chainB-ICA1-key.pem chainB-ICA1-pathlen0.pem chainB-ICA2-key.pem chainB-ICA2-pathlen1.pem chainB-assembled.pem chainB-entity-key.pem chainB-entity.pem chainC-ICA1-key.pem chainC-ICA1-pathlen1.pem chainC-assembled.pem chainC-entity-key.pem chainC-entity.pem chainD-ICA1-key.pem chainD-ICA1-pathlen127.pem chainD-assembled.pem chainD-entity-key.pem chainD-entity.pem chainE-ICA1-key.pem chainE-ICA1-pathlen128.pem chainE-assembled.pem chainE-entity-key.pem chainE-entity.pem chainF-ICA1-key.pem chainF-ICA1-pathlen1.pem chainF-ICA2-key.pem chainF-ICA2-pathlen0.pem chainF-assembled.pem chainF-entity-key.pem chainF-entity.pem chainG-ICA1-key.pem chainG-ICA1-pathlen0.pem chainG-ICA2-key.pem chainG-ICA2-pathlen1.pem chainG-ICA3-key.pem chainG-ICA3-pathlen99.pem chainG-ICA4-key.pem chainG-ICA4-pathlen5.pem chainG-ICA5-key.pem chainG-ICA5-pathlen20.pem chainG-ICA6-key.pem chainG-ICA6-pathlen10.pem chainG-ICA7-key.pem chainG-ICA7-pathlen100.pem chainG-assembled.pem chainG-entity-key.pem chainG-entity.pem chainH-ICA1-key.pem chainH-ICA1-pathlen0.pem chainH-ICA2-key.pem chainH-ICA2-pathlen2.pem chainH-ICA3-key.pem chainH-ICA3-pathlen2.pem chainH-ICA4-key.pem chainH-ICA4-pathlen2.pem chainH-assembled.pem chainH-entity-key.pem chainH-entity.pem chainI-ICA1-key.pem chainI-ICA1-no_pathlen.pem chainI-ICA2-key.pem chainI-ICA2-no_pathlen.pem chainI-ICA3-key.pem chainI-ICA3-pathlen2.pem chainI-assembled.pem chainI-entity-key.pem chainI-entity.pem chainJ-ICA1-key.pem chainJ-ICA1-no_pathlen.pem chainJ-ICA2-key.pem chainJ-ICA2-no_pathlen.pem chainJ-ICA3-key.pem chainJ-ICA3-no_pathlen.pem chainJ-ICA4-key.pem chainJ-ICA4-pathlen2.pem chainJ-assembled.pem chainJ-entity-key.pem chainJ-entity.pem include.am refreshkeys.sh
test-serial0 ee_normal.pem ee_serial0.pem generate_certs.sh include.am intermediate_serial0.pem root_serial0.pem root_serial0_key.pem selfsigned_nonca_serial0.pem
xmss bc_xmss_chain_ca.der bc_xmss_chain_leaf.der bc_xmss_sha2_10_256_root.der bc_xmss_sha2_16_256_root.der bc_xmssmt_sha2_20_2_256_root.der bc_xmssmt_sha2_20_4_256_root.der bc_xmssmt_sha2_40_8_256_root.der include.am
ca-cert-chain.der ca-cert.der ca-cert.pem ca-ecc-cert.der ca-ecc-cert.pem ca-ecc-key.der ca-ecc-key.pem ca-ecc384-cert.der ca-ecc384-cert.pem ca-ecc384-key.der ca-ecc384-key.pem ca-key-pkcs8-attribute.der ca-key.der ca-key.pem check_dates.sh client-absolute-urn.pem client-ca-cert.der client-ca-cert.pem client-ca.pem client-cert-ext.der client-cert-ext.pem client-cert.der client-cert.pem client-crl-dist.der client-crl-dist.pem client-ecc-ca-cert.der client-ecc-ca-cert.pem client-ecc-cert.der client-ecc-cert.pem client-ecc384-cert.der client-ecc384-cert.pem client-ecc384-key.der client-ecc384-key.pem client-key.der client-key.pem client-keyEnc.pem client-keyPub.der client-keyPub.pem client-relative-uri.pem client-uri-cert.pem csr.attr.der csr.dsa.der csr.dsa.pem csr.ext.der csr.signed.der dh-priv-2048.der dh-priv-2048.pem dh-pub-2048.der dh-pub-2048.pem dh-pubkey-2048.der dh2048.der dh2048.pem dh3072.der dh3072.pem dh4096.der dh4096.pem dsa-pubkey-2048.der dsa2048.der dsa2048.pem dsa3072.der dsaparams.der dsaparams.pem ecc-client-key.der ecc-client-key.pem ecc-client-keyPub.der ecc-client-keyPub.pem ecc-key-comp.pem ecc-keyPkcs8.der ecc-keyPkcs8.pem ecc-keyPkcs8Enc.der ecc-keyPkcs8Enc.pem ecc-keyPub.der ecc-keyPub.pem ecc-params.der ecc-params.pem ecc-privOnlyCert.pem ecc-privOnlyKey.pem ecc-privkey.der ecc-privkey.pem ecc-privkeyPkcs8.der ecc-privkeyPkcs8.pem ecc-rsa-server.p12 empty-issuer-cert.pem entity-no-ca-bool-cert.pem entity-no-ca-bool-key.pem fpki-cert.der fpki-certpol-cert.der gen_revoked.sh include.am renewcerts.sh rid-cert.der rsa-pub-2048.pem rsa2048.der rsa3072.der server-cert-chain.der server-cert.der server-cert.pem server-ecc-comp.der server-ecc-comp.pem server-ecc-rsa.der server-ecc-rsa.pem server-ecc-self.der server-ecc-self.pem server-ecc.der server-ecc.pem server-ecc384-cert.der server-ecc384-cert.pem server-ecc384-key.der server-ecc384-key.pem server-key.der server-key.pem server-keyEnc.pem server-keyPkcs8.der server-keyPkcs8.pem server-keyPkcs8Enc.der server-keyPkcs8Enc.pem server-keyPkcs8Enc12.pem server-keyPkcs8Enc2.pem server-keyPub.der server-keyPub.pem server-revoked-cert.pem server-revoked-key.pem taoCert.txt test-ber-exp02-05-2022.p7b test-degenerate.p7b test-multiple-recipients.p7b test-servercert-rc2.p12 test-servercert.p12 test-stream-dec.p7b test-stream-sign.p7b wolfssl-website-ca.pem x942dh2048.der x942dh2048.pem
cmake
consumer CMakeLists.txt README.md main.c
modules FindARIA.cmake FindOQS.cmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.in
debian
source format
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.in
doc
dox_comments
header_files aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h puf.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wc_she.h wc_slhdsa.h wolfio.h
header_files-ja aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wolfio.h
formats
html
html_changes
search search.css search.js
customdoxygen.css doxygen.css menu.js menudata.js tabs.css
Doxyfile footer.html header.html mainpage.dox
pdf Doxyfile header.tex
images wolfssl_logo.png
QUIC.md README.txt README_DOXYGEN check_api.sh generate_documentation.sh include.am
examples
asn1 asn1.c dumpasn1.cfg gen_oid_names.rb include.am oid_names.h
async Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.h
benchmark include.am tls_bench.c tls_bench.h
client client.c client.h client.sln client.vcproj client.vcxproj include.am
configs README.md include.am user_settings_EBSnet.h user_settings_all.h user_settings_arduino.h user_settings_baremetal.h user_settings_ca.h user_settings_curve25519nonblock.h user_settings_dtls13.h user_settings_eccnonblock.h user_settings_espressif.h user_settings_fipsv2.h user_settings_fipsv5.h user_settings_min_ecc.h user_settings_openssl_compat.h user_settings_pkcs7.h user_settings_platformio.h user_settings_pq.h user_settings_rsa_only.h user_settings_stm32.h user_settings_template.h user_settings_tls12.h user_settings_tls13.h user_settings_wolfboot_keytools.h user_settings_wolfssh.h user_settings_wolftpm.h
crypto_policies
default wolfssl.txt
future wolfssl.txt
legacy wolfssl.txt
echoclient echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quit
echoserver echoserver.c echoserver.h echoserver.sln echoserver.vcproj echoserver.vcxproj include.am
ocsp_responder include.am ocsp_responder.c ocsp_responder.h
pem include.am pem.c
sctp include.am sctp-client-dtls.c sctp-client.c sctp-server-dtls.c sctp-server.c
server include.am server.c server.h server.sln server.vcproj server.vcxproj
README.md include.am
linuxkm
patches
5.10.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch
5.10.236 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch
5.14.0-570.58.1.el9_6 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v14-570v58v1-el9_6.patch
5.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch
5.17 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch
5.17-ubuntu-jammy-tegra WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17-ubuntu-jammy-tegra.patch
6.1.73 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch
6.12 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch
6.15 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch
7.0 WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-7v0.patch
regen-patches.sh
Kbuild Makefile README.md get_thread_size.c include.am linuxkm-fips-hash-wrapper.sh linuxkm-fips-hash.c linuxkm_memory.c linuxkm_memory.h linuxkm_wc_port.h lkcapi_aes_glue.c lkcapi_dh_glue.c lkcapi_ecdh_glue.c lkcapi_ecdsa_glue.c lkcapi_glue.c lkcapi_rsa_glue.c lkcapi_sha_glue.c module_exports.c.template module_hooks.c pie_redirect_table.c wolfcrypt.lds x86_vector_register_glue.c
m4 ax_add_am_macro.m4 ax_am_jobserver.m4 ax_am_macros.m4 ax_append_compile_flags.m4 ax_append_flag.m4 ax_append_link_flags.m4 ax_append_to_file.m4 ax_atomic.m4 ax_bsdkm.m4 ax_check_compile_flag.m4 ax_check_link_flag.m4 ax_compiler_version.m4 ax_count_cpus.m4 ax_create_generic_config.m4 ax_debug.m4 ax_file_escapes.m4 ax_harden_compiler_flags.m4 ax_linuxkm.m4 ax_print_to_file.m4 ax_pthread.m4 ax_require_defined.m4 ax_tls.m4 ax_vcs_checkout.m4 hexversion.m4 lib_socket_nsl.m4 visibility.m4
mcapi
wolfcrypt_mcapi.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
zlib.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README crypto.c crypto.h include.am mcapi_test.c user_settings.h
mplabx
wolfcrypt_benchmark.X
nbproject configurations.xml include.am project.xml
Makefile
wolfcrypt_test.X
nbproject configurations.xml include.am project.xml
Makefile
wolfssl.X
nbproject configurations.xml include.am project.xml
Makefile
PIC32MZ-serial.h README benchmark_main.c include.am test_main.c user_settings.h
mqx
util_lib
Sources include.am util.c util.h
wolfcrypt_benchmark
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfcrypt_test
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
wolfssl include.am
wolfssl_client
Debugger K70FN1M0.mem init_kinetis.tcl mass_erase_kinetis.tcl
Sources include.am main.c main.h
ReferencedRSESystems.xml wolfssl_client_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launch
README
rpm include.am spec.in
scripts
bench bench_functions.sh
aria-cmake-build-test.sh asn1_oid_sum.pl benchmark.test benchmark_compare.sh cleanup_testfiles.sh crl-gen-openssl.test crl-revoked.test dertoc.pl dtls.test dtlscid.test external.test google.test include.am makedistsmall.sh memtest.sh ocsp-responder-openssl-interop.test ocsp-stapling-with-ca-as-responder.test ocsp-stapling-with-wolfssl-responder.test ocsp-stapling.test ocsp-stapling2.test ocsp-stapling_tls13multi.test ocsp.test openssl.test openssl_srtp.test pem.test ping.test pkcallbacks.test psk.test resume.test rsapss.test sniffer-gen.sh sniffer-ipv6.pcap sniffer-static-rsa.pcap sniffer-testsuite.test sniffer-tls12-keylog.out sniffer-tls12-keylog.pcap sniffer-tls12-keylog.sslkeylog sniffer-tls13-dh-resume.pcap sniffer-tls13-dh.pcap sniffer-tls13-ecc-resume.pcap sniffer-tls13-ecc.pcap sniffer-tls13-hrr.pcap sniffer-tls13-keylog.out sniffer-tls13-keylog.pcap sniffer-tls13-keylog.sslkeylog sniffer-tls13-x25519-resume.pcap sniffer-tls13-x25519.pcap stm32l4-v4_0_1_build.sh tls13.test trusted_peer.test unit.test.in user_settings_asm.sh
src bio.c conf.c crl.c dtls.c dtls13.c include.am internal.c keys.c ocsp.c pk.c pk_ec.c pk_rsa.c quic.c sniffer.c ssl.c ssl_api_cert.c ssl_api_crl_ocsp.c ssl_api_pk.c ssl_asn1.c ssl_bn.c ssl_certman.c ssl_crypto.c ssl_ech.c ssl_load.c ssl_misc.c ssl_p7p12.c ssl_sess.c ssl_sk.c tls.c tls13.c wolfio.c x509.c x509_str.c
sslSniffer
sslSnifferTest README_WIN.md include.am snifftest.c sslSniffTest.vcproj sslSniffTest.vcxproj
README.md sslSniffer.vcproj sslSniffer.vcxproj
support gen-debug-trace-error-codes.sh include.am wolfssl.pc.in
tests
api api.h api_decl.h create_ocsp_test_blobs.py include.am test_aes.c test_aes.h test_arc4.c test_arc4.h test_ascon.c test_ascon.h test_ascon_kats.h test_asn.c test_asn.h test_blake2.c test_blake2.h test_camellia.c test_camellia.h test_certman.c test_certman.h test_chacha.c test_chacha.h test_chacha20_poly1305.c test_chacha20_poly1305.h test_cmac.c test_cmac.h test_curve25519.c test_curve25519.h test_curve448.c test_curve448.h test_des3.c test_des3.h test_dh.c test_dh.h test_digest.h test_dsa.c test_dsa.h test_dtls.c test_dtls.h test_ecc.c test_ecc.h test_ed25519.c test_ed25519.h test_ed448.c test_ed448.h test_evp.c test_evp.h test_evp_cipher.c test_evp_cipher.h test_evp_digest.c test_evp_digest.h test_evp_pkey.c test_evp_pkey.h test_hash.c test_hash.h test_hmac.c test_hmac.h test_md2.c test_md2.h test_md4.c test_md4.h test_md5.c test_md5.h test_mldsa.c test_mldsa.h test_mlkem.c test_mlkem.h test_ocsp.c test_ocsp.h test_ocsp_test_blobs.h test_ossl_asn1.c test_ossl_asn1.h test_ossl_bio.c test_ossl_bio.h test_ossl_bn.c test_ossl_bn.h test_ossl_cipher.c test_ossl_cipher.h test_ossl_dgst.c test_ossl_dgst.h test_ossl_dh.c test_ossl_dh.h test_ossl_dsa.c test_ossl_dsa.h test_ossl_ec.c test_ossl_ec.h test_ossl_ecx.c test_ossl_ecx.h test_ossl_mac.c test_ossl_mac.h test_ossl_obj.c test_ossl_obj.h test_ossl_p7p12.c test_ossl_p7p12.h test_ossl_pem.c test_ossl_pem.h test_ossl_rand.c test_ossl_rand.h test_ossl_rsa.c test_ossl_rsa.h test_ossl_sk.c test_ossl_sk.h test_ossl_x509.c test_ossl_x509.h test_ossl_x509_acert.c test_ossl_x509_acert.h test_ossl_x509_crypto.c test_ossl_x509_crypto.h test_ossl_x509_ext.c test_ossl_x509_ext.h test_ossl_x509_info.c test_ossl_x509_info.h test_ossl_x509_io.c test_ossl_x509_io.h test_ossl_x509_lu.c test_ossl_x509_lu.h test_ossl_x509_name.c test_ossl_x509_name.h test_ossl_x509_pk.c test_ossl_x509_pk.h test_ossl_x509_str.c test_ossl_x509_str.h test_ossl_x509_vp.c test_ossl_x509_vp.h test_pkcs12.c test_pkcs12.h test_pkcs7.c test_pkcs7.h test_poly1305.c test_poly1305.h test_random.c test_random.h test_rc2.c test_rc2.h test_ripemd.c test_ripemd.h test_rsa.c test_rsa.h test_sha.c test_sha.h test_sha256.c test_sha256.h test_sha3.c test_sha3.h test_sha512.c test_sha512.h test_she.c test_she.h test_signature.c test_signature.h test_slhdsa.c test_slhdsa.h test_sm2.c test_sm2.h test_sm3.c test_sm3.h test_sm4.c test_sm4.h test_tls.c test_tls.h test_tls13.c test_tls13.h test_tls_ext.c test_tls_ext.h test_wc_encrypt.c test_wc_encrypt.h test_wolfmath.c test_wolfmath.h test_x509.c test_x509.h
emnet
IP IP.h
Makefile emnet_nonblock_test.c emnet_shim.c
freertos-mem-track-repro FreeRTOS.h repro.c run.sh semphr.h task.h user_settings.h
swdev .gitignore Makefile README.md swdev.c swdev.h swdev_loader.c swdev_loader.h user_settings.h
CONF_FILES_README.md NCONF_test.cnf README TXT_DB.txt api.c include.am quic.c srp.c suites.c test-altchains.conf test-chains.conf test-dhprime.conf test-dtls-downgrade.conf test-dtls-fails-cipher.conf test-dtls-fails.conf test-dtls-group.conf test-dtls-mtu.conf test-dtls-reneg-client.conf test-dtls-reneg-server.conf test-dtls-resume.conf test-dtls-sha2.conf test-dtls-srtp-fails.conf test-dtls-srtp.conf test-dtls.conf test-dtls13-cid.conf test-dtls13-downgrade-fails.conf test-dtls13-downgrade.conf test-dtls13-pq-hybrid-extra-frag.conf test-dtls13-pq-hybrid-extra.conf test-dtls13-pq-hybrid-frag.conf test-dtls13-pq-standalone-frag.conf test-dtls13-pq-standalone.conf test-dtls13-psk.conf test-dtls13.conf test-ecc-cust-curves.conf test-ed25519.conf test-ed448.conf test-enckeys.conf test-fails.conf test-maxfrag-dtls.conf test-maxfrag.conf test-p521.conf test-psk-no-id-sha2.conf test-psk-no-id.conf test-psk.conf test-rsapss.conf test-sctp-sha2.conf test-sctp.conf test-sha2.conf test-sig.conf test-sm2.conf test-tls-downgrade.conf test-tls13-down.conf test-tls13-ecc.conf test-tls13-pq-hybrid-extra.conf test-tls13-pq-hybrid.conf test-tls13-pq-standalone.conf test-tls13-psk-certs.conf test-tls13-psk.conf test-tls13-slhdsa-fail.conf test-tls13-slhdsa-sha2.conf test-tls13-slhdsa-shake.conf test-tls13.conf test-trustpeer.conf test.conf unit.c unit.h utils.c utils.h w64wrapper.c
testsuite include.am testsuite.c testsuite.sln testsuite.vcproj testsuite.vcxproj utils.c utils.h
tirtos
packages
ti
net
wolfssl
tests
EK_TM4C1294XL
wolfcrypt
benchmark TM4C1294NC.icf benchmark.cfg main.c package.bld.hide package.xdc
test TM4C1294NC.icf main.c package.bld.hide package.xdc test.cfg
package.bld package.xdc package.xs
.gitignore README include.am products.mak wolfssl.bld wolfssl.mak
wolfcrypt
benchmark README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.am
src
port
Espressif
esp_crt_bundle README.md cacrt_all.pem cacrt_deprecated.pem cacrt_local.pem esp_crt_bundle.c gen_crt_bundle.py pio_install_cryptography.py
README.md esp32_aes.c esp32_mp.c esp32_sha.c esp32_util.c esp_sdk_mem_lib.c esp_sdk_time_lib.c esp_sdk_wifi_lib.c
Renesas README.md renesas_common.c renesas_fspsm_aes.c renesas_fspsm_rsa.c renesas_fspsm_sha.c renesas_fspsm_util.c renesas_rx64_hw_sha.c renesas_rx64_hw_util.c renesas_tsip_aes.c renesas_tsip_rsa.c renesas_tsip_sha.c renesas_tsip_util.c
af_alg afalg_aes.c afalg_hash.c wc_afalg.c
aria aria-crypt.c aria-cryptocb.c
arm armv8-32-aes-asm.S armv8-32-aes-asm_c.c armv8-32-chacha-asm.S armv8-32-chacha-asm_c.c armv8-32-curve25519.S armv8-32-curve25519_c.c armv8-32-mlkem-asm.S armv8-32-mlkem-asm_c.c armv8-32-poly1305-asm.S armv8-32-poly1305-asm_c.c armv8-32-sha256-asm.S armv8-32-sha256-asm_c.c armv8-32-sha3-asm.S armv8-32-sha3-asm_c.c armv8-32-sha512-asm.S armv8-32-sha512-asm_c.c armv8-aes-asm.S armv8-aes-asm_c.c armv8-aes.c armv8-chacha-asm.S armv8-chacha-asm_c.c armv8-curve25519.S armv8-curve25519_c.c armv8-mlkem-asm.S armv8-mlkem-asm_c.c armv8-poly1305-asm.S armv8-poly1305-asm_c.c armv8-sha256-asm.S armv8-sha256-asm_c.c armv8-sha256.c armv8-sha3-asm.S armv8-sha3-asm_c.c armv8-sha512-asm.S armv8-sha512-asm_c.c armv8-sha512.c cryptoCell.c cryptoCellHash.c thumb2-aes-asm.S thumb2-aes-asm_c.c thumb2-chacha-asm.S thumb2-chacha-asm_c.c thumb2-curve25519.S thumb2-curve25519_c.c thumb2-mlkem-asm.S thumb2-mlkem-asm_c.c thumb2-poly1305-asm.S thumb2-poly1305-asm_c.c thumb2-sha256-asm.S thumb2-sha256-asm_c.c thumb2-sha3-asm.S thumb2-sha3-asm_c.c thumb2-sha512-asm.S thumb2-sha512-asm_c.c
atmel README.md atmel.c
autosar README.md cryif.c crypto.c csm.c include.am test.c
caam README.md caam_aes.c caam_doc.pdf caam_driver.c caam_error.c caam_integrity.c caam_qnx.c caam_sha.c wolfcaam_aes.c wolfcaam_cmac.c wolfcaam_ecdsa.c wolfcaam_fsl_nxp.c wolfcaam_hash.c wolfcaam_hmac.c wolfcaam_init.c wolfcaam_qnx.c wolfcaam_rsa.c wolfcaam_seco.c wolfcaam_x25519.c
cavium README.md README_Octeon.md cavium_nitrox.c cavium_octeon_sync.c
cuda README.md aes-cuda.cu
cypress README.md psoc6_crypto.c
devcrypto README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.c
intel README.md quickassist.c quickassist_mem.c quickassist_sync.c
iotsafe iotsafe.c
kcapi README.md kcapi_aes.c kcapi_dh.c kcapi_ecc.c kcapi_hash.c kcapi_hmac.c kcapi_rsa.c
liboqs liboqs.c
maxim README.md max3266x.c maxq10xx.c
mynewt mynewt_port.c
nxp README.md README_SE050.md casper_port.c dcp_port.c hashcrypt_port.c ksdk_port.c se050_port.c
pic32 pic32mz-crypt.c
ppc32 ppc32-sha256-asm.S ppc32-sha256-asm_c.c ppc32-sha256-asm_cr.c
psa README.md psa.c psa_aes.c psa_hash.c psa_pkcbs.c
riscv riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.c
rpi_pico README.md pico.c
silabs README.md silabs_aes.c silabs_ecc.c silabs_hash.c silabs_random.c
st README.md STM32MP13.md STM32MP25.md stm32.c stsafe.c
ti ti-aes.c ti-ccm.c ti-des3.c ti-hash.c
tropicsquare README.md tropic01.c
xilinx xil-aesgcm.c xil-sha3.c xil-versal-glue.c xil-versal-trng.c
nrf51.c
ASN_TEMPLATE.md aes.c aes_asm.S aes_asm.asm aes_gcm_asm.S aes_gcm_asm.asm aes_gcm_x86_asm.S aes_xts_asm.S aes_xts_asm.asm arc4.c ascon.c asm.c asn.c asn_orig.c async.c blake2b.c blake2s.c camellia.c chacha.c chacha20_poly1305.c chacha_asm.S chacha_asm.asm cmac.c coding.c compress.c cpuid.c cryptocb.c curve25519.c curve448.c des3.c dh.c dilithium.c dsa.c ecc.c ecc_fp.c eccsi.c ed25519.c ed448.c error.c evp.c evp_pk.c falcon.c fe_448.c fe_low_mem.c fe_operations.c fe_x25519_128.h fe_x25519_asm.S fp_mont_small.i fp_mul_comba_12.i fp_mul_comba_17.i fp_mul_comba_20.i fp_mul_comba_24.i fp_mul_comba_28.i fp_mul_comba_3.i fp_mul_comba_32.i fp_mul_comba_4.i fp_mul_comba_48.i fp_mul_comba_6.i fp_mul_comba_64.i fp_mul_comba_7.i fp_mul_comba_8.i fp_mul_comba_9.i fp_mul_comba_small_set.i fp_sqr_comba_12.i fp_sqr_comba_17.i fp_sqr_comba_20.i fp_sqr_comba_24.i fp_sqr_comba_28.i fp_sqr_comba_3.i fp_sqr_comba_32.i fp_sqr_comba_4.i fp_sqr_comba_48.i fp_sqr_comba_6.i fp_sqr_comba_64.i fp_sqr_comba_7.i fp_sqr_comba_8.i fp_sqr_comba_9.i fp_sqr_comba_small_set.i ge_448.c ge_low_mem.c ge_operations.c hash.c hmac.c hpke.c include.am integer.c kdf.c logging.c md2.c md4.c md5.c memory.c misc.c pkcs12.c pkcs7.c poly1305.c poly1305_asm.S poly1305_asm.asm puf.c pwdbased.c random.c rc2.c ripemd.c rng_bank.c rsa.c sakke.c sha.c sha256.c sha256_asm.S sha3.c sha3_asm.S sha512.c sha512_asm.S signature.c siphash.c sm2.c sm3.c sm3_asm.S sm4.c sp_arm32.c sp_arm64.c sp_armthumb.c sp_c32.c sp_c64.c sp_cortexm.c sp_dsp32.c sp_int.c sp_sm2_arm32.c sp_sm2_arm64.c sp_sm2_armthumb.c sp_sm2_c32.c sp_sm2_c64.c sp_sm2_cortexm.c sp_sm2_x86_64.c sp_sm2_x86_64_asm.S sp_x86_64.c sp_x86_64_asm.S sp_x86_64_asm.asm srp.c tfm.c wc_dsp.c wc_encrypt.c wc_lms.c wc_lms_impl.c wc_mldsa_asm.S wc_mlkem.c wc_mlkem_asm.S wc_mlkem_poly.c wc_pkcs11.c wc_port.c wc_she.c wc_slhdsa.c wc_xmss.c wc_xmss_impl.c wolfentropy.c wolfevent.c wolfmath.c
test README.md include.am test-VS2022.sln test-VS2022.vcxproj test-VS2022.vcxproj.user test.c test.h test.sln test.vcproj test_paths.h.in
wolfssl
openssl aes.h asn1.h asn1t.h bio.h bn.h buffer.h camellia.h cmac.h cms.h compat_types.h conf.h crypto.h des.h dh.h dsa.h ec.h ec25519.h ec448.h ecdh.h ecdsa.h ed25519.h ed448.h engine.h err.h evp.h fips_rand.h hmac.h include.am kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pkcs12.h pkcs7.h rand.h rc4.h ripemd.h rsa.h safestack.h sha.h sha3.h srp.h ssl.h ssl23.h stack.h tls1.h txt_db.h ui.h x509.h x509_vfy.h x509v3.h
wolfcrypt
port
Espressif esp-sdk-lib.h esp32-crypt.h esp_crt_bundle.h
Renesas renesas-fspsm-crypt.h renesas-fspsm-types.h renesas-rx64-hw-crypt.h renesas-tsip-crypt.h renesas_cmn.h renesas_fspsm_internal.h renesas_sync.h renesas_tsip_internal.h renesas_tsip_types.h
af_alg afalg_hash.h wc_afalg.h
aria aria-crypt.h aria-cryptocb.h
arm cryptoCell.h
atmel atmel.h
autosar CryIf.h Crypto.h Csm.h StandardTypes.h
caam caam_driver.h caam_error.h caam_qnx.h wolfcaam.h wolfcaam_aes.h wolfcaam_cmac.h wolfcaam_ecdsa.h wolfcaam_fsl_nxp.h wolfcaam_hash.h wolfcaam_qnx.h wolfcaam_rsa.h wolfcaam_seco.h wolfcaam_sha.h wolfcaam_x25519.h
cavium cavium_nitrox.h cavium_octeon_sync.h
cypress psoc6_crypto.h
devcrypto wc_devcrypto.h
intel quickassist.h quickassist_mem.h quickassist_sync.h
iotsafe iotsafe.h
kcapi kcapi_dh.h kcapi_ecc.h kcapi_hash.h kcapi_hmac.h kcapi_rsa.h wc_kcapi.h
liboqs liboqs.h
maxim max3266x-cryptocb.h max3266x.h maxq10xx.h
nxp casper_port.h dcp_port.h hashcrypt_port.h ksdk_port.h se050_port.h
pic32 pic32mz-crypt.h
psa psa.h
riscv riscv-64-asm.h
rpi_pico pico.h
silabs silabs_aes.h silabs_ecc.h silabs_hash.h silabs_random.h
st stm32.h stsafe.h
ti ti-ccm.h ti-hash.h
tropicsquare tropic01.h
xilinx xil-sha3.h xil-versal-glue.h xil-versal-trng.h
nrf51.h
aes.h arc4.h ascon.h asn.h asn_public.h async.h blake2-impl.h blake2-int.h blake2.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cpuid.h cryptocb.h curve25519.h curve448.h des3.h dh.h dilithium.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h falcon.h fe_448.h fe_operations.h fips_test.h ge_448.h ge_operations.h hash.h hmac.h hpke.h include.am integer.h kdf.h libwolfssl_sources.h libwolfssl_sources_asm.h logging.h md2.h md4.h md5.h mem_track.h memory.h misc.h mpi_class.h mpi_superclass.h oid_sum.h pkcs11.h pkcs12.h pkcs7.h poly1305.h puf.h pwdbased.h random.h rc2.h ripemd.h rng_bank.h rsa.h sakke.h selftest.h settings.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h sm2.h sm3.h sm4.h sp.h sp_int.h srp.h tfm.h types.h visibility.h wc_encrypt.h wc_lms.h wc_mlkem.h wc_pkcs11.h wc_port.h wc_she.h wc_slhdsa.h wc_xmss.h wolfentropy.h wolfevent.h wolfmath.h
callbacks.h certs_test.h certs_test_sm.h crl.h error-ssl.h include.am internal.h ocsp.h options.h.in quic.h sniffer.h sniffer_error.h sniffer_error.rc ssl.h test.h version.h version.h.in wolfio.h
wrapper
Ada
examples
src aes_verify_main.adb rsa_verify_main.adb sha256_main.adb spark_sockets.adb spark_sockets.ads spark_terminal.adb spark_terminal.ads tls_client.adb tls_client.ads tls_client_main.adb tls_server.adb tls_server.ads tls_server_main.adb
.gitignore alire.toml examples.gpr
tests
src
support test_support.adb test_support.ads tests_root_suite.adb tests_root_suite.ads
aes_bindings_tests.adb aes_bindings_tests.ads rsa_verify_bindings_tests.adb rsa_verify_bindings_tests.ads sha256_bindings_tests.adb sha256_bindings_tests.ads tests.adb
.gitignore README.md alire.toml tests.gpr valgrind.supp
.gitignore README.md ada_binding.c alire.toml default.gpr include.am restricted.adc user_settings.h wolfssl-full_runtime.adb wolfssl-full_runtime.ads wolfssl.adb wolfssl.ads wolfssl.gpr
CSharp
wolfCrypt-Test
Properties AssemblyInfo.cs
App.config wolfCrypt-Test.cs wolfCrypt-Test.csproj
wolfSSL-DTLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-PSK-Server.cs wolfSSL-DTLS-PSK-Server.csproj
wolfSSL-DTLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-DTLS-Server.cs wolfSSL-DTLS-Server.csproj
wolfSSL-Example-IOCallbacks
Properties AssemblyInfo.cs
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csproj
wolfSSL-TLS-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Client.cs wolfSSL-TLS-Client.csproj
wolfSSL-TLS-PSK-Client
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Client.cs wolfSSL-TLS-PSK-Client.csproj
wolfSSL-TLS-PSK-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-PSK-Server.cs wolfSSL-TLS-PSK-Server.csproj
wolfSSL-TLS-Server
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-Server.cs wolfSSL-TLS-Server.csproj
wolfSSL-TLS-ServerThreaded
Properties AssemblyInfo.cs
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csproj
wolfSSL_CSharp
Properties AssemblyInfo.cs Resources.Designer.cs Resources.resx
X509.cs wolfCrypt.cs wolfSSL.cs wolfSSL_CSharp.csproj
README.md include.am user_settings.h wolfSSL_CSharp.sln wolfssl.vcxproj
python README.md
rust
wolfssl-wolfcrypt
src aes.rs blake2.rs chacha20_poly1305.rs cmac.rs cmac_mac.rs curve25519.rs dh.rs dilithium.rs ecc.rs ecdsa.rs ed25519.rs ed448.rs fips.rs hkdf.rs hmac.rs hmac_mac.rs kdf.rs lib.rs lms.rs mlkem.rs mlkem_kem.rs pbkdf2_password_hash.rs prf.rs random.rs rsa.rs rsa_pkcs1v15.rs sha.rs sha_digest.rs sys.rs
tests
common mod.rs
test_aes.rs test_blake2.rs test_chacha20_poly1305.rs test_cmac.rs test_cmac_mac.rs test_curve25519.rs test_dh.rs test_dilithium.rs test_ecc.rs test_ecdsa.rs test_ed25519.rs test_ed448.rs test_hkdf.rs test_hmac.rs test_hmac_mac.rs test_kdf.rs test_lms.rs test_mlkem.rs test_mlkem_kem.rs test_pbkdf2_password_hash.rs test_prf.rs test_random.rs test_rsa.rs test_rsa_pkcs1v15.rs test_sha.rs test_sha_digest.rs test_wolfcrypt.rs
CHANGELOG.md Cargo.lock Cargo.toml Makefile README.md build.rs headers.h
Makefile README.md include.am
include.am
zephyr
samples
wolfssl_benchmark
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_test
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_sock
boards native_sim.conf
src tls_sock.c
CMakeLists.txt README install_sample.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl_tls_thread
boards native_sim.conf nrf5340dk_nrf5340_cpuapp.conf nrf5340dk_nrf5340_cpuapp_ns.conf
src tls_threaded.c
CMakeLists.txt README install_sample.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl options.h
CMakeLists.txt Kconfig Kconfig.tls-generic README.md include.am module.yml user_settings-no-malloc.h user_settings.h zephyr_init.c
.codespellexcludelines .cyignore .editorconfig .gitignore .wolfssl_known_macro_extras AUTHORS CMakeLists.txt CMakePresets.json CMakeSettings.json COPYING ChangeLog.md INSTALL LICENSING LPCExpresso.cproject LPCExpresso.project Makefile.am README README-async.md README.md SCRIPTS-LIST SECURITY-POLICY.md SECURITY-REPORT-TEMPLATE.md Vagrantfile autogen.sh commit-tests.sh configure.ac fips-check.sh fips-hash.sh gencertbuf.pl input pull_to_vagrant.sh quit resource.h stamp-h.in valgrind-bash.supp valgrind-error.sh wnr-example.conf wolfssl-VS2022.vcxproj wolfssl.rc wolfssl.vcproj wolfssl.vcxproj wolfssl64.sln
.clangd .gitignore DOCS.md Makefile README.md assert.c core.c crypto.c env.c fs.c http.c ini.c json.c log.c luna.h main.c makext.mk path.c process.c request.c sqlite.c stash.c template.c util.c
wolfssl/wolfcrypt/src/aes.c raw
    1/* aes.c
    2 *
    3 * Copyright (C) 2006-2026 wolfSSL Inc.
    4 *
    5 * This file is part of wolfSSL.
    6 *
    7 * wolfSSL is free software; you can redistribute it and/or modify
    8 * it under the terms of the GNU General Public License as published by
    9 * the Free Software Foundation; either version 3 of the License, or
   10 * (at your option) any later version.
   11 *
   12 * wolfSSL is distributed in the hope that it will be useful,
   13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15 * GNU General Public License for more details.
   16 *
   17 * You should have received a copy of the GNU General Public License
   18 * along with this program; if not, write to the Free Software
   19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
   20 */
   21
   22/*
   23
   24DESCRIPTION
   25This library provides the interfaces to the Advanced Encryption Standard (AES)
   26for encrypting and decrypting data. AES is the standard known for a symmetric
   27block cipher mechanism that uses n-bit binary string parameter key with 128-bits,
   28192-bits, and 256-bits of key sizes.
   29
   30*/
   31
   32/*
   33 * AES Build Options:
   34 *
   35 * Core:
   36 * NO_AES:                  Disable AES support entirely          default: off
   37 * WOLFSSL_AES_128:         Enable AES-128 key size               default: on
   38 * WOLFSSL_AES_192:         Enable AES-192 key size               default: on
   39 * WOLFSSL_AES_256:         Enable AES-256 key size               default: on
   40 * AES_MAX_KEY_SIZE:        Maximum AES key size in bits           default: 256
   41 *
   42 * Cipher Modes:
   43 * HAVE_AES_CBC:            Enable AES-CBC mode                   default: on
   44 * HAVE_AES_ECB:            Enable AES-ECB mode                   default: off
   45 * HAVE_AES_DECRYPT:        Enable AES decryption                 default: on
   46 * WOLFSSL_AES_COUNTER:     Enable AES-CTR mode                   default: off
   47 * WOLFSSL_AES_CFB:         Enable AES-CFB mode                   default: off
   48 * WOLFSSL_NO_AES_CFB_1_8:  Disable AES-CFB-1 and AES-CFB-8      default: off
   49 * WOLFSSL_AES_OFB:         Enable AES-OFB mode                   default: off
   50 * WOLFSSL_AES_DIRECT:      Enable direct AES encrypt/decrypt API default: off
   51 * WOLFSSL_AES_XTS:         Enable AES-XTS mode                   default: off
   52 * WOLFSSL_AES_CTS:         Enable AES-CTS (ciphertext stealing)  default: off
   53 * WOLFSSL_AES_SIV:         Enable AES-SIV (synthetic IV) mode    default: off
   54 * WOLFSSL_AES_EAX:         Enable AES-EAX AEAD mode              default: off
   55 * WOLFSSL_CMAC:            Enable AES-CMAC (RFC 4493)            default: off
   56 * HAVE_AESCCM:             Enable AES-CCM mode                   default: off
   57 * HAVE_AES_KEYWRAP:        Enable AES key wrap (RFC 3394)        default: off
   58 * WOLFSSL_AES_CBC_LENGTH_CHECKS: Validate CBC input length       default: off
   59 *
   60 * AES-GCM:
   61 * HAVE_AESGCM:             Enable AES-GCM mode                   default: off
   62 * HAVE_AESGCM_DECRYPT:     Enable AES-GCM decryption             default: on
   63 *                           (when HAVE_AESGCM is enabled)
   64 * WOLFSSL_AESGCM_STREAM:   Enable streaming AES-GCM API          default: off
   65 * WC_AES_GCM_DEC_AUTH_EARLY: Authenticate tag before decryption  default: off
   66 * GCM_SMALL:               Small GCM table, saves memory         default: off
   67 * GCM_TABLE:               Full 4-bit GCM lookup table, faster   default: off
   68 * GCM_TABLE_4BIT:          Explicit 4-bit GCM table mode         default: off
   69 * GCM_WORD32:              Use 32-bit word GCM implementation    default: off
   70 * GCM_GMULT_LEN:           GCM GMULT length optimization         default: off
   71 *
   72 * AES-XTS Stream:
   73 * WOLFSSL_AESXTS_STREAM:   Enable streaming AES-XTS API          default: off
   74 * WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING:
   75 *                           Disable XTS stream request accounting default: off
   76 * WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS:
   77 *                           Support both encrypt and decrypt keys default: off
   78 *                           simultaneously in XTS context
   79 *
   80 * Performance / Side-Channel:
   81 * WOLFSSL_AESNI:           Enable Intel AES-NI instructions      default: off
   82 * WOLFSSL_AESNI_BY4:       AES-NI 4-block parallel processing    default: off
   83 * WOLFSSL_AESNI_BY6:       AES-NI 6-block parallel processing    default: off
   84 * USE_INTEL_SPEEDUP:       Intel AVX/AVX2 for AES acceleration   default: off
   85 * WOLFSSL_AES_SMALL_TABLES: Use smaller AES S-box tables         default: off
   86 * WOLFSSL_AES_NO_UNROLL:   Disable AES round loop unrolling      default: off
   87 * WOLFSSL_AES_TOUCH_LINES: Touch all cache lines for             default: off
   88 *                           side-channel resistance
   89 * WC_AES_BITSLICED:        Use bitsliced AES implementation      default: off
   90 * AES_GCM_GMULT_NCT:       GCM GMULT non-constant-time          default: off
   91 * NO_WOLFSSL_ALLOC_ALIGN:  Disable aligned memory allocation     default: off
   92 *
   93 * Hardware Acceleration (AES-specific):
   94 * WC_ASYNC_ENABLE_AES:     Enable async AES operations           default: off
   95 * WOLFSSL_CRYPTOCELL_AES:  CryptoCell AES acceleration           default: off
   96 * WOLFSSL_DEVCRYPTO_AES:   /dev/crypto AES acceleration          default: off
   97 * WOLFSSL_DEVCRYPTO_CBC:   /dev/crypto AES-CBC acceleration      default: off
   98 * WOLFSSL_KCAPI_AES:       Linux kernel crypto API for AES       default: off
   99 * WOLFSSL_NO_KCAPI_AES_CBC: Disable KCAPI AES-CBC                default: off
  100 * WOLFSSL_NRF51_AES:       nRF51 hardware AES                    default: off
  101 * WOLFSSL_PSA_NO_AES:      Disable PSA AES                       default: off
  102 * WOLFSSL_SCE_NO_AES:      Disable Renesas SCE AES               default: off
  103 * NO_IMX6_CAAM_AES:        Disable i.MX6 CAAM AES               default: off
  104 * WOLFSSL_AFALG_XILINX_AES: AF_ALG Xilinx AES acceleration      default: off
  105 * NO_WOLFSSL_ESP32_CRYPT_AES: Disable ESP32 AES acceleration     default: off
  106 * STM32_CRYPTO_AES_ONLY:   STM32 AES-only crypto mode            default: off
  107 *
  108 * Debug:
  109 * WC_DEBUG_CIPHER_LIFECYCLE: Debug cipher init/free lifecycle     default: off
  110 * WOLFSSL_HW_METRICS:      Track hardware acceleration usage     default: off
  111 */
  112
  113#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
  114
  115#if !defined(NO_AES)
  116
  117/* Tip: Locate the software cipher modes by searching for "Software AES" */
  118
  119#if FIPS_VERSION3_GE(2,0,0)
  120    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
  121    #define FIPS_NO_WRAPPERS
  122
  123    #ifdef USE_WINDOWS_API
  124        #pragma code_seg(".fipsA$b")
  125        #pragma const_seg(".fipsB$b")
  126    #endif
  127#endif
  128
  129#include <wolfssl/wolfcrypt/aes.h>
  130
  131#ifdef WOLFSSL_AESNI
  132#include <wmmintrin.h>
  133#include <emmintrin.h>
  134#include <smmintrin.h>
  135#endif /* WOLFSSL_AESNI */
  136
  137#include <wolfssl/wolfcrypt/cpuid.h>
  138
  139#ifdef WOLF_CRYPTO_CB
  140    #include <wolfssl/wolfcrypt/cryptocb.h>
  141#endif
  142
  143#ifdef WOLFSSL_NXP_HASHCRYPT_AES
  144    #include <wolfssl/wolfcrypt/port/nxp/hashcrypt_port.h>
  145#endif
  146
  147#ifdef WOLFSSL_SECO_CAAM
  148#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
  149#endif
  150
  151#ifdef WOLFSSL_IMXRT_DCP
  152    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
  153#endif
  154#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
  155    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
  156#endif
  157#ifdef WOLFSSL_MICROCHIP_TA100
  158    #include <wolfssl/wolfcrypt/port/atmel/atmel.h>
  159#endif
  160#ifdef WOLFSSL_CMAC
  161    #include <wolfssl/wolfcrypt/cmac.h>
  162#endif
  163
  164#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
  165    #include <wolfssl/wolfcrypt/port/psa/psa.h>
  166#endif
  167
  168#if defined(WOLFSSL_MAX3266X) || defined(WOLFSSL_MAX3266X_OLD)
  169    #include <wolfssl/wolfcrypt/port/maxim/max3266x.h>
  170#ifdef MAX3266X_CB
  171    /* Revert back to SW so HW CB works */
  172    /* HW only works for AES: ECB, CBC, and partial via ECB for other modes */
  173    #include <wolfssl/wolfcrypt/port/maxim/max3266x-cryptocb.h>
  174    /* Turn off MAX3266X_AES in the context of this file when using CB */
  175    #undef MAX3266X_AES
  176#endif
  177#endif
  178
  179#if defined(WOLFSSL_TI_CRYPT)
  180    #include <wolfcrypt/src/port/ti/ti-aes.c>
  181
  182    #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
  183        wc_AesEncryptDirect(aes, outBlock, inBlock)
  184    #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
  185        wc_AesDecryptDirect(aes, outBlock, inBlock)
  186#else
  187
  188
  189#if defined(WOLFSSL_PSOC6_CRYPTO)
  190    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
  191#endif /* WOLFSSL_PSOC6_CRYPTO */
  192
  193#ifdef NO_INLINE
  194    #include <wolfssl/wolfcrypt/misc.h>
  195#else
  196    #define WOLFSSL_MISC_INCLUDED
  197    #include <wolfcrypt/src/misc.c>
  198#endif
  199
  200#if !defined(WOLFSSL_RISCV_ASM)
  201
  202#ifdef WOLFSSL_IMX6_CAAM_BLOB
  203    /* case of possibly not using hardware acceleration for AES but using key
  204       blobs */
  205    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
  206#endif
  207
  208#ifdef DEBUG_AESNI
  209    #include <stdio.h>
  210#endif
  211
  212#ifdef _MSC_VER
  213    /* 4127 warning constant while(1)  */
  214    #pragma warning(disable: 4127)
  215#endif
  216
  217#if (!defined(WOLFSSL_ARMASM) && FIPS_VERSION3_GE(6,0,0)) || \
  218    FIPS_VERSION3_GE(7,0,0)
  219    const unsigned int wolfCrypt_FIPS_aes_ro_sanity[2] =
  220                                                     { 0x1a2b3c4d, 0x00000002 };
  221    int wolfCrypt_FIPS_AES_sanity(void)
  222    {
  223        return 0;
  224    }
  225#endif
  226
  227/* Define AES implementation includes and functions */
  228#if defined(STM32_CRYPTO)
  229     /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
  230
  231#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
  232
  233    static WARN_UNUSED_RESULT int wc_AesEncrypt(
  234        Aes* aes, const byte* inBlock, byte* outBlock)
  235    {
  236        int ret = 0;
  237    #ifdef WOLFSSL_STM32_CUBEMX
  238        CRYP_HandleTypeDef hcryp;
  239    #else
  240        CRYP_InitTypeDef cryptInit;
  241        CRYP_KeyInitTypeDef keyInit;
  242    #endif
  243
  244#ifdef WC_DEBUG_CIPHER_LIFECYCLE
  245        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  246        if (ret < 0)
  247            return ret;
  248#endif
  249
  250    #ifdef WOLFSSL_STM32U5_DHUK
  251        ret = wolfSSL_CryptHwMutexLock();
  252        if (ret != 0)
  253            return ret;
  254
  255        /* Handle making use of wrapped key */
  256        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
  257            CRYP_ConfigTypeDef Config = {0};
  258
  259            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key,
  260                aes->keylen, aes->dhukIV, aes->dhukIVLen);
  261            if (ret != HAL_OK) {
  262                WOLFSSL_MSG("Error with DHUK key unwrap");
  263                ret = BAD_FUNC_ARG;
  264            }
  265            /* reconfigure for using unwrapped key now */
  266            HAL_CRYP_GetConfig(&hcryp, &Config);
  267            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
  268            Config.KeySelect = CRYP_KEYSEL_NORMAL;
  269            Config.Algorithm = CRYP_AES_ECB;
  270            Config.DataType  = CRYP_DATATYPE_8B;
  271            Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
  272            HAL_CRYP_SetConfig(&hcryp, &Config);
  273        }
  274        else {
  275            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
  276            if (ret == 0) {
  277                hcryp.Init.Algorithm  = CRYP_AES_ECB;
  278                ret = HAL_CRYP_Init(&hcryp);
  279                if (ret != HAL_OK) {
  280                    ret = BAD_FUNC_ARG;
  281                }
  282            }
  283        }
  284
  285        if (ret == HAL_OK) {
  286            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
  287                    (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
  288            if (ret != HAL_OK) {
  289                ret = WC_TIMEOUT_E;
  290            }
  291        }
  292        HAL_CRYP_DeInit(&hcryp);
  293    #elif defined(WOLFSSL_STM32_CUBEMX)
  294        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
  295        if (ret != 0)
  296            return ret;
  297
  298        ret = wolfSSL_CryptHwMutexLock();
  299        if (ret != 0)
  300            return ret;
  301
  302    #if defined(STM32_HAL_V2)
  303        hcryp.Init.Algorithm  = CRYP_AES_ECB;
  304    #elif defined(STM32_CRYPTO_AES_ONLY)
  305        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
  306        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
  307        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
  308    #endif
  309        if (HAL_CRYP_Init(&hcryp) != HAL_OK) {
  310            ret = BAD_FUNC_ARG;
  311        }
  312
  313        if (ret == 0) {
  314        #if defined(STM32_HAL_V2)
  315            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
  316                (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
  317        #elif defined(STM32_CRYPTO_AES_ONLY)
  318            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
  319                outBlock, STM32_HAL_TIMEOUT);
  320        #else
  321            ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
  322                outBlock, STM32_HAL_TIMEOUT);
  323        #endif
  324            if (ret != HAL_OK) {
  325                ret = WC_TIMEOUT_E;
  326            }
  327            HAL_CRYP_DeInit(&hcryp);
  328        }
  329
  330    #else /* Standard Peripheral Library */
  331        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
  332        if (ret != 0)
  333            return ret;
  334
  335        ret = wolfSSL_CryptHwMutexLock();
  336        if (ret != 0)
  337            return ret;
  338
  339        /* reset registers to their default values */
  340        CRYP_DeInit();
  341
  342        /* setup key */
  343        CRYP_KeyInit(&keyInit);
  344
  345        /* set direction and mode */
  346        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
  347        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
  348        CRYP_Init(&cryptInit);
  349
  350        /* enable crypto processor */
  351        CRYP_Cmd(ENABLE);
  352
  353        /* flush IN/OUT FIFOs */
  354        CRYP_FIFOFlush();
  355
  356        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
  357        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
  358        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
  359        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
  360
  361        /* wait until the complete message has been processed */
  362        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
  363
  364        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
  365        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
  366        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
  367        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
  368
  369        /* disable crypto processor */
  370        CRYP_Cmd(DISABLE);
  371    #endif /* WOLFSSL_STM32_CUBEMX */
  372        wolfSSL_CryptHwMutexUnLock();
  373        wc_Stm32_Aes_Cleanup();
  374
  375        return ret;
  376    }
  377#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
  378
  379#ifdef HAVE_AES_DECRYPT
  380    #if defined(WOLFSSL_AES_DIRECT)
  381    static WARN_UNUSED_RESULT int wc_AesDecrypt(
  382        Aes* aes, const byte* inBlock, byte* outBlock)
  383    {
  384        int ret = 0;
  385    #ifdef WOLFSSL_STM32_CUBEMX
  386        CRYP_HandleTypeDef hcryp;
  387    #else
  388        CRYP_InitTypeDef cryptInit;
  389        CRYP_KeyInitTypeDef keyInit;
  390    #endif
  391
  392#ifdef WC_DEBUG_CIPHER_LIFECYCLE
  393        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  394        if (ret < 0)
  395            return ret;
  396#endif
  397
  398    #ifdef WOLFSSL_STM32U5_DHUK
  399        ret = wolfSSL_CryptHwMutexLock();
  400        if (ret != 0)
  401            return ret;
  402
  403        /* Handle making use of wrapped key */
  404        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
  405            CRYP_ConfigTypeDef Config;
  406
  407            XMEMSET(&Config, 0, sizeof(Config));
  408            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key,
  409                aes->keylen, aes->dhukIV, aes->dhukIVLen);
  410            if (ret != HAL_OK) {
  411                WOLFSSL_MSG("Error with DHUK unwrap");
  412                ret = BAD_FUNC_ARG;
  413            }
  414            /* reconfigure for using unwrapped key now */
  415            HAL_CRYP_GetConfig(&hcryp, &Config);
  416            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
  417            Config.KeySelect = CRYP_KEYSEL_NORMAL;
  418            Config.Algorithm = CRYP_AES_ECB;
  419            Config.DataType  = CRYP_DATATYPE_8B;
  420            Config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
  421            HAL_CRYP_SetConfig(&hcryp, &Config);
  422        }
  423        else {
  424            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
  425            if (ret == 0) {
  426                hcryp.Init.Algorithm  = CRYP_AES_ECB;
  427                ret = HAL_CRYP_Init(&hcryp);
  428                if (ret != HAL_OK) {
  429                    ret = BAD_FUNC_ARG;
  430                }
  431            }
  432        }
  433
  434        if (ret == HAL_OK) {
  435            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
  436                    (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
  437            if (ret != HAL_OK) {
  438                ret = WC_TIMEOUT_E;
  439            }
  440        }
  441        HAL_CRYP_DeInit(&hcryp);
  442    #elif defined(WOLFSSL_STM32_CUBEMX)
  443        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
  444        if (ret != 0)
  445            return ret;
  446
  447        ret = wolfSSL_CryptHwMutexLock();
  448        if (ret != 0)
  449            return ret;
  450
  451    #if defined(STM32_HAL_V2)
  452        hcryp.Init.Algorithm  = CRYP_AES_ECB;
  453    #elif defined(STM32_CRYPTO_AES_ONLY)
  454        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
  455        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
  456        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
  457    #endif
  458        HAL_CRYP_Init(&hcryp);
  459
  460    #if defined(STM32_HAL_V2)
  461        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, WC_AES_BLOCK_SIZE,
  462            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
  463    #elif defined(STM32_CRYPTO_AES_ONLY)
  464        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
  465            outBlock, STM32_HAL_TIMEOUT);
  466    #else
  467        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, WC_AES_BLOCK_SIZE,
  468            outBlock, STM32_HAL_TIMEOUT);
  469    #endif
  470        if (ret != HAL_OK) {
  471            ret = WC_TIMEOUT_E;
  472        }
  473        HAL_CRYP_DeInit(&hcryp);
  474
  475    #else /* Standard Peripheral Library */
  476        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
  477        if (ret != 0)
  478            return ret;
  479
  480        ret = wolfSSL_CryptHwMutexLock();
  481        if (ret != 0)
  482            return ret;
  483
  484        /* reset registers to their default values */
  485        CRYP_DeInit();
  486
  487        /* set direction and key */
  488        CRYP_KeyInit(&keyInit);
  489        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
  490        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
  491        CRYP_Init(&cryptInit);
  492
  493        /* enable crypto processor */
  494        CRYP_Cmd(ENABLE);
  495
  496        /* wait until decrypt key has been initialized */
  497        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
  498
  499        /* set direction and mode */
  500        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
  501        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
  502        CRYP_Init(&cryptInit);
  503
  504        /* enable crypto processor */
  505        CRYP_Cmd(ENABLE);
  506
  507        /* flush IN/OUT FIFOs */
  508        CRYP_FIFOFlush();
  509
  510        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
  511        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
  512        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
  513        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
  514
  515        /* wait until the complete message has been processed */
  516        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
  517
  518        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
  519        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
  520        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
  521        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
  522
  523        /* disable crypto processor */
  524        CRYP_Cmd(DISABLE);
  525    #endif /* WOLFSSL_STM32_CUBEMX */
  526        wolfSSL_CryptHwMutexUnLock();
  527        wc_Stm32_Aes_Cleanup();
  528
  529        return ret;
  530    }
  531    #endif /* WOLFSSL_AES_DIRECT */
  532#endif /* HAVE_AES_DECRYPT */
  533
  534#elif defined(HAVE_COLDFIRE_SEC)
  535    /* Freescale Coldfire SEC support for CBC mode.
  536     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
  537    #include "sec.h"
  538    #include "mcf5475_sec.h"
  539    #include "mcf5475_siu.h"
  540#elif defined(FREESCALE_LTC)
  541    #include "fsl_ltc.h"
  542    #if defined(FREESCALE_LTC_AES_GCM)
  543        #undef NEED_AES_TABLES
  544        #undef GCM_TABLE
  545    #endif
  546
  547        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
  548        static WARN_UNUSED_RESULT int wc_AesEncrypt(
  549            Aes* aes, const byte* inBlock, byte* outBlock)
  550        {
  551            word32 keySize = 0;
  552            byte* key = (byte*)aes->key;
  553            int ret = wc_AesGetKeySize(aes, &keySize);
  554            if (ret != 0)
  555                return ret;
  556
  557#ifdef WC_DEBUG_CIPHER_LIFECYCLE
  558            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  559            if (ret < 0)
  560                return ret;
  561#endif
  562
  563            if (wolfSSL_CryptHwMutexLock() == 0) {
  564                LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
  565                    key, keySize);
  566                wolfSSL_CryptHwMutexUnLock();
  567            }
  568            return 0;
  569        }
  570        #ifdef HAVE_AES_DECRYPT
  571        static WARN_UNUSED_RESULT int wc_AesDecrypt(
  572            Aes* aes, const byte* inBlock, byte* outBlock)
  573        {
  574            word32 keySize = 0;
  575            byte* key = (byte*)aes->key;
  576            int ret = wc_AesGetKeySize(aes, &keySize);
  577            if (ret != 0)
  578                return ret;
  579
  580#ifdef WC_DEBUG_CIPHER_LIFECYCLE
  581            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  582            if (ret < 0)
  583                return ret;
  584#endif
  585
  586            if (wolfSSL_CryptHwMutexLock() == 0) {
  587                LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, WC_AES_BLOCK_SIZE,
  588                    key, keySize, kLTC_EncryptKey);
  589                wolfSSL_CryptHwMutexUnLock();
  590            }
  591            return 0;
  592        }
  593        #endif
  594
  595#elif defined(WOLFSSL_PIC32MZ_CRYPT)
  596
  597    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
  598
  599    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
  600    static WARN_UNUSED_RESULT int wc_AesEncrypt(
  601        Aes* aes, const byte* inBlock, byte* outBlock)
  602    {
  603#ifdef WC_DEBUG_CIPHER_LIFECYCLE
  604        {
  605            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  606            if (ret < 0)
  607                return ret;
  608        }
  609#endif
  610        /* Thread mutex protection handled in Pic32Crypto */
  611        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
  612            outBlock, inBlock, WC_AES_BLOCK_SIZE,
  613            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
  614    }
  615    #endif
  616
  617    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
  618    static WARN_UNUSED_RESULT int wc_AesDecrypt(
  619        Aes* aes, const byte* inBlock, byte* outBlock)
  620    {
  621#ifdef WC_DEBUG_CIPHER_LIFECYCLE
  622        {
  623            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  624            if (ret < 0)
  625                return ret;
  626        }
  627#endif
  628        /* Thread mutex protection handled in Pic32Crypto */
  629        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
  630            outBlock, inBlock, WC_AES_BLOCK_SIZE,
  631            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
  632    }
  633    #endif
  634
  635#elif defined(WOLFSSL_NRF51_AES)
  636    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
  637    #include "wolfssl/wolfcrypt/port/nrf51.h"
  638
  639    static WARN_UNUSED_RESULT int wc_AesEncrypt(
  640        Aes* aes, const byte* inBlock, byte* outBlock)
  641    {
  642        int ret;
  643
  644#ifdef WC_DEBUG_CIPHER_LIFECYCLE
  645        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  646        if (ret < 0)
  647            return ret;
  648#endif
  649
  650        ret = wolfSSL_CryptHwMutexLock();
  651        if (ret == 0) {
  652            ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds,
  653                                    outBlock);
  654            wolfSSL_CryptHwMutexUnLock();
  655        }
  656        return ret;
  657    }
  658
  659    #ifdef HAVE_AES_DECRYPT
  660        #error nRF51 AES Hardware does not support decrypt
  661    #endif /* HAVE_AES_DECRYPT */
  662
  663#elif defined(WOLFSSL_ESP32_CRYPT) && \
  664     !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
  665    #include <esp_log.h>
  666    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
  667    #define TAG "aes"
  668
  669    /* We'll use SW for fallback:
  670     *   unsupported key lengths. (e.g. ESP32-S3)
  671     *   chipsets not implemented.
  672     *   hardware busy. */
  673    #define NEED_AES_TABLES
  674    #define NEED_AES_HW_FALLBACK
  675    #define NEED_SOFTWARE_AES_SETKEY
  676    #undef  WOLFSSL_AES_DIRECT
  677    #define WOLFSSL_AES_DIRECT
  678
  679    /* Encrypt: If we choose to never have a fallback to SW: */
  680    #if !defined(NEED_AES_HW_FALLBACK) && \
  681        (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
  682    /* calling this one when NO_AES_192 is defined */
  683    static WARN_UNUSED_RESULT int wc_AesEncrypt(
  684        Aes* aes, const byte* inBlock, byte* outBlock)
  685    {
  686        int ret;
  687
  688    #ifdef WC_DEBUG_CIPHER_LIFECYCLE
  689        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  690        if (ret < 0)
  691            return ret;
  692    #endif
  693
  694        /* Thread mutex protection handled in esp_aes_hw_InUse */
  695    #ifdef NEED_AES_HW_FALLBACK
  696        if (wc_esp32AesSupportedKeyLen(aes)) {
  697            ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
  698        }
  699    #else
  700        ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
  701    #endif
  702        return ret;
  703    }
  704    #endif
  705
  706    /* Decrypt: If we choose to never have a fallback to SW: */
  707    #if !defined(NEED_AES_HW_FALLBACK) && \
  708        (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
  709    static WARN_UNUSED_RESULT int wc_AesDecrypt(
  710        Aes* aes, const byte* inBlock, byte* outBlock)
  711    {
  712        int ret = 0;
  713#ifdef WC_DEBUG_CIPHER_LIFECYCLE
  714        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  715        if (ret < 0)
  716            return ret;
  717#endif
  718        /* Thread mutex protection handled in esp_aes_hw_InUse */
  719    #ifdef NEED_AES_HW_FALLBACK
  720        if (wc_esp32AesSupportedKeyLen(aes)) {
  721            ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
  722        }
  723        else {
  724            ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
  725        }
  726    #else
  727        /* if we don't need fallback, always use HW */
  728        ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
  729    #endif
  730        return ret;
  731    }
  732    #endif
  733
  734#elif defined(WOLFSSL_AESNI)
  735
  736    #define NEED_AES_TABLES
  737
  738    /* Each platform needs to query info type 1 from cpuid to see if aesni is
  739     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
  740     */
  741
  742    #ifndef AESNI_ALIGN
  743        #define AESNI_ALIGN 16
  744    #endif
  745
  746    /* note that all write access to these static variables must be idempotent,
  747     * as arranged by Check_CPU_support_AES(), else they will be susceptible to
  748     * data races.
  749     */
  750    static int checkedAESNI = 0;
  751    static int haveAESNI  = 0;
  752    static cpuid_flags_t intel_flags = WC_CPUID_INITIALIZER;
  753
  754    static WARN_UNUSED_RESULT int Check_CPU_support_AES(void)
  755    {
  756        cpuid_get_flags_ex(&intel_flags);
  757
  758        return IS_INTEL_AESNI(intel_flags) != 0;
  759    }
  760
  761
  762    /* tell C compiler these are asm functions in case any mix up of ABI underscore
  763       prefix between clang/gcc/llvm etc */
  764    #ifdef HAVE_AES_CBC
  765        void AES_CBC_encrypt_AESNI(const unsigned char* in, unsigned char* out,
  766                             unsigned char* ivec, unsigned long length,
  767                             const unsigned char* KS, int nr)
  768                             XASM_LINK("AES_CBC_encrypt_AESNI");
  769
  770        #ifdef HAVE_AES_DECRYPT
  771            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
  772                void AES_CBC_decrypt_AESNI_by4(const unsigned char* in, unsigned char* out,
  773                                         unsigned char* ivec, unsigned long length,
  774                                         const unsigned char* KS, int nr)
  775                                         XASM_LINK("AES_CBC_decrypt_AESNI_by4");
  776            #elif defined(WOLFSSL_AESNI_BY6)
  777                void AES_CBC_decrypt_AESNI_by6(const unsigned char* in, unsigned char* out,
  778                                         unsigned char* ivec, unsigned long length,
  779                                         const unsigned char* KS, int nr)
  780                                         XASM_LINK("AES_CBC_decrypt_AESNI_by6");
  781            #else /* WOLFSSL_AESNI_BYx */
  782                void AES_CBC_decrypt_AESNI_by8(const unsigned char* in, unsigned char* out,
  783                                         unsigned char* ivec, unsigned long length,
  784                                         const unsigned char* KS, int nr)
  785                                         XASM_LINK("AES_CBC_decrypt_AESNI_by8");
  786            #endif /* WOLFSSL_AESNI_BYx */
  787        #endif /* HAVE_AES_DECRYPT */
  788    #endif /* HAVE_AES_CBC */
  789
  790    void AES_ECB_encrypt_AESNI(const unsigned char* in, unsigned char* out,
  791                         unsigned long length, const unsigned char* KS, int nr)
  792                         XASM_LINK("AES_ECB_encrypt_AESNI");
  793
  794    #ifdef HAVE_AES_DECRYPT
  795        void AES_ECB_decrypt_AESNI(const unsigned char* in, unsigned char* out,
  796                             unsigned long length, const unsigned char* KS, int nr)
  797                             XASM_LINK("AES_ECB_decrypt_AESNI");
  798    #endif
  799
  800    void AES_128_Key_Expansion_AESNI(const unsigned char* userkey,
  801                               unsigned char* key_schedule)
  802                               XASM_LINK("AES_128_Key_Expansion_AESNI");
  803
  804    void AES_192_Key_Expansion_AESNI(const unsigned char* userkey,
  805                               unsigned char* key_schedule)
  806                               XASM_LINK("AES_192_Key_Expansion_AESNI");
  807
  808    void AES_256_Key_Expansion_AESNI(const unsigned char* userkey,
  809                               unsigned char* key_schedule)
  810                               XASM_LINK("AES_256_Key_Expansion_AESNI");
  811
  812
  813    static WARN_UNUSED_RESULT int AES_set_encrypt_key_AESNI(
  814        const unsigned char *userKey, const int bits, Aes* aes)
  815    {
  816        int ret;
  817
  818        ASSERT_SAVED_VECTOR_REGISTERS();
  819
  820        if (!userKey || !aes)
  821            return BAD_FUNC_ARG;
  822
  823        switch (bits) {
  824            case 128:
  825               AES_128_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 10;
  826               return 0;
  827            case 192:
  828               AES_192_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 12;
  829               return 0;
  830            case 256:
  831               AES_256_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 14;
  832               return 0;
  833            default:
  834                ret = BAD_FUNC_ARG;
  835        }
  836
  837        return ret;
  838    }
  839
  840    #ifdef HAVE_AES_DECRYPT
  841        static WARN_UNUSED_RESULT int AES_set_decrypt_key_AESNI(
  842            const unsigned char* userKey, const int bits, Aes* aes)
  843        {
  844            word32 nr;
  845            WC_DECLARE_VAR(temp_key, Aes, 1, 0);
  846            __m128i *Key_Schedule;
  847            __m128i *Temp_Key_Schedule;
  848
  849            ASSERT_SAVED_VECTOR_REGISTERS();
  850
  851            if (!userKey || !aes)
  852                return BAD_FUNC_ARG;
  853
  854#ifdef WOLFSSL_SMALL_STACK
  855            if ((temp_key = (Aes *)XMALLOC(sizeof *aes, aes->heap,
  856                                           DYNAMIC_TYPE_AES)) == NULL)
  857                return MEMORY_E;
  858#endif
  859
  860            if (AES_set_encrypt_key_AESNI(userKey,bits,temp_key)
  861                == WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
  862                WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
  863                return BAD_FUNC_ARG;
  864            }
  865
  866            Key_Schedule = (__m128i*)aes->key;
  867            Temp_Key_Schedule = (__m128i*)temp_key->key;
  868
  869            nr = temp_key->rounds;
  870            aes->rounds = nr;
  871
  872            Key_Schedule[nr] = Temp_Key_Schedule[0];
  873            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
  874            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
  875            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
  876            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
  877            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
  878            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
  879            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
  880            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
  881            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
  882
  883            if (nr>10) {
  884                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
  885                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
  886            }
  887
  888            if (nr>12) {
  889                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
  890                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
  891            }
  892
  893            Key_Schedule[0] = Temp_Key_Schedule[nr];
  894
  895            WC_FREE_VAR_EX(temp_key, aes->heap, DYNAMIC_TYPE_AES);
  896
  897            return 0;
  898        }
  899    #endif /* HAVE_AES_DECRYPT */
  900
  901#elif defined(WOLFSSL_ARMASM)
  902#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
  903static cpuid_flags_t cpuid_flags = WC_CPUID_INITIALIZER;
  904
  905static void Check_CPU_support_HwCrypto(Aes* aes)
  906{
  907    cpuid_get_flags_ex(&cpuid_flags);
  908    aes->use_aes_hw_crypto = IS_AARCH64_AES(cpuid_flags);
  909#ifdef HAVE_AESGCM
  910    aes->use_pmull_hw_crypto = IS_AARCH64_PMULL(cpuid_flags);
  911    aes->use_sha3_hw_crypto = IS_AARCH64_SHA3(cpuid_flags);
  912#endif
  913}
  914#endif /* __aarch64__ && !WOLFSSL_ARMASM_NO_HW_CRYPTO */
  915
  916#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
  917    defined(WOLFSSL_AESGCM_STREAM)
  918static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
  919    byte* outBlock)
  920{
  921#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
  922#if !defined(__aarch64__)
  923    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
  924#else
  925    if (aes->use_aes_hw_crypto) {
  926        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
  927           (int)aes->rounds);
  928    }
  929    else
  930#endif /* !__aarch64__ */
  931#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
  932#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
  933    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
  934    {
  935        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
  936            (const unsigned char*)aes->key, aes->rounds);
  937    }
  938#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
  939    {
  940        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
  941            (int)aes->rounds);
  942    }
  943#endif
  944
  945    return 0;
  946}
  947#endif
  948
  949#if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
  950static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
  951    byte* outBlock)
  952{
  953#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
  954#if !defined(__aarch64__)
  955    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
  956#else
  957    if (aes->use_aes_hw_crypto) {
  958        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
  959            (int)aes->rounds);
  960    }
  961    else
  962#endif /* !__aarch64__ */
  963#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
  964#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
  965    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
  966    {
  967        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
  968            (byte*)aes->key, (int)aes->rounds);
  969    }
  970#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
  971    {
  972        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
  973            (int)aes->rounds);
  974    }
  975#endif
  976    return 0;
  977}
  978#endif /* HAVE_AES_DECRYPT && WOLFSSL_AES_DIRECT */
  979
  980#elif defined(FREESCALE_MMCAU)
  981    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
  982     * through the CAU/mmCAU library. Documentation located in
  983     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
  984     * Guide (See note in README). */
  985    #ifdef FREESCALE_MMCAU_CLASSIC
  986        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
  987        #include "cau_api.h"
  988    #else
  989        #include "fsl_mmcau.h"
  990    #endif
  991
  992    static WARN_UNUSED_RESULT int wc_AesEncrypt(
  993        Aes* aes, const byte* inBlock, byte* outBlock)
  994    {
  995#ifdef WC_DEBUG_CIPHER_LIFECYCLE
  996        {
  997            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
  998            if (ret < 0)
  999                return ret;
 1000        }
 1001#endif
 1002
 1003        if (wolfSSL_CryptHwMutexLock() == 0) {
 1004        #ifdef FREESCALE_MMCAU_CLASSIC
 1005            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
 1006                WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
 1007                return BAD_ALIGN_E;
 1008            }
 1009            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
 1010        #else
 1011            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
 1012                                 outBlock);
 1013        #endif
 1014            wolfSSL_CryptHwMutexUnLock();
 1015        }
 1016        return 0;
 1017    }
 1018    #ifdef HAVE_AES_DECRYPT
 1019    static WARN_UNUSED_RESULT int wc_AesDecrypt(
 1020        Aes* aes, const byte* inBlock, byte* outBlock)
 1021    {
 1022#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 1023        {
 1024            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 1025            if (ret < 0)
 1026                return ret;
 1027        }
 1028#endif
 1029        if (wolfSSL_CryptHwMutexLock() == 0) {
 1030        #ifdef FREESCALE_MMCAU_CLASSIC
 1031            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
 1032                WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
 1033                return BAD_ALIGN_E;
 1034            }
 1035            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
 1036        #else
 1037            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
 1038                                 outBlock);
 1039        #endif
 1040            wolfSSL_CryptHwMutexUnLock();
 1041        }
 1042        return 0;
 1043    }
 1044    #endif /* HAVE_AES_DECRYPT */
 1045
 1046#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
 1047        && !defined(WOLFSSL_QNX_CAAM)) || \
 1048      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
 1049        defined(HAVE_AESCCM))
 1050        static WARN_UNUSED_RESULT int wc_AesEncrypt(
 1051            Aes* aes, const byte* inBlock, byte* outBlock)
 1052        {
 1053#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 1054            {
 1055                int ret =
 1056                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 1057                if (ret < 0)
 1058                    return ret;
 1059            }
 1060#endif
 1061            return wc_AesEncryptDirect(aes, outBlock, inBlock);
 1062        }
 1063
 1064#elif defined(WOLFSSL_AFALG)
 1065    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
 1066
 1067#elif defined(WOLFSSL_DEVCRYPTO_AES)
 1068    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
 1069
 1070#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
 1071    #include "hal_data.h"
 1072
 1073    #ifndef WOLFSSL_SCE_AES256_HANDLE
 1074        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
 1075    #endif
 1076
 1077    #ifndef WOLFSSL_SCE_AES192_HANDLE
 1078        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
 1079    #endif
 1080
 1081    #ifndef WOLFSSL_SCE_AES128_HANDLE
 1082        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
 1083    #endif
 1084
 1085    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
 1086        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
 1087    {
 1088        word32 ret;
 1089
 1090        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
 1091                CRYPTO_WORD_ENDIAN_BIG) {
 1092            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
 1093        }
 1094
 1095        switch (aes->keylen) {
 1096        #ifdef WOLFSSL_AES_128
 1097            case AES_128_KEY_SIZE:
 1098                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
 1099                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
 1100                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
 1101                        (word32*)outBlock);
 1102                break;
 1103        #endif
 1104        #ifdef WOLFSSL_AES_192
 1105            case AES_192_KEY_SIZE:
 1106                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
 1107                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
 1108                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
 1109                        (word32*)outBlock);
 1110                break;
 1111        #endif
 1112        #ifdef WOLFSSL_AES_256
 1113            case AES_256_KEY_SIZE:
 1114                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
 1115                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
 1116                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
 1117                        (word32*)outBlock);
 1118                break;
 1119        #endif
 1120            default:
 1121                WOLFSSL_MSG("Unknown key size");
 1122                return BAD_FUNC_ARG;
 1123        }
 1124
 1125        if (ret != SSP_SUCCESS) {
 1126            /* revert input */
 1127            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
 1128            return WC_HW_E;
 1129        }
 1130
 1131        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
 1132                CRYPTO_WORD_ENDIAN_BIG) {
 1133            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
 1134            if (inBlock != outBlock) {
 1135                /* revert input */
 1136                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
 1137            }
 1138        }
 1139        return 0;
 1140    }
 1141
 1142    #if defined(HAVE_AES_DECRYPT)
 1143    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
 1144        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
 1145    {
 1146        word32 ret;
 1147
 1148        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
 1149                CRYPTO_WORD_ENDIAN_BIG) {
 1150            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
 1151        }
 1152
 1153        switch (aes->keylen) {
 1154        #ifdef WOLFSSL_AES_128
 1155            case AES_128_KEY_SIZE:
 1156                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
 1157                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
 1158                        (sz / sizeof(word32)), (word32*)inBlock,
 1159                        (word32*)outBlock);
 1160                break;
 1161        #endif
 1162        #ifdef WOLFSSL_AES_192
 1163            case AES_192_KEY_SIZE:
 1164                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
 1165                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
 1166                        (sz / sizeof(word32)), (word32*)inBlock,
 1167                        (word32*)outBlock);
 1168                break;
 1169        #endif
 1170        #ifdef WOLFSSL_AES_256
 1171            case AES_256_KEY_SIZE:
 1172                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
 1173                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
 1174                        (sz / sizeof(word32)), (word32*)inBlock,
 1175                        (word32*)outBlock);
 1176                break;
 1177        #endif
 1178            default:
 1179                WOLFSSL_MSG("Unknown key size");
 1180                return BAD_FUNC_ARG;
 1181        }
 1182        if (ret != SSP_SUCCESS) {
 1183            return WC_HW_E;
 1184        }
 1185
 1186        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
 1187                CRYPTO_WORD_ENDIAN_BIG) {
 1188            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
 1189            if (inBlock != outBlock) {
 1190                /* revert input */
 1191                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
 1192            }
 1193        }
 1194
 1195        return 0;
 1196    }
 1197    #endif /* HAVE_AES_DECRYPT */
 1198
 1199    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
 1200    static WARN_UNUSED_RESULT int wc_AesEncrypt(
 1201        Aes* aes, const byte* inBlock, byte* outBlock)
 1202    {
 1203#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 1204        {
 1205            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 1206            if (ret < 0)
 1207                return ret;
 1208        }
 1209#endif
 1210        return AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
 1211    }
 1212    #endif
 1213
 1214    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
 1215    static WARN_UNUSED_RESULT int wc_AesDecrypt(
 1216        Aes* aes, const byte* inBlock, byte* outBlock)
 1217    {
 1218#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 1219        {
 1220            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 1221            if (ret < 0)
 1222                return ret;
 1223        }
 1224#endif
 1225        return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
 1226    }
 1227    #endif
 1228
 1229#elif defined(WOLFSSL_KCAPI_AES)
 1230    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
 1231    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
 1232        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
 1233        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
 1234        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
 1235        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
 1236
 1237        #define NEED_AES_TABLES
 1238    #endif
 1239#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
 1240/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
 1241
 1242#elif defined(WOLFSSL_RISCV_ASM)
 1243/* implemented in wolfcrypt/src/port/riscv/riscv-64-aes.c */
 1244
 1245#elif defined(WOLFSSL_SILABS_SE_ACCEL)
 1246/* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
 1247
 1248#elif defined(WOLFSSL_PSOC6_CRYPTO)
 1249
 1250    #if (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
 1251        static WARN_UNUSED_RESULT int wc_AesEncrypt(
 1252            Aes* aes, const byte* inBlock, byte* outBlock)
 1253        {
 1254            return wc_Psoc6_Aes_Encrypt(aes, inBlock, outBlock);
 1255        }
 1256    #endif
 1257
 1258    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
 1259        static WARN_UNUSED_RESULT int wc_AesDecrypt(
 1260            Aes* aes, const byte* inBlock, byte* outBlock)
 1261        {
 1262            return wc_Psoc6_Aes_Decrypt(aes, inBlock, outBlock);
 1263        }
 1264
 1265    #endif
 1266#elif defined(WOLF_CRYPTO_CB_ONLY_AES)
 1267    /* No software implementation AES T-tables, S-box, Rcon and the C key
 1268     * schedule are stripped. */
 1269#else
 1270
 1271    /* using wolfCrypt software implementation */
 1272    #define NEED_AES_TABLES
 1273#endif
 1274
 1275
 1276
 1277#if defined(WC_AES_BITSLICED) && !defined(HAVE_AES_ECB)
 1278    #error "When WC_AES_BITSLICED is defined, HAVE_AES_ECB is needed."
 1279#endif
 1280
 1281#ifdef NEED_AES_TABLES
 1282
 1283#ifndef WC_AES_BITSLICED
 1284#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
 1285#if !defined(WOLFSSL_ESP32_CRYPT) || \
 1286    (defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
 1287     defined(NEED_AES_HW_FALLBACK))
 1288static const FLASH_QUALIFIER word32 rcon[] = {
 1289    0x01000000, 0x02000000, 0x04000000, 0x08000000,
 1290    0x10000000, 0x20000000, 0x40000000, 0x80000000,
 1291    0x1B000000, 0x36000000,
 1292    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
 1293};
 1294#endif /* ESP32 */
 1295#endif /* __aarch64__ || !WOLFSSL_ARMASM */
 1296
 1297#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
 1298      defined(HAVE_AESCCM)
 1299#ifndef WOLFSSL_AES_SMALL_TABLES
 1300static const FLASH_QUALIFIER word32 Te[4][256] = {
 1301{
 1302    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
 1303    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
 1304    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
 1305    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
 1306    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
 1307    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
 1308    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
 1309    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
 1310    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
 1311    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
 1312    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
 1313    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
 1314    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
 1315    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
 1316    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
 1317    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
 1318    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
 1319    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
 1320    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
 1321    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
 1322    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
 1323    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
 1324    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
 1325    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
 1326    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
 1327    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
 1328    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
 1329    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
 1330    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
 1331    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
 1332    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
 1333    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
 1334    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
 1335    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
 1336    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
 1337    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
 1338    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
 1339    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
 1340    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
 1341    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
 1342    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
 1343    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
 1344    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
 1345    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
 1346    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
 1347    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
 1348    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
 1349    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
 1350    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
 1351    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
 1352    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
 1353    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
 1354    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
 1355    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
 1356    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
 1357    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
 1358    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
 1359    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
 1360    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
 1361    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
 1362    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
 1363    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
 1364    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
 1365    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
 1366},
 1367{
 1368    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
 1369    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
 1370    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
 1371    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
 1372    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
 1373    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
 1374    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
 1375    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
 1376    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
 1377    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
 1378    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
 1379    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
 1380    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
 1381    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
 1382    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
 1383    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
 1384    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
 1385    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
 1386    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
 1387    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
 1388    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
 1389    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
 1390    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
 1391    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
 1392    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
 1393    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
 1394    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
 1395    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
 1396    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
 1397    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
 1398    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
 1399    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
 1400    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
 1401    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
 1402    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
 1403    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
 1404    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
 1405    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
 1406    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
 1407    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
 1408    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
 1409    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
 1410    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
 1411    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
 1412    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
 1413    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
 1414    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
 1415    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
 1416    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
 1417    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
 1418    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
 1419    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
 1420    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
 1421    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
 1422    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
 1423    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
 1424    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
 1425    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
 1426    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
 1427    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
 1428    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
 1429    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
 1430    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
 1431    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
 1432},
 1433{
 1434    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
 1435    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
 1436    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
 1437    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
 1438    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
 1439    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
 1440    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
 1441    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
 1442    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
 1443    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
 1444    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
 1445    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
 1446    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
 1447    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
 1448    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
 1449    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
 1450    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
 1451    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
 1452    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
 1453    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
 1454    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
 1455    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
 1456    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
 1457    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
 1458    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
 1459    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
 1460    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
 1461    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
 1462    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
 1463    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
 1464    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
 1465    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
 1466    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
 1467    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
 1468    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
 1469    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
 1470    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
 1471    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
 1472    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
 1473    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
 1474    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
 1475    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
 1476    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
 1477    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
 1478    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
 1479    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
 1480    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
 1481    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
 1482    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
 1483    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
 1484    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
 1485    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
 1486    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
 1487    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
 1488    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
 1489    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
 1490    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
 1491    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
 1492    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
 1493    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
 1494    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
 1495    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
 1496    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
 1497    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
 1498},
 1499{
 1500    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
 1501    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
 1502    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
 1503    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
 1504    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
 1505    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
 1506    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
 1507    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
 1508    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
 1509    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
 1510    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
 1511    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
 1512    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
 1513    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
 1514    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
 1515    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
 1516    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
 1517    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
 1518    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
 1519    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
 1520    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
 1521    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
 1522    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
 1523    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
 1524    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
 1525    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
 1526    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
 1527    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
 1528    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
 1529    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
 1530    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
 1531    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
 1532    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
 1533    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
 1534    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
 1535    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
 1536    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
 1537    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
 1538    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
 1539    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
 1540    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
 1541    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
 1542    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
 1543    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
 1544    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
 1545    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
 1546    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
 1547    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
 1548    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
 1549    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
 1550    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
 1551    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
 1552    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
 1553    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
 1554    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
 1555    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
 1556    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
 1557    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
 1558    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
 1559    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
 1560    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
 1561    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
 1562    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
 1563    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
 1564}
 1565};
 1566
 1567#ifdef HAVE_AES_DECRYPT
 1568#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
 1569static const FLASH_QUALIFIER word32 Td[4][256] = {
 1570{
 1571    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
 1572    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
 1573    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
 1574    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
 1575    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
 1576    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
 1577    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
 1578    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
 1579    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
 1580    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
 1581    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
 1582    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
 1583    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
 1584    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
 1585    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
 1586    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
 1587    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
 1588    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
 1589    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
 1590    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
 1591    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
 1592    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
 1593    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
 1594    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
 1595    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
 1596    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
 1597    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
 1598    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
 1599    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
 1600    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
 1601    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
 1602    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
 1603    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
 1604    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
 1605    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
 1606    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
 1607    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
 1608    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
 1609    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
 1610    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
 1611    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
 1612    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
 1613    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
 1614    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
 1615    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
 1616    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
 1617    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
 1618    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
 1619    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
 1620    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
 1621    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
 1622    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
 1623    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
 1624    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
 1625    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
 1626    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
 1627    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
 1628    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
 1629    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
 1630    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
 1631    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
 1632    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
 1633    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
 1634    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
 1635},
 1636{
 1637    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
 1638    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
 1639    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
 1640    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
 1641    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
 1642    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
 1643    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
 1644    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
 1645    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
 1646    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
 1647    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
 1648    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
 1649    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
 1650    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
 1651    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
 1652    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
 1653    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
 1654    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
 1655    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
 1656    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
 1657    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
 1658    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
 1659    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
 1660    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
 1661    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
 1662    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
 1663    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
 1664    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
 1665    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
 1666    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
 1667    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
 1668    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
 1669    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
 1670    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
 1671    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
 1672    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
 1673    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
 1674    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
 1675    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
 1676    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
 1677    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
 1678    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
 1679    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
 1680    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
 1681    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
 1682    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
 1683    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
 1684    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
 1685    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
 1686    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
 1687    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
 1688    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
 1689    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
 1690    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
 1691    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
 1692    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
 1693    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
 1694    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
 1695    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
 1696    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
 1697    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
 1698    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
 1699    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
 1700    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
 1701},
 1702{
 1703    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
 1704    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
 1705    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
 1706    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
 1707    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
 1708    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
 1709    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
 1710    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
 1711    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
 1712    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
 1713    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
 1714    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
 1715    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
 1716    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
 1717    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
 1718    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
 1719    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
 1720    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
 1721    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
 1722    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
 1723
 1724    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
 1725    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
 1726    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
 1727    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
 1728    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
 1729    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
 1730    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
 1731    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
 1732    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
 1733    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
 1734    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
 1735    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
 1736    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
 1737    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
 1738    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
 1739    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
 1740    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
 1741    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
 1742    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
 1743    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
 1744    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
 1745    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
 1746    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
 1747    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
 1748    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
 1749    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
 1750    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
 1751    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
 1752    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
 1753    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
 1754    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
 1755    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
 1756    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
 1757    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
 1758    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
 1759    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
 1760    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
 1761    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
 1762    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
 1763    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
 1764    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
 1765    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
 1766    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
 1767    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
 1768},
 1769{
 1770    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
 1771    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
 1772    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
 1773    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
 1774    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
 1775    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
 1776    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
 1777    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
 1778    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
 1779    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
 1780    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
 1781    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
 1782    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
 1783    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
 1784    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
 1785    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
 1786    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
 1787    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
 1788    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
 1789    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
 1790    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
 1791    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
 1792    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
 1793    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
 1794    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
 1795    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
 1796    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
 1797    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
 1798    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
 1799    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
 1800    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
 1801    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
 1802    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
 1803    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
 1804    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
 1805    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
 1806    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
 1807    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
 1808    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
 1809    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
 1810    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
 1811    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
 1812    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
 1813    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
 1814    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
 1815    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
 1816    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
 1817    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
 1818    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
 1819    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
 1820    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
 1821    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
 1822    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
 1823    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
 1824    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
 1825    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
 1826    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
 1827    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
 1828    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
 1829    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
 1830    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
 1831    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
 1832    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
 1833    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
 1834}
 1835};
 1836#endif /* __aarch64__ || !WOLFSSL_ARMASM */
 1837#endif /* HAVE_AES_DECRYPT */
 1838#endif /* WOLFSSL_AES_SMALL_TABLES */
 1839
 1840#ifdef HAVE_AES_DECRYPT
 1841#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
 1842     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)
 1843#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
 1844static const FLASH_QUALIFIER byte Td4[256] =
 1845{
 1846    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
 1847    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
 1848    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
 1849    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
 1850    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
 1851    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
 1852    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
 1853    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
 1854    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
 1855    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
 1856    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
 1857    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
 1858    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
 1859    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
 1860    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
 1861    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
 1862    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
 1863    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
 1864    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
 1865    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
 1866    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
 1867    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
 1868    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
 1869    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
 1870    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
 1871    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
 1872    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
 1873    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
 1874    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
 1875    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
 1876    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
 1877    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
 1878};
 1879#endif
 1880#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
 1881#endif /* HAVE_AES_DECRYPT */
 1882
 1883#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
 1884
 1885#ifdef WOLFSSL_AES_SMALL_TABLES
 1886static const byte Tsbox[256] = {
 1887    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
 1888    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
 1889    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
 1890    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
 1891    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
 1892    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
 1893    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
 1894    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
 1895    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
 1896    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
 1897    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
 1898    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
 1899    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
 1900    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
 1901    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
 1902    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
 1903    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
 1904    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
 1905    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
 1906    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
 1907    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
 1908    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
 1909    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
 1910    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
 1911    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
 1912    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
 1913    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
 1914    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
 1915    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
 1916    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
 1917    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
 1918    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
 1919};
 1920
 1921#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
 1922
 1923static WARN_UNUSED_RESULT word32 col_mul(
 1924    word32 t, int i2, int i3, int ia, int ib)
 1925{
 1926    byte t3 = GETBYTE(t, i3);
 1927    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
 1928
 1929    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
 1930}
 1931
 1932#if defined(HAVE_AES_DECRYPT) && \
 1933    (defined(HAVE_AES_CBC) || defined(HAVE_AES_ECB) || \
 1934     defined(WOLFSSL_AES_DIRECT))
 1935static WARN_UNUSED_RESULT word32 inv_col_mul(
 1936    word32 t, int i9, int ib, int id, int ie)
 1937{
 1938    byte t9 = GETBYTE(t, i9);
 1939    byte tb = GETBYTE(t, ib);
 1940    byte td = GETBYTE(t, id);
 1941    byte te = GETBYTE(t, ie);
 1942    byte t0 = t9 ^ tb ^ td;
 1943    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
 1944}
 1945#endif /* HAVE_AES_DECRYPT && (HAVE_AES_CBC || HAVE_AES_ECB || WOLFSSL_AES_DIRECT) */
 1946#endif /* WOLFSSL_AES_SMALL_TABLES */
 1947#endif
 1948#endif
 1949
 1950#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
 1951                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
 1952#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_AES_DIRECT) || \
 1953      defined(HAVE_AESCCM)
 1954
 1955
 1956#ifndef WC_AES_BITSLICED
 1957
 1958#ifndef WC_CACHE_LINE_SZ
 1959    #if defined(__x86_64__) || defined(_M_X64) || \
 1960       (defined(__ILP32__) && (__ILP32__ >= 1))
 1961        #define WC_CACHE_LINE_SZ 64
 1962    #else
 1963        /* default cache line size */
 1964        #define WC_CACHE_LINE_SZ 32
 1965    #endif
 1966#endif
 1967
 1968#ifndef WC_NO_CACHE_RESISTANT
 1969
 1970#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
 1971    #define WOLFSSL_AES_TOUCH_LINES
 1972#endif
 1973
 1974#ifndef WOLFSSL_AES_SMALL_TABLES
 1975/* load 4 Te Tables into cache by cache line stride */
 1976static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
 1977{
 1978#ifndef WOLFSSL_AES_TOUCH_LINES
 1979    volatile word32 x = 0;
 1980    int i;
 1981    int j;
 1982
 1983    for (i = 0; i < 4; i++) {
 1984        /* 256 elements, each one is 4 bytes */
 1985        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
 1986            x &= Te[i][j];
 1987        }
 1988    }
 1989
 1990    return x;
 1991#else
 1992    return 0;
 1993#endif
 1994}
 1995#else
 1996/* load sbox into cache by cache line stride */
 1997static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
 1998{
 1999#ifndef WOLFSSL_AES_TOUCH_LINES
 2000    volatile word32 x = 0;
 2001    int i;
 2002
 2003    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
 2004        x &= Tsbox[i];
 2005    }
 2006
 2007    return x;
 2008#else
 2009    return 0;
 2010#endif
 2011}
 2012#endif
 2013#endif
 2014
 2015#ifdef WOLFSSL_AES_TOUCH_LINES
 2016#if WC_CACHE_LINE_SZ == 128
 2017    #define WC_CACHE_LINE_BITS      5
 2018    #define WC_CACHE_LINE_MASK_HI   0xe0
 2019    #define WC_CACHE_LINE_MASK_LO   0x1f
 2020    #define WC_CACHE_LINE_ADD       0x20
 2021#elif WC_CACHE_LINE_SZ == 64
 2022    #define WC_CACHE_LINE_BITS      4
 2023    #define WC_CACHE_LINE_MASK_HI   0xf0
 2024    #define WC_CACHE_LINE_MASK_LO   0x0f
 2025    #define WC_CACHE_LINE_ADD       0x10
 2026#elif WC_CACHE_LINE_SZ == 32
 2027    #define WC_CACHE_LINE_BITS      3
 2028    #define WC_CACHE_LINE_MASK_HI   0xf8
 2029    #define WC_CACHE_LINE_MASK_LO   0x07
 2030    #define WC_CACHE_LINE_ADD       0x08
 2031#elif WC_CACHE_LINE_SZ == 16
 2032    #define WC_CACHE_LINE_BITS      2
 2033    #define WC_CACHE_LINE_MASK_HI   0xfc
 2034    #define WC_CACHE_LINE_MASK_LO   0x03
 2035    #define WC_CACHE_LINE_ADD       0x04
 2036#else
 2037    #error Cache line size not supported
 2038#endif
 2039
 2040#ifndef WOLFSSL_AES_SMALL_TABLES
 2041static word32 GetTable(const word32* t, byte o)
 2042{
 2043#if WC_CACHE_LINE_SZ == 64
 2044    word32 e;
 2045    byte hi = o & 0xf0;
 2046    byte lo = o & 0x0f;
 2047
 2048    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2049    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2050    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2051    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2052    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2053    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2054    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2055    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2056    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2057    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2058    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2059    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2060    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2061    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2062    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2063    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
 2064
 2065    return e;
 2066#else
 2067    word32 e = 0;
 2068    int i;
 2069    byte hi = o & WC_CACHE_LINE_MASK_HI;
 2070    byte lo = o & WC_CACHE_LINE_MASK_LO;
 2071
 2072    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
 2073        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
 2074        hi -= WC_CACHE_LINE_ADD;
 2075    }
 2076
 2077    return e;
 2078#endif
 2079}
 2080#endif
 2081
 2082#ifdef WOLFSSL_AES_SMALL_TABLES
 2083static byte GetTable8(const byte* t, byte o)
 2084{
 2085#if WC_CACHE_LINE_SZ == 64
 2086    byte e;
 2087    byte hi = o & 0xf0;
 2088    byte lo = o & 0x0f;
 2089
 2090    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2091    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2092    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2093    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2094    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2095    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2096    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2097    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2098    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2099    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2100    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2101    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2102    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2103    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2104    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
 2105    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
 2106
 2107    return e;
 2108#else
 2109    byte e = 0;
 2110    int i;
 2111    byte hi = o & WC_CACHE_LINE_MASK_HI;
 2112    byte lo = o & WC_CACHE_LINE_MASK_LO;
 2113
 2114    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
 2115        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
 2116        hi -= WC_CACHE_LINE_ADD;
 2117    }
 2118
 2119    return e;
 2120#endif
 2121}
 2122#endif
 2123
 2124#ifndef WOLFSSL_AES_SMALL_TABLES
 2125static void GetTable_Multi(const word32* t, word32* t0, byte o0,
 2126    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
 2127{
 2128    word32 e0 = 0;
 2129    word32 e1 = 0;
 2130    word32 e2 = 0;
 2131    word32 e3 = 0;
 2132    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
 2133    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
 2134    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
 2135    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
 2136    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
 2137    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
 2138    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
 2139    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
 2140    int i;
 2141
 2142    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
 2143        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
 2144        hi0 -= WC_CACHE_LINE_ADD;
 2145        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
 2146        hi1 -= WC_CACHE_LINE_ADD;
 2147        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
 2148        hi2 -= WC_CACHE_LINE_ADD;
 2149        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
 2150        hi3 -= WC_CACHE_LINE_ADD;
 2151    }
 2152    *t0 = e0;
 2153    *t1 = e1;
 2154    *t2 = e2;
 2155    *t3 = e3;
 2156}
 2157static void XorTable_Multi(const word32* t, word32* t0, byte o0,
 2158    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
 2159{
 2160    word32 e0 = 0;
 2161    word32 e1 = 0;
 2162    word32 e2 = 0;
 2163    word32 e3 = 0;
 2164    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
 2165    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
 2166    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
 2167    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
 2168    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
 2169    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
 2170    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
 2171    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
 2172    int i;
 2173
 2174    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
 2175        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
 2176        hi0 -= WC_CACHE_LINE_ADD;
 2177        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
 2178        hi1 -= WC_CACHE_LINE_ADD;
 2179        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
 2180        hi2 -= WC_CACHE_LINE_ADD;
 2181        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
 2182        hi3 -= WC_CACHE_LINE_ADD;
 2183    }
 2184    *t0 ^= e0;
 2185    *t1 ^= e1;
 2186    *t2 ^= e2;
 2187    *t3 ^= e3;
 2188}
 2189static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
 2190{
 2191    word32 e = 0;
 2192    int i;
 2193    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
 2194    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
 2195    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
 2196    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
 2197    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
 2198    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
 2199    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
 2200    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
 2201
 2202    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
 2203        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
 2204             << 24;
 2205        hi0 -= WC_CACHE_LINE_ADD;
 2206        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
 2207             << 16;
 2208        hi1 -= WC_CACHE_LINE_ADD;
 2209        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
 2210             <<  8;
 2211        hi2 -= WC_CACHE_LINE_ADD;
 2212        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
 2213             <<  0;
 2214        hi3 -= WC_CACHE_LINE_ADD;
 2215    }
 2216
 2217    return e;
 2218}
 2219#endif
 2220#else
 2221
 2222#define GetTable(t, o)  t[o]
 2223#define GetTable8(t, o) t[o]
 2224#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
 2225    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
 2226#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
 2227    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
 2228#define GetTable8_4(t, o0, o1, o2, o3) \
 2229    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
 2230     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
 2231#endif
 2232
 2233#ifndef HAVE_CUDA
 2234/* Encrypt a block using AES.
 2235 *
 2236 * @param [in]  aes       AES object.
 2237 * @param [in]  inBlock   Block to encrypt.
 2238 * @param [out] outBlock  Encrypted block.
 2239 * @param [in]  r         Rounds divided by 2.
 2240 */
 2241#define WC_AES_HAVE_PREFETCH_ARG
 2242static int always_prefetch = 0;
 2243WC_MAYBE_UNUSED static int never_prefetch = 1;
 2244WC_ARGS_NOT_NULL((1, 2, 3, 5))
 2245static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
 2246        word32 r, int *prefetch_ptr)
 2247{
 2248    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
 2249    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
 2250    const word32* rk;
 2251
 2252#ifdef WC_C_DYNAMIC_FALLBACK
 2253    rk = aes->key_C_fallback;
 2254#else
 2255    rk = aes->key;
 2256#endif
 2257
 2258    /*
 2259     * map byte array block to cipher state
 2260     * and add initial round key:
 2261     */
 2262    XMEMCPY(&s0, inBlock,                  sizeof(s0));
 2263    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
 2264    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
 2265    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
 2266
 2267#ifdef LITTLE_ENDIAN_ORDER
 2268    s0 = ByteReverseWord32(s0);
 2269    s1 = ByteReverseWord32(s1);
 2270    s2 = ByteReverseWord32(s2);
 2271    s3 = ByteReverseWord32(s3);
 2272#endif
 2273
 2274    /* AddRoundKey */
 2275    s0 ^= rk[0];
 2276    s1 ^= rk[1];
 2277    s2 ^= rk[2];
 2278    s3 ^= rk[3];
 2279
 2280#ifndef WOLFSSL_AES_SMALL_TABLES
 2281
 2282#ifndef WC_NO_CACHE_RESISTANT
 2283    if (*prefetch_ptr == 0) {
 2284        s0 |= PreFetchTe();
 2285        if (prefetch_ptr != &always_prefetch)
 2286            *prefetch_ptr = 1;
 2287    }
 2288#else
 2289    (void)prefetch_ptr;
 2290#endif
 2291
 2292#ifndef WOLFSSL_AES_TOUCH_LINES
 2293#define ENC_ROUND_T_S(o)                                                       \
 2294    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
 2295         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
 2296         rk[(o)+4];                                                            \
 2297    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
 2298         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
 2299         rk[(o)+5];                                                            \
 2300    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
 2301         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
 2302         rk[(o)+6];                                                            \
 2303    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
 2304         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
 2305         rk[(o)+7]
 2306#define ENC_ROUND_S_T(o)                                                       \
 2307    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
 2308         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
 2309         rk[(o)+0];                                                            \
 2310    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
 2311         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
 2312         rk[(o)+1];                                                            \
 2313    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
 2314         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
 2315         rk[(o)+2];                                                            \
 2316    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
 2317         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
 2318         rk[(o)+3]
 2319#else
 2320#define ENC_ROUND_T_S(o)                                                       \
 2321    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
 2322                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
 2323    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
 2324                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
 2325    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
 2326                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
 2327    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
 2328                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
 2329    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
 2330
 2331#define ENC_ROUND_S_T(o)                                                       \
 2332    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
 2333                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
 2334    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
 2335                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
 2336    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
 2337                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
 2338    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
 2339                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
 2340    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
 2341#endif
 2342
 2343#ifndef WOLFSSL_AES_NO_UNROLL
 2344/* Unroll the loop. */
 2345                       ENC_ROUND_T_S( 0);
 2346    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
 2347    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
 2348    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
 2349    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
 2350    if (r > 5) {
 2351        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
 2352        if (r > 6) {
 2353            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
 2354        }
 2355    }
 2356    rk += r * 8;
 2357#else
 2358    /*
 2359     * Nr - 1 full rounds:
 2360     */
 2361
 2362    for (;;) {
 2363        ENC_ROUND_T_S(0);
 2364
 2365        rk += 8;
 2366        if (--r == 0) {
 2367            break;
 2368        }
 2369
 2370        ENC_ROUND_S_T(0);
 2371    }
 2372#endif
 2373
 2374    /*
 2375     * apply last round and
 2376     * map cipher state to byte array block:
 2377     */
 2378
 2379#ifndef WOLFSSL_AES_TOUCH_LINES
 2380    s0 =
 2381        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
 2382        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
 2383        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
 2384        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
 2385        rk[0];
 2386    s1 =
 2387        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
 2388        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
 2389        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
 2390        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
 2391        rk[1];
 2392    s2 =
 2393        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
 2394        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
 2395        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
 2396        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
 2397        rk[2];
 2398    s3 =
 2399        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
 2400        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
 2401        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
 2402        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
 2403        rk[3];
 2404#else
 2405{
 2406    word32 u0;
 2407    word32 u1;
 2408    word32 u2;
 2409    word32 u3;
 2410
 2411    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
 2412    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
 2413                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
 2414    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
 2415    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
 2416    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
 2417                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
 2418    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
 2419    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
 2420    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
 2421                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
 2422    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
 2423    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
 2424    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
 2425                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
 2426    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
 2427    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
 2428}
 2429#endif
 2430
 2431#else /* WOLFSSL_AES_SMALL_TABLES */
 2432
 2433#ifndef WC_NO_CACHE_RESISTANT
 2434    if (*prefetch_ptr == 0) {
 2435        s0 |= PreFetchSBox();
 2436        if (prefetch_ptr != &always_prefetch)
 2437            *prefetch_ptr = 1;
 2438    }
 2439#else
 2440    (void)prefetch_ptr;
 2441#endif
 2442
 2443    r *= 2;
 2444    /* Two rounds at a time */
 2445    for (rk += 4; r > 1; r--, rk += 4) {
 2446        t0 =
 2447            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
 2448            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
 2449            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
 2450            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
 2451        t1 =
 2452            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
 2453            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
 2454            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
 2455            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
 2456        t2 =
 2457            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
 2458            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
 2459            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
 2460            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
 2461        t3 =
 2462            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
 2463            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
 2464            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
 2465            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
 2466
 2467        s0 =
 2468            (col_mul(t0, 3, 2, 0, 1) << 24) ^
 2469            (col_mul(t0, 2, 1, 0, 3) << 16) ^
 2470            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
 2471            (col_mul(t0, 0, 3, 2, 1)      ) ^
 2472            rk[0];
 2473        s1 =
 2474            (col_mul(t1, 3, 2, 0, 1) << 24) ^
 2475            (col_mul(t1, 2, 1, 0, 3) << 16) ^
 2476            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
 2477            (col_mul(t1, 0, 3, 2, 1)      ) ^
 2478            rk[1];
 2479        s2 =
 2480            (col_mul(t2, 3, 2, 0, 1) << 24) ^
 2481            (col_mul(t2, 2, 1, 0, 3) << 16) ^
 2482            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
 2483            (col_mul(t2, 0, 3, 2, 1)      ) ^
 2484            rk[2];
 2485        s3 =
 2486            (col_mul(t3, 3, 2, 0, 1) << 24) ^
 2487            (col_mul(t3, 2, 1, 0, 3) << 16) ^
 2488            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
 2489            (col_mul(t3, 0, 3, 2, 1)      ) ^
 2490            rk[3];
 2491    }
 2492
 2493    t0 =
 2494        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
 2495        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
 2496        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
 2497        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
 2498    t1 =
 2499        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
 2500        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
 2501        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
 2502        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
 2503    t2 =
 2504        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
 2505        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
 2506        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
 2507        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
 2508    t3 =
 2509        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
 2510        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
 2511        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
 2512        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
 2513    s0 = t0 ^ rk[0];
 2514    s1 = t1 ^ rk[1];
 2515    s2 = t2 ^ rk[2];
 2516    s3 = t3 ^ rk[3];
 2517
 2518#endif /* WOLFSSL_AES_SMALL_TABLES */
 2519
 2520    /* write out */
 2521#ifdef LITTLE_ENDIAN_ORDER
 2522    s0 = ByteReverseWord32(s0);
 2523    s1 = ByteReverseWord32(s1);
 2524    s2 = ByteReverseWord32(s2);
 2525    s3 = ByteReverseWord32(s3);
 2526#endif
 2527
 2528    XMEMCPY(outBlock,                  &s0, sizeof(s0));
 2529    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
 2530    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
 2531    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
 2532}
 2533
 2534#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
 2535    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
 2536    !defined(MAX3266X_AES)
 2537#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__)
 2538/* Encrypt a number of blocks using AES.
 2539 *
 2540 * @param [in]  aes  AES object.
 2541 * @param [in]  in   Block to encrypt.
 2542 * @param [out] out  Encrypted block.
 2543 * @param [in]  sz   Number of blocks to encrypt.
 2544 */
 2545static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
 2546{
 2547    word32 i;
 2548    int did_prefetches = 0;
 2549
 2550    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
 2551        AesEncrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
 2552        in += WC_AES_BLOCK_SIZE;
 2553        out += WC_AES_BLOCK_SIZE;
 2554    }
 2555}
 2556#endif
 2557#endif
 2558#else
 2559extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
 2560        word32 r);
 2561extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
 2562#endif /* HAVE_CUDA */
 2563
 2564#else
 2565
 2566/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
 2567 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
 2568 */
 2569/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
 2570static void bs_sub_bytes(bs_word u[8])
 2571{
 2572    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
 2573    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
 2574    bs_word y20, y21;
 2575    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
 2576    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
 2577    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
 2578    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
 2579    bs_word t40, t41, t42, t43, t44, t45;
 2580    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
 2581    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
 2582    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
 2583    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
 2584    bs_word tc20, tc21, tc26;
 2585    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
 2586    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
 2587
 2588    U0 = u[7];
 2589    U1 = u[6];
 2590    U2 = u[5];
 2591    U3 = u[4];
 2592    U4 = u[3];
 2593    U5 = u[2];
 2594    U6 = u[1];
 2595    U7 = u[0];
 2596
 2597    y14 = U3 ^ U5;
 2598    y13 = U0 ^ U6;
 2599    y9 = U0 ^ U3;
 2600    y8 = U0 ^ U5;
 2601    t0 = U1 ^ U2;
 2602    y1 = t0 ^ U7;
 2603    y4 = y1 ^ U3;
 2604    y12 = y13 ^ y14;
 2605    y2 = y1 ^ U0;
 2606    y5 = y1 ^ U6;
 2607    y3 = y5 ^ y8;
 2608    t1 = U4 ^ y12;
 2609    y15 = t1 ^ U5;
 2610    y20 = t1 ^ U1;
 2611    y6 = y15 ^ U7;
 2612    y10 = y15 ^ t0;
 2613    y11 = y20 ^ y9;
 2614    y7 = U7 ^ y11;
 2615    y17 = y10 ^ y11;
 2616    y19 = y10 ^ y8;
 2617    y16 = t0 ^ y11;
 2618    y21 = y13 ^ y16;
 2619    y18 = U0 ^ y16;
 2620    t2 = y12 & y15;
 2621    t3 = y3 & y6;
 2622    t4 = t3 ^ t2;
 2623    t5 = y4 & U7;
 2624    t6 = t5 ^ t2;
 2625    t7 = y13 & y16;
 2626    t8 = y5 & y1;
 2627    t9 = t8 ^ t7;
 2628    t10 = y2 & y7;
 2629    t11 = t10 ^ t7;
 2630    t12 = y9 & y11;
 2631    t13 = y14 & y17;
 2632    t14 = t13 ^ t12;
 2633    t15 = y8 & y10;
 2634    t16 = t15 ^ t12;
 2635    t17 = t4 ^ y20;
 2636    t18 = t6 ^ t16;
 2637    t19 = t9 ^ t14;
 2638    t20 = t11 ^ t16;
 2639    t21 = t17 ^ t14;
 2640    t22 = t18 ^ y19;
 2641    t23 = t19 ^ y21;
 2642    t24 = t20 ^ y18;
 2643    t25 = t21 ^ t22;
 2644    t26 = t21 & t23;
 2645    t27 = t24 ^ t26;
 2646    t28 = t25 & t27;
 2647    t29 = t28 ^ t22;
 2648    t30 = t23 ^ t24;
 2649    t31 = t22 ^ t26;
 2650    t32 = t31 & t30;
 2651    t33 = t32 ^ t24;
 2652    t34 = t23 ^ t33;
 2653    t35 = t27 ^ t33;
 2654    t36 = t24 & t35;
 2655    t37 = t36 ^ t34;
 2656    t38 = t27 ^ t36;
 2657    t39 = t29 & t38;
 2658    t40 = t25 ^ t39;
 2659    t41 = t40 ^ t37;
 2660    t42 = t29 ^ t33;
 2661    t43 = t29 ^ t40;
 2662    t44 = t33 ^ t37;
 2663    t45 = t42 ^ t41;
 2664    z0 = t44 & y15;
 2665    z1 = t37 & y6;
 2666    z2 = t33 & U7;
 2667    z3 = t43 & y16;
 2668    z4 = t40 & y1;
 2669    z5 = t29 & y7;
 2670    z6 = t42 & y11;
 2671    z7 = t45 & y17;
 2672    z8 = t41 & y10;
 2673    z9 = t44 & y12;
 2674    z10 = t37 & y3;
 2675    z11 = t33 & y4;
 2676    z12 = t43 & y13;
 2677    z13 = t40 & y5;
 2678    z14 = t29 & y2;
 2679    z15 = t42 & y9;
 2680    z16 = t45 & y14;
 2681    z17 = t41 & y8;
 2682    tc1 = z15 ^ z16;
 2683    tc2 = z10 ^ tc1;
 2684    tc3 = z9 ^ tc2;
 2685    tc4 = z0 ^ z2;
 2686    tc5 = z1 ^ z0;
 2687    tc6 = z3 ^ z4;
 2688    tc7 = z12 ^ tc4;
 2689    tc8 = z7 ^ tc6;
 2690    tc9 = z8 ^ tc7;
 2691    tc10 = tc8 ^ tc9;
 2692    tc11 = tc6 ^ tc5;
 2693    tc12 = z3 ^ z5;
 2694    tc13 = z13 ^ tc1;
 2695    tc14 = tc4 ^ tc12;
 2696    S3 = tc3 ^ tc11;
 2697    tc16 = z6 ^ tc8;
 2698    tc17 = z14 ^ tc10;
 2699    tc18 = tc13 ^ tc14;
 2700    S7 = ~(z12 ^ tc18);
 2701    tc20 = z15 ^ tc16;
 2702    tc21 = tc2 ^ z11;
 2703    S0 = tc3 ^ tc16;
 2704    S6 = ~(tc10 ^ tc18);
 2705    S4 = tc14 ^ S3;
 2706    S1 = ~(S3 ^ tc16);
 2707    tc26 = tc17 ^ tc20;
 2708    S2 = ~(tc26 ^ z17);
 2709    S5 = tc21 ^ tc17;
 2710
 2711    u[0] = S7;
 2712    u[1] = S6;
 2713    u[2] = S5;
 2714    u[3] = S4;
 2715    u[4] = S3;
 2716    u[5] = S2;
 2717    u[6] = S1;
 2718    u[7] = S0;
 2719}
 2720
 2721#define BS_MASK_BIT_SET(w, j, bmask) \
 2722    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
 2723
 2724#define BS_TRANS_8(t, o, w, bmask, s)                   \
 2725    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
 2726    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
 2727    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
 2728    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
 2729    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
 2730    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
 2731    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
 2732    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
 2733
 2734static void bs_transpose(bs_word* t, bs_word* blocks)
 2735{
 2736    bs_word bmask = 1;
 2737    int i;
 2738
 2739    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
 2740
 2741    for (i = 0; i < BS_WORD_SIZE; i++) {
 2742        int j;
 2743        int o = 0;
 2744        for (j = 0; j < BS_BLOCK_WORDS; j++) {
 2745        #ifdef LITTLE_ENDIAN_ORDER
 2746            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
 2747        #else
 2748            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
 2749        #endif
 2750    #ifdef WOLFSSL_AES_NO_UNROLL
 2751            int k;
 2752            for (k = 0; k < BS_WORD_SIZE; k++) {
 2753                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
 2754            }
 2755    #else
 2756            BS_TRANS_8(t, o, w, bmask,  0);
 2757        #if BS_WORD_SIZE >= 16
 2758            BS_TRANS_8(t, o, w, bmask,  8);
 2759        #endif
 2760        #if BS_WORD_SIZE >= 32
 2761            BS_TRANS_8(t, o, w, bmask, 16);
 2762            BS_TRANS_8(t, o, w, bmask, 24);
 2763        #endif
 2764        #if BS_WORD_SIZE >= 64
 2765            BS_TRANS_8(t, o, w, bmask, 32);
 2766            BS_TRANS_8(t, o, w, bmask, 40);
 2767            BS_TRANS_8(t, o, w, bmask, 48);
 2768            BS_TRANS_8(t, o, w, bmask, 56);
 2769        #endif
 2770    #endif
 2771            o += BS_WORD_SIZE;
 2772        }
 2773        bmask <<= 1;
 2774    }
 2775}
 2776
 2777#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
 2778    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
 2779    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
 2780    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
 2781    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
 2782    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
 2783    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
 2784    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
 2785    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
 2786
 2787static void bs_inv_transpose(bs_word* t, bs_word* blocks)
 2788{
 2789    int o;
 2790
 2791    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
 2792
 2793    for (o = 0; o < BS_BLOCK_WORDS; o++) {
 2794        int i;
 2795        for (i = 0; i < BS_WORD_SIZE; i++) {
 2796        #ifdef LITTLE_ENDIAN_ORDER
 2797            bs_word bmask = (bs_word)1 << i;
 2798        #else
 2799            bs_word bmask = bs_bswap((bs_word)1 << i);
 2800        #endif
 2801            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
 2802    #ifdef WOLFSSL_AES_NO_UNROLL
 2803            int j;
 2804            for (j = 0; j < BS_WORD_SIZE; j++) {
 2805                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
 2806            }
 2807    #else
 2808            BS_INV_TRANS_8(t, o, w, bmask, 0);
 2809        #if BS_WORD_SIZE >= 16
 2810            BS_INV_TRANS_8(t, o, w, bmask, 8);
 2811        #endif
 2812        #if BS_WORD_SIZE >= 32
 2813            BS_INV_TRANS_8(t, o, w, bmask, 16);
 2814            BS_INV_TRANS_8(t, o, w, bmask, 24);
 2815        #endif
 2816        #if BS_WORD_SIZE >= 64
 2817            BS_INV_TRANS_8(t, o, w, bmask, 32);
 2818            BS_INV_TRANS_8(t, o, w, bmask, 40);
 2819            BS_INV_TRANS_8(t, o, w, bmask, 48);
 2820            BS_INV_TRANS_8(t, o, w, bmask, 56);
 2821        #endif
 2822    #endif
 2823        }
 2824    }
 2825}
 2826
 2827#define BS_ROW_OFF_0    0
 2828#define BS_ROW_OFF_1    32
 2829#define BS_ROW_OFF_2    64
 2830#define BS_ROW_OFF_3    96
 2831
 2832#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
 2833#define BS_IDX_MASK     0x7f
 2834
 2835#define BS_ASSIGN_8(d, od, s, os)   \
 2836    d[(od) + 0] = s[(os) + 0];      \
 2837    d[(od) + 1] = s[(os) + 1];      \
 2838    d[(od) + 2] = s[(os) + 2];      \
 2839    d[(od) + 3] = s[(os) + 3];      \
 2840    d[(od) + 4] = s[(os) + 4];      \
 2841    d[(od) + 5] = s[(os) + 5];      \
 2842    d[(od) + 6] = s[(os) + 6];      \
 2843    d[(od) + 7] = s[(os) + 7]
 2844
 2845static void bs_shift_rows(bs_word* t, bs_word* b)
 2846{
 2847    int i;
 2848
 2849    for (i = 0; i < 128; i += 32) {
 2850        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
 2851        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
 2852        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
 2853        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
 2854    }
 2855}
 2856
 2857#define BS_SHIFT_OFF_0  0
 2858#define BS_SHIFT_OFF_1  8
 2859#define BS_SHIFT_OFF_2  16
 2860#define BS_SHIFT_OFF_3  24
 2861
 2862/* Shift rows and mix columns.
 2863 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
 2864 */
 2865
 2866#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
 2867        of      = br0[7] ^ br1[7];                                  \
 2868        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
 2869        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
 2870        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
 2871        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
 2872        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
 2873        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
 2874        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
 2875        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
 2876
 2877static void bs_shift_mix(bs_word* t, bs_word* b)
 2878{
 2879    int i;
 2880    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
 2881    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
 2882    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
 2883    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
 2884
 2885    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
 2886        bs_word* br0 = b + or0;
 2887        bs_word* br1 = b + or1;
 2888        bs_word* br2 = b + or2;
 2889        bs_word* br3 = b + or3;
 2890        bs_word of;
 2891
 2892        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
 2893        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
 2894        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
 2895        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
 2896
 2897        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
 2898        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
 2899        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
 2900        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
 2901    }
 2902}
 2903
 2904static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
 2905{
 2906    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
 2907}
 2908
 2909static void bs_sub_bytes_blocks(bs_word* b)
 2910{
 2911    int i;
 2912
 2913    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
 2914        bs_sub_bytes(b + i);
 2915    }
 2916}
 2917
 2918static const FLASH_QUALIFIER byte bs_rcon[] = {
 2919    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
 2920    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
 2921};
 2922
 2923static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
 2924    bs_word block[AES_BLOCK_BITS];
 2925    bs_word trans[AES_BLOCK_BITS];
 2926
 2927    XMEMSET(block, 0, sizeof(block));
 2928    XMEMCPY(block, in, 4);
 2929
 2930    bs_transpose(trans, block);
 2931    bs_sub_bytes_blocks(trans);
 2932    bs_inv_transpose(block, trans);
 2933
 2934    XMEMCPY(out, block, 4);
 2935}
 2936
 2937static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
 2938    /* Rotate the input 8 bits to the left */
 2939#ifdef LITTLE_ENDIAN_ORDER
 2940    *(word32*)out = rotrFixed(*(word32*)in, 8);
 2941#else
 2942    *(word32*)out = rotlFixed(*(word32*)in, 8);
 2943#endif
 2944    bs_ke_sub_bytes(out, out);
 2945    /* On just the first byte, add 2^i to the byte */
 2946    out[0] ^= bs_rcon[i];
 2947}
 2948
 2949static void bs_expand_key(unsigned char *in, word32 sz) {
 2950    unsigned char t[4];
 2951    word32 o;
 2952    word8 i = 0;
 2953
 2954    if (sz == 176) {
 2955        /* Total of 11 rounds - AES-128. */
 2956        for (o = 16; o < sz; o += 16) {
 2957            bs_ke_transform(t, in + o - 4, i);
 2958            i++;
 2959            *(word32*)(in + o +  0) = *(word32*)(in + o - 16) ^
 2960                                      *(word32*) t;
 2961            *(word32*)(in + o +  4) = *(word32*)(in + o - 12) ^
 2962                                      *(word32*)(in + o +  0);
 2963            *(word32*)(in + o +  8) = *(word32*)(in + o -  8) ^
 2964                                      *(word32*)(in + o +  4);
 2965            *(word32*)(in + o + 12) = *(word32*)(in + o -  4) ^
 2966                                      *(word32*)(in + o +  8);
 2967        }
 2968    }
 2969    else if (sz == 208) {
 2970        /* Total of 13 rounds - AES-192. */
 2971        for (o = 24; o < sz; o += 24) {
 2972            bs_ke_transform(t, in + o - 4, i);
 2973            i++;
 2974            *(word32*)(in + o +  0) = *(word32*)(in + o - 24) ^
 2975                                      *(word32*) t;
 2976            *(word32*)(in + o +  4) = *(word32*)(in + o - 20) ^
 2977                                      *(word32*)(in + o +  0);
 2978            *(word32*)(in + o +  8) = *(word32*)(in + o - 16) ^
 2979                                      *(word32*)(in + o +  4);
 2980            *(word32*)(in + o + 12) = *(word32*)(in + o - 12) ^
 2981                                      *(word32*)(in + o +  8);
 2982            *(word32*)(in + o + 16) = *(word32*)(in + o -  8) ^
 2983                                      *(word32*)(in + o + 12);
 2984            *(word32*)(in + o + 20) = *(word32*)(in + o -  4) ^
 2985                                      *(word32*)(in + o + 16);
 2986        }
 2987    }
 2988    else if (sz == 240) {
 2989        /* Total of 15 rounds - AES-256. */
 2990        for (o = 32; o < sz; o += 16) {
 2991            if ((o & 0x1f) == 0) {
 2992                bs_ke_transform(t, in + o - 4, i);
 2993                i++;
 2994            }
 2995            else {
 2996                bs_ke_sub_bytes(t, in + o - 4);
 2997            }
 2998            *(word32*)(in + o +  0) = *(word32*)(in + o - 32) ^
 2999                                      *(word32*) t;
 3000            *(word32*)(in + o +  4) = *(word32*)(in + o - 28) ^
 3001                                      *(word32*)(in + o +  0);
 3002            *(word32*)(in + o +  8) = *(word32*)(in + o - 24) ^
 3003                                      *(word32*)(in + o +  4);
 3004            *(word32*)(in + o + 12) = *(word32*)(in + o - 20) ^
 3005                                      *(word32*)(in + o +  8);
 3006        }
 3007    }
 3008}
 3009
 3010static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
 3011    word32 rounds)
 3012{
 3013    int i;
 3014    byte bs_key[15 * WC_AES_BLOCK_SIZE];
 3015    int ksSz = (rounds + 1) * WC_AES_BLOCK_SIZE;
 3016    bs_word block[AES_BLOCK_BITS];
 3017
 3018    /* Fist round. */
 3019    XMEMCPY(bs_key, key, keyLen);
 3020    bs_expand_key(bs_key, ksSz);
 3021
 3022    for (i = 0; i < ksSz; i += WC_AES_BLOCK_SIZE) {
 3023        int k;
 3024
 3025        XMEMCPY(block, bs_key + i, WC_AES_BLOCK_SIZE);
 3026        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
 3027            int l;
 3028            for (l = 0; l < BS_BLOCK_WORDS; l++) {
 3029                block[k + l] = block[l];
 3030            }
 3031        }
 3032        bs_transpose(rk, block);
 3033        rk += AES_BLOCK_BITS;
 3034    }
 3035}
 3036
 3037static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
 3038{
 3039    word32 i;
 3040    bs_word trans[AES_BLOCK_BITS];
 3041
 3042    bs_transpose(trans, state);
 3043
 3044    bs_add_round_key(trans, trans, rk);
 3045    for (i = 1; i < r; i++) {
 3046        bs_sub_bytes_blocks(trans);
 3047        bs_shift_mix(state, trans);
 3048        rk += AES_BLOCK_BITS;
 3049        bs_add_round_key(trans, state, rk);
 3050    }
 3051    bs_sub_bytes_blocks(trans);
 3052    bs_shift_rows(state, trans);
 3053    rk += AES_BLOCK_BITS;
 3054    bs_add_round_key(trans, state, rk);
 3055    bs_inv_transpose(state, trans);
 3056}
 3057
 3058#ifndef HAVE_CUDA
 3059/* Encrypt a block using AES.
 3060 *
 3061 * @param [in]  aes       AES object.
 3062 * @param [in]  inBlock   Block to encrypt.
 3063 * @param [out] outBlock  Encrypted block.
 3064 * @param [in]  r         Rounds divided by 2.
 3065 */
 3066static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
 3067        word32 r)
 3068{
 3069    bs_word state[AES_BLOCK_BITS];
 3070
 3071    (void)r;
 3072
 3073    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
 3074    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
 3075
 3076    bs_encrypt(state, aes->bs_key, aes->rounds);
 3077
 3078    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
 3079}
 3080
 3081#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
 3082    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
 3083/* Encrypt a number of blocks using AES.
 3084 *
 3085 * @param [in]  aes  AES object.
 3086 * @param [in]  in   Block to encrypt.
 3087 * @param [out] out  Encrypted block.
 3088 * @param [in]  sz   Number of blocks to encrypt.
 3089 */
 3090static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
 3091{
 3092    bs_word state[AES_BLOCK_BITS];
 3093
 3094    while (sz >= BS_BLOCK_SIZE) {
 3095        XMEMCPY(state, in, BS_BLOCK_SIZE);
 3096        bs_encrypt(state, aes->bs_key, aes->rounds);
 3097        XMEMCPY(out, state, BS_BLOCK_SIZE);
 3098        sz  -= BS_BLOCK_SIZE;
 3099        in  += BS_BLOCK_SIZE;
 3100        out += BS_BLOCK_SIZE;
 3101    }
 3102    if (sz > 0) {
 3103        XMEMCPY(state, in, sz);
 3104        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
 3105        bs_encrypt(state, aes->bs_key, aes->rounds);
 3106        XMEMCPY(out, state, sz);
 3107    }
 3108}
 3109#endif
 3110#else
 3111extern void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
 3112        word32 r);
 3113extern void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz);
 3114#endif /* HAVE_CUDA */
 3115
 3116#endif /* !WC_AES_BITSLICED */
 3117
 3118#ifdef WC_AES_HAVE_PREFETCH_ARG
 3119#define wc_AesEncrypt(aes, inBlock, outBlock) \
 3120    AesEncrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
 3121WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesEncrypt_preFetchOpt(
 3122    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
 3123#else
 3124#define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
 3125    wc_AesEncrypt(aes, inBlock, outBlock)
 3126WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesEncrypt(
 3127    Aes* aes, const byte* inBlock, byte* outBlock)
 3128#endif
 3129{
 3130#if defined(MAX3266X_AES)
 3131    word32 keySize;
 3132#endif
 3133#if defined(MAX3266X_CB)
 3134    int ret_cb;
 3135#endif
 3136    word32 r;
 3137
 3138#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 3139    {
 3140        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 3141        if (ret < 0)
 3142            return ret;
 3143    }
 3144#endif
 3145
 3146    r = aes->rounds >> 1;
 3147
 3148    if (r > 7 || r == 0) {
 3149        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
 3150        return KEYUSAGE_E;
 3151    }
 3152
 3153#ifdef WOLFSSL_AESNI
 3154    if (aes->use_aesni) {
 3155        ASSERT_SAVED_VECTOR_REGISTERS();
 3156
 3157        #ifdef DEBUG_AESNI
 3158            printf("about to aes encrypt\n");
 3159            printf("in  = %p\n", inBlock);
 3160            printf("out = %p\n", outBlock);
 3161            printf("aes->key = %p\n", aes->key);
 3162            printf("aes->rounds = %d\n", aes->rounds);
 3163            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
 3164        #endif
 3165
 3166        /* check alignment, decrypt doesn't need alignment */
 3167        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
 3168        #ifndef NO_WOLFSSL_ALLOC_ALIGN
 3169            byte* tmp = (byte*)XMALLOC(WC_AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
 3170                                                      DYNAMIC_TYPE_TMP_BUFFER);
 3171            byte* tmp_align;
 3172            if (tmp == NULL)
 3173                return MEMORY_E;
 3174
 3175            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
 3176
 3177            XMEMCPY(tmp_align, inBlock, WC_AES_BLOCK_SIZE);
 3178            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, WC_AES_BLOCK_SIZE,
 3179                    (byte*)aes->key, (int)aes->rounds);
 3180            XMEMCPY(outBlock, tmp_align, WC_AES_BLOCK_SIZE);
 3181            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
 3182            return 0;
 3183        #else
 3184            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
 3185            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
 3186            return BAD_ALIGN_E;
 3187        #endif
 3188        }
 3189
 3190        AES_ECB_encrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
 3191                        (int)aes->rounds);
 3192
 3193        return 0;
 3194    }
 3195    else {
 3196        #ifdef DEBUG_AESNI
 3197            printf("Skipping AES-NI\n");
 3198        #endif
 3199    }
 3200#elif defined(WOLFSSL_ARMASM)
 3201#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
 3202#if !defined(__aarch64__)
 3203    AES_encrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
 3204#else
 3205    if (aes->use_aes_hw_crypto) {
 3206        AES_encrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
 3207            (int)aes->rounds);
 3208    }
 3209    else
 3210#endif /* !__aarch64__ */
 3211#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
 3212#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
 3213    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
 3214    {
 3215        AES_ECB_encrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
 3216            (const unsigned char*)aes->key, aes->rounds);
 3217    }
 3218#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 3219    {
 3220        AES_ECB_encrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
 3221            (const unsigned char*)aes->key, aes->rounds);
 3222    }
 3223#endif
 3224    return 0;
 3225#endif /* WOLFSSL_AESNI */
 3226#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
 3227    AES_ECB_encrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
 3228    return 0;
 3229#endif
 3230
 3231#if defined(WOLFSSL_IMXRT_DCP)
 3232    if (aes->keylen == 16) {
 3233        DCPAesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
 3234        return 0;
 3235    }
 3236#endif
 3237
 3238#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
 3239    if (aes->useSWCrypt == 0) {
 3240        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
 3241                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
 3242    }
 3243#endif
 3244
 3245#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
 3246    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
 3247    if (wc_esp32AesSupportedKeyLen(aes)) {
 3248        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
 3249    }
 3250    else {
 3251        /* For example, the ESP32-S3 does not support HW for len = 24,
 3252         * so fall back to SW */
 3253    #ifdef DEBUG_WOLFSSL
 3254        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
 3255                      aes->keylen);
 3256    #endif
 3257    }
 3258#endif
 3259
 3260#if defined(MAX3266X_AES)
 3261    if (wc_AesGetKeySize(aes, &keySize) == 0) {
 3262        return wc_MXC_TPU_AesEncrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
 3263                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
 3264                                    outBlock, (unsigned int)keySize);
 3265    }
 3266#endif
 3267#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
 3268    #ifndef WOLF_CRYPTO_CB_FIND
 3269    if (aes->devId != INVALID_DEVID)
 3270    #endif
 3271    {
 3272        ret_cb = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock,
 3273                                            WC_AES_BLOCK_SIZE);
 3274        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 3275            return ret_cb;
 3276        /* fall-through when unavailable */
 3277    }
 3278#endif
 3279
 3280#ifdef WC_AES_HAVE_PREFETCH_ARG
 3281    AesEncrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
 3282#else
 3283    AesEncrypt_C(aes, inBlock, outBlock, r);
 3284#endif
 3285
 3286    return 0;
 3287} /* wc_AesEncrypt */
 3288#endif
 3289#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
 3290
 3291#if defined(HAVE_AES_DECRYPT)
 3292#if ((defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
 3293     defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT)) && \
 3294    (defined(__aarch64__) || !defined(WOLFSSL_ARMASM))
 3295
 3296#ifndef WC_AES_BITSLICED
 3297#ifndef WC_NO_CACHE_RESISTANT
 3298#ifndef WOLFSSL_AES_SMALL_TABLES
 3299/* load 4 Td Tables into cache by cache line stride */
 3300static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
 3301{
 3302    volatile word32 x = 0;
 3303    int i;
 3304    int j;
 3305
 3306    for (i = 0; i < 4; i++) {
 3307        /* 256 elements, each one is 4 bytes */
 3308        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ / 4) {
 3309            x &= Td[i][j];
 3310        }
 3311    }
 3312
 3313    return x;
 3314}
 3315#endif /* !WOLFSSL_AES_SMALL_TABLES */
 3316
 3317/* load Td Table4 into cache by cache line stride */
 3318static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
 3319{
 3320#ifndef WOLFSSL_AES_TOUCH_LINES
 3321    volatile word32 x = 0;
 3322    int i;
 3323
 3324    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
 3325        x &= (word32)Td4[i];
 3326    }
 3327
 3328    return x;
 3329#else
 3330    return 0;
 3331#endif
 3332}
 3333#endif /* !WC_NO_CACHE_RESISTANT */
 3334
 3335/* Decrypt a block using AES.
 3336 *
 3337 * @param [in]  aes       AES object.
 3338 * @param [in]  inBlock   Block to encrypt.
 3339 * @param [out] outBlock  Encrypted block.
 3340 * @param [in]  r         Rounds divided by 2.
 3341 */
 3342#ifndef WC_AES_HAVE_PREFETCH_ARG
 3343    #define WC_AES_HAVE_PREFETCH_ARG
 3344    static int always_prefetch = 0;
 3345    WC_MAYBE_UNUSED static int never_prefetch = 1;
 3346#endif
 3347WC_ARGS_NOT_NULL((1, 2, 3, 5))
 3348static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
 3349    word32 r, int *prefetch_ptr)
 3350{
 3351    word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0;
 3352    word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0;
 3353    const word32* rk;
 3354
 3355#ifdef WC_C_DYNAMIC_FALLBACK
 3356    rk = aes->key_C_fallback;
 3357#else
 3358    rk = aes->key;
 3359#endif
 3360
 3361    /*
 3362     * map byte array block to cipher state
 3363     * and add initial round key:
 3364     */
 3365    XMEMCPY(&s0, inBlock,                  sizeof(s0));
 3366    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
 3367    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
 3368    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
 3369
 3370#ifdef LITTLE_ENDIAN_ORDER
 3371    s0 = ByteReverseWord32(s0);
 3372    s1 = ByteReverseWord32(s1);
 3373    s2 = ByteReverseWord32(s2);
 3374    s3 = ByteReverseWord32(s3);
 3375#endif
 3376
 3377    s0 ^= rk[0];
 3378    s1 ^= rk[1];
 3379    s2 ^= rk[2];
 3380    s3 ^= rk[3];
 3381
 3382#ifndef WOLFSSL_AES_SMALL_TABLES
 3383
 3384#ifndef WC_NO_CACHE_RESISTANT
 3385    if (*prefetch_ptr == 0) {
 3386        s0 |= PreFetchTd();
 3387        /* don't set the prefetched flag here -- PreFetchTd4() is called
 3388         * below.
 3389         */
 3390    }
 3391#else
 3392    (void)prefetch_ptr;
 3393#endif
 3394
 3395#ifndef WOLFSSL_AES_TOUCH_LINES
 3396/* Unroll the loop. */
 3397#define DEC_ROUND_T_S(o)                                            \
 3398    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
 3399         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
 3400    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
 3401         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
 3402    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
 3403         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
 3404    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
 3405         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
 3406#define DEC_ROUND_S_T(o)                                            \
 3407    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
 3408         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
 3409    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
 3410         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
 3411    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
 3412         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
 3413    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
 3414         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
 3415#else
 3416#define DEC_ROUND_T_S(o)                                                       \
 3417    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
 3418                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
 3419    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
 3420                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
 3421    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
 3422                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
 3423    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
 3424                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
 3425    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
 3426
 3427#define DEC_ROUND_S_T(o)                                                       \
 3428    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
 3429                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
 3430    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
 3431                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
 3432    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
 3433                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
 3434    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
 3435                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
 3436    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
 3437#endif
 3438
 3439#ifndef WOLFSSL_AES_NO_UNROLL
 3440                       DEC_ROUND_T_S( 0);
 3441    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
 3442    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
 3443    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
 3444    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
 3445    if (r > 5) {
 3446        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
 3447        if (r > 6) {
 3448            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
 3449        }
 3450    }
 3451    rk += r * 8;
 3452#else
 3453
 3454    /*
 3455     * Nr - 1 full rounds:
 3456     */
 3457
 3458    for (;;) {
 3459        DEC_ROUND_T_S(0);
 3460
 3461        rk += 8;
 3462        if (--r == 0) {
 3463            break;
 3464        }
 3465
 3466        DEC_ROUND_S_T(0);
 3467    }
 3468#endif
 3469    /*
 3470     * apply last round and
 3471     * map cipher state to byte array block:
 3472     */
 3473
 3474#ifndef WC_NO_CACHE_RESISTANT
 3475    if (*prefetch_ptr == 0) {
 3476        t0 |= PreFetchTd4();
 3477        if (prefetch_ptr != &always_prefetch)
 3478            *prefetch_ptr = 1;
 3479    }
 3480#else
 3481    (void)prefetch_ptr;
 3482#endif
 3483
 3484    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
 3485                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
 3486    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
 3487                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
 3488    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
 3489                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
 3490    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
 3491                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
 3492
 3493#else /* WOLFSSL_AES_SMALL_TABLES */
 3494
 3495#ifndef WC_NO_CACHE_RESISTANT
 3496    if (*prefetch_ptr == 0) {
 3497        s0 |= PreFetchTd4();
 3498        if (prefetch_ptr != &always_prefetch)
 3499            *prefetch_ptr = 1;
 3500    }
 3501#else
 3502    (void)prefetch_ptr;
 3503#endif
 3504
 3505    r *= 2;
 3506    for (rk += 4; r > 1; r--, rk += 4) {
 3507        t0 =
 3508            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
 3509            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
 3510            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
 3511            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
 3512            rk[0];
 3513        t1 =
 3514            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
 3515            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
 3516            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
 3517            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
 3518            rk[1];
 3519        t2 =
 3520            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
 3521            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
 3522            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
 3523            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
 3524            rk[2];
 3525        t3 =
 3526            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
 3527            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
 3528            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
 3529            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
 3530            rk[3];
 3531
 3532        s0 =
 3533            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
 3534            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
 3535            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
 3536            (inv_col_mul(t0, 1, 3, 2, 0)      );
 3537        s1 =
 3538            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
 3539            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
 3540            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
 3541            (inv_col_mul(t1, 1, 3, 2, 0)      );
 3542        s2 =
 3543            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
 3544            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
 3545            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
 3546            (inv_col_mul(t2, 1, 3, 2, 0)      );
 3547        s3 =
 3548            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
 3549            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
 3550            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
 3551            (inv_col_mul(t3, 1, 3, 2, 0)      );
 3552    }
 3553
 3554    t0 =
 3555        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
 3556        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
 3557        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
 3558        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
 3559    t1 =
 3560        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
 3561        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
 3562        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
 3563        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
 3564    t2 =
 3565        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
 3566        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
 3567        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
 3568        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
 3569    t3 =
 3570        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
 3571        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
 3572        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
 3573        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
 3574    s0 = t0 ^ rk[0];
 3575    s1 = t1 ^ rk[1];
 3576    s2 = t2 ^ rk[2];
 3577    s3 = t3 ^ rk[3];
 3578
 3579#endif /* WOLFSSL_AES_SMALL_TABLES */
 3580
 3581    /* write out */
 3582#ifdef LITTLE_ENDIAN_ORDER
 3583    s0 = ByteReverseWord32(s0);
 3584    s1 = ByteReverseWord32(s1);
 3585    s2 = ByteReverseWord32(s2);
 3586    s3 = ByteReverseWord32(s3);
 3587#endif
 3588
 3589    XMEMCPY(outBlock,                  &s0, sizeof(s0));
 3590    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
 3591    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
 3592    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
 3593
 3594}
 3595
 3596#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
 3597    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM)) && \
 3598    !defined(MAX3266X_AES)
 3599#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
 3600/* Decrypt a number of blocks using AES.
 3601 *
 3602 * @param [in]  aes  AES object.
 3603 * @param [in]  in   Block to encrypt.
 3604 * @param [out] out  Encrypted block.
 3605 * @param [in]  sz   Number of blocks to encrypt.
 3606 */
 3607static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
 3608{
 3609    word32 i;
 3610    int did_prefetches = 0;
 3611
 3612    for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
 3613        AesDecrypt_C(aes, in, out, aes->rounds >> 1, &did_prefetches);
 3614        in += WC_AES_BLOCK_SIZE;
 3615        out += WC_AES_BLOCK_SIZE;
 3616    }
 3617}
 3618#endif
 3619#endif
 3620
 3621#else /* WC_AES_BITSLICED */
 3622
 3623/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
 3624static void bs_inv_sub_bytes(bs_word u[8])
 3625{
 3626    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
 3627    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
 3628    bs_word RTL0, RTL1, RTL2;
 3629    bs_word sa0, sa1;
 3630    bs_word sb0, sb1;
 3631    bs_word ab0, ab1, ab2, ab3;
 3632    bs_word ab20, ab21, ab22, ab23;
 3633    bs_word al, ah, aa, bl, bh, bb;
 3634    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
 3635    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
 3636    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
 3637    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
 3638    bs_word rr1, rr2;
 3639    bs_word r10, r11;
 3640    bs_word cp1, cp2, cp3, cp4;
 3641    bs_word vr1, vr2, vr3;
 3642    bs_word pr1, pr2, pr3;
 3643    bs_word wr1, wr2, wr3;
 3644    bs_word qr1, qr2, qr3;
 3645    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
 3646    bs_word tinv10, tinv11, tinv12, tinv13;
 3647    bs_word t01, t02;
 3648    bs_word d0, d1, d2, d3;
 3649    bs_word dl, dd, dh;
 3650    bs_word sd0, sd1;
 3651    bs_word p0, p1, p2, p3, p4, p6, p7;
 3652    bs_word X11, X13, X14, X16, X18, X19;
 3653    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
 3654
 3655    U0 = u[7];
 3656    U1 = u[6];
 3657    U2 = u[5];
 3658    U3 = u[4];
 3659    U4 = u[3];
 3660    U5 = u[2];
 3661    U6 = u[1];
 3662    U7 = u[0];
 3663
 3664    Y0 = U0 ^ U3;
 3665    Y2 = ~(U1 ^ U3);
 3666    Y4 = U0 ^ Y2;
 3667    RTL0 = U6 ^ U7;
 3668    Y1 = Y2 ^ RTL0;
 3669    Y7 = ~(U2 ^ Y1);
 3670    RTL1 = U3 ^ U4;
 3671    Y6 = ~(U7 ^ RTL1);
 3672    Y3 = Y1 ^ RTL1;
 3673    RTL2 = ~(U0 ^ U2);
 3674    Y5 = U5 ^ RTL2;
 3675    sa1 = Y0 ^ Y2;
 3676    sa0 = Y1 ^ Y3;
 3677    sb1 = Y4 ^ Y6;
 3678    sb0 = Y5 ^ Y7;
 3679    ah = Y0 ^ Y1;
 3680    al = Y2 ^ Y3;
 3681    aa = sa0 ^ sa1;
 3682    bh = Y4 ^ Y5;
 3683    bl = Y6 ^ Y7;
 3684    bb = sb0 ^ sb1;
 3685    ab20 = sa0 ^ sb0;
 3686    ab22 = al ^ bl;
 3687    ab23 = Y3 ^ Y7;
 3688    ab21 = sa1 ^ sb1;
 3689    abcd1 = ah & bh;
 3690    rr1 = Y0 & Y4;
 3691    ph11 = ab20 ^ abcd1;
 3692    t01 = Y1 & Y5;
 3693    ph01 = t01 ^ abcd1;
 3694    abcd2 = al & bl;
 3695    r1 = Y2 & Y6;
 3696    pl11 = ab22 ^ abcd2;
 3697    r2 = Y3 & Y7;
 3698    pl01 = r2 ^ abcd2;
 3699    r3 = sa0 & sb0;
 3700    vr1 = aa & bb;
 3701    pr1 = vr1 ^ r3;
 3702    wr1 = sa1 & sb1;
 3703    qr1 = wr1 ^ r3;
 3704    ab0 = ph11 ^ rr1;
 3705    ab1 = ph01 ^ ab21;
 3706    ab2 = pl11 ^ r1;
 3707    ab3 = pl01 ^ qr1;
 3708    cp1 = ab0 ^ pr1;
 3709    cp2 = ab1 ^ qr1;
 3710    cp3 = ab2 ^ pr1;
 3711    cp4 = ab3 ^ ab23;
 3712    tinv1 = cp3 ^ cp4;
 3713    tinv2 = cp3 & cp1;
 3714    tinv3 = cp2 ^ tinv2;
 3715    tinv4 = cp1 ^ cp2;
 3716    tinv5 = cp4 ^ tinv2;
 3717    tinv6 = tinv5 & tinv4;
 3718    tinv7 = tinv3 & tinv1;
 3719    d2 = cp4 ^ tinv7;
 3720    d0 = cp2 ^ tinv6;
 3721    tinv8 = cp1 & cp4;
 3722    tinv9 = tinv4 & tinv8;
 3723    tinv10 = tinv4 ^ tinv2;
 3724    d1 = tinv9 ^ tinv10;
 3725    tinv11 = cp2 & cp3;
 3726    tinv12 = tinv1 & tinv11;
 3727    tinv13 = tinv1 ^ tinv2;
 3728    d3 = tinv12 ^ tinv13;
 3729    sd1 = d1 ^ d3;
 3730    sd0 = d0 ^ d2;
 3731    dl = d0 ^ d1;
 3732    dh = d2 ^ d3;
 3733    dd = sd0 ^ sd1;
 3734    abcd3 = dh & bh;
 3735    rr2 = d3 & Y4;
 3736    t02 = d2 & Y5;
 3737    abcd4 = dl & bl;
 3738    r4 = d1 & Y6;
 3739    r5 = d0 & Y7;
 3740    r6 = sd0 & sb0;
 3741    vr2 = dd & bb;
 3742    wr2 = sd1 & sb1;
 3743    abcd5 = dh & ah;
 3744    r7 = d3 & Y0;
 3745    r8 = d2 & Y1;
 3746    abcd6 = dl & al;
 3747    r9 = d1 & Y2;
 3748    r10 = d0 & Y3;
 3749    r11 = sd0 & sa0;
 3750    vr3 = dd & aa;
 3751    wr3 = sd1 & sa1;
 3752    ph12 = rr2 ^ abcd3;
 3753    ph02 = t02 ^ abcd3;
 3754    pl12 = r4 ^ abcd4;
 3755    pl02 = r5 ^ abcd4;
 3756    pr2 = vr2 ^ r6;
 3757    qr2 = wr2 ^ r6;
 3758    p0 = ph12 ^ pr2;
 3759    p1 = ph02 ^ qr2;
 3760    p2 = pl12 ^ pr2;
 3761    p3 = pl02 ^ qr2;
 3762    ph13 = r7 ^ abcd5;
 3763    ph03 = r8 ^ abcd5;
 3764    pl13 = r9 ^ abcd6;
 3765    pl03 = r10 ^ abcd6;
 3766    pr3 = vr3 ^ r11;
 3767    qr3 = wr3 ^ r11;
 3768    p4 = ph13 ^ pr3;
 3769    S7 = ph03 ^ qr3;
 3770    p6 = pl13 ^ pr3;
 3771    p7 = pl03 ^ qr3;
 3772    S3 = p1 ^ p6;
 3773    S6 = p2 ^ p6;
 3774    S0 = p3 ^ p6;
 3775    X11 = p0 ^ p2;
 3776    S5 = S0 ^ X11;
 3777    X13 = p4 ^ p7;
 3778    X14 = X11 ^ X13;
 3779    S1 = S3 ^ X14;
 3780    X16 = p1 ^ S7;
 3781    S2 = X14 ^ X16;
 3782    X18 = p0 ^ p4;
 3783    X19 = S5 ^ X16;
 3784    S4 = X18 ^ X19;
 3785
 3786    u[0] = S7;
 3787    u[1] = S6;
 3788    u[2] = S5;
 3789    u[3] = S4;
 3790    u[4] = S3;
 3791    u[5] = S2;
 3792    u[6] = S1;
 3793    u[7] = S0;
 3794}
 3795
 3796static void bs_inv_shift_rows(bs_word* b)
 3797{
 3798    bs_word t[AES_BLOCK_BITS];
 3799    int i;
 3800
 3801    for (i = 0; i < 128; i += 32) {
 3802        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
 3803        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
 3804        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
 3805        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
 3806    }
 3807
 3808    XMEMCPY(b, t, sizeof(t));
 3809}
 3810
 3811#define O0  0
 3812#define O1  8
 3813#define O2  16
 3814#define O3  24
 3815
 3816#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
 3817    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
 3818          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
 3819    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
 3820          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
 3821    of2 =                     b[O0+7] ^             b[O1+7] ^               \
 3822                    b[O2+7] ^ b[O3+7];                                      \
 3823                                                                            \
 3824    br[0] =                                                   b[O1+0] ^     \
 3825            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
 3826    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
 3827            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
 3828    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
 3829            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
 3830    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
 3831            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
 3832    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
 3833            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
 3834    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
 3835            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
 3836    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
 3837            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
 3838    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
 3839            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
 3840
 3841/* Inverse mix columns and shift rows. */
 3842static void bs_inv_mix_shift(bs_word* t, bs_word* b)
 3843{
 3844    bs_word* bp = b;
 3845    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
 3846    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
 3847    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
 3848    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
 3849    int i;
 3850
 3851    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
 3852        bs_word* br;
 3853        bs_word of0;
 3854        bs_word of1;
 3855        bs_word of2;
 3856
 3857        br = t + or0;
 3858        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
 3859        br = t + or1;
 3860        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
 3861        br = t + or2;
 3862        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
 3863        br = t + or3;
 3864        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
 3865
 3866        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
 3867        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
 3868        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
 3869        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
 3870
 3871        bp += AES_BLOCK_BITS / 4;
 3872    }
 3873}
 3874
 3875static void bs_inv_sub_bytes_blocks(bs_word* b)
 3876{
 3877    int i;
 3878
 3879    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
 3880        bs_inv_sub_bytes(b + i);
 3881    }
 3882}
 3883
 3884static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
 3885{
 3886    int i;
 3887    bs_word trans[AES_BLOCK_BITS];
 3888
 3889    bs_transpose(trans, state);
 3890
 3891    rk += r * AES_BLOCK_BITS;
 3892    bs_add_round_key(trans, trans, rk);
 3893    bs_inv_shift_rows(trans);
 3894    bs_inv_sub_bytes_blocks(trans);
 3895    rk -= AES_BLOCK_BITS;
 3896    bs_add_round_key(trans, trans, rk);
 3897    for (i = (int)r - 2; i >= 0; i--) {
 3898        bs_inv_mix_shift(state, trans);
 3899        bs_inv_sub_bytes_blocks(state);
 3900        rk -= AES_BLOCK_BITS;
 3901        bs_add_round_key(trans, state, rk);
 3902    }
 3903
 3904    bs_inv_transpose(state, trans);
 3905}
 3906
 3907#ifdef WOLFSSL_AES_DIRECT
 3908/* Decrypt a block using AES.
 3909 *
 3910 * @param [in]  aes       AES object.
 3911 * @param [in]  inBlock   Block to encrypt.
 3912 * @param [out] outBlock  Encrypted block.
 3913 * @param [in]  r         Rounds divided by 2.
 3914 */
 3915static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
 3916    word32 r)
 3917{
 3918    bs_word state[AES_BLOCK_BITS];
 3919
 3920    (void)r;
 3921
 3922    XMEMCPY(state, inBlock, WC_AES_BLOCK_SIZE);
 3923    XMEMSET(((byte*)state) + WC_AES_BLOCK_SIZE, 0, sizeof(state) - WC_AES_BLOCK_SIZE);
 3924
 3925    bs_decrypt(state, aes->bs_key, aes->rounds);
 3926
 3927    XMEMCPY(outBlock, state, WC_AES_BLOCK_SIZE);
 3928}
 3929#endif
 3930
 3931#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
 3932    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
 3933/* Decrypt a number of blocks using AES.
 3934 *
 3935 * @param [in]  aes  AES object.
 3936 * @param [in]  in   Block to encrypt.
 3937 * @param [out] out  Encrypted block.
 3938 * @param [in]  sz   Number of blocks to encrypt.
 3939 */
 3940static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
 3941{
 3942    bs_word state[AES_BLOCK_BITS];
 3943
 3944    while (sz >= BS_BLOCK_SIZE) {
 3945        XMEMCPY(state, in, BS_BLOCK_SIZE);
 3946        bs_decrypt(state, aes->bs_key, aes->rounds);
 3947        XMEMCPY(out, state, BS_BLOCK_SIZE);
 3948        sz  -= BS_BLOCK_SIZE;
 3949        in  += BS_BLOCK_SIZE;
 3950        out += BS_BLOCK_SIZE;
 3951    }
 3952    if (sz > 0) {
 3953        XMEMCPY(state, in, sz);
 3954        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
 3955        bs_decrypt(state, aes->bs_key, aes->rounds);
 3956        XMEMCPY(out, state, sz);
 3957    }
 3958}
 3959#endif
 3960
 3961#endif /* !WC_AES_BITSLICED */
 3962#endif
 3963
 3964#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \
 3965    defined(WOLFSSL_AES_DIRECT)
 3966#if defined(__aarch64__) || !defined(WOLFSSL_ARMASM)
 3967#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
 3968/* Software AES - ECB Decrypt */
 3969
 3970#ifdef WC_AES_HAVE_PREFETCH_ARG
 3971#define wc_AesDecrypt(aes, inBlock, outBlock) \
 3972    AesDecrypt_preFetchOpt(aes, inBlock, outBlock, &always_prefetch)
 3973WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int AesDecrypt_preFetchOpt(
 3974    Aes* aes, const byte* inBlock, byte* outBlock, int *prefetch_ptr)
 3975#else
 3976#define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, prefetch_ptr) \
 3977    wc_AesDecrypt(aes, inBlock, outBlock)
 3978WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
 3979    Aes* aes, const byte* inBlock, byte* outBlock)
 3980#endif
 3981{
 3982#if defined(MAX3266X_AES)
 3983    word32 keySize;
 3984#endif
 3985#if defined(MAX3266X_CB)
 3986    int ret_cb;
 3987#endif
 3988    word32 r;
 3989
 3990#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 3991    {
 3992        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 3993        if (ret < 0)
 3994            return ret;
 3995    }
 3996#endif
 3997
 3998    r = aes->rounds >> 1;
 3999
 4000    if (r > 7 || r == 0) {
 4001        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
 4002        return KEYUSAGE_E;
 4003    }
 4004
 4005#ifdef WOLFSSL_AESNI
 4006    if (aes->use_aesni) {
 4007        ASSERT_SAVED_VECTOR_REGISTERS();
 4008
 4009        #ifdef DEBUG_AESNI
 4010            printf("about to aes decrypt\n");
 4011            printf("in  = %p\n", inBlock);
 4012            printf("out = %p\n", outBlock);
 4013            printf("aes->key = %p\n", aes->key);
 4014            printf("aes->rounds = %d\n", aes->rounds);
 4015            printf("sz = %d\n", WC_AES_BLOCK_SIZE);
 4016        #endif
 4017
 4018        /* if input and output same will overwrite input iv */
 4019        if ((const byte*)aes->tmp != inBlock)
 4020            XMEMCPY(aes->tmp, inBlock, WC_AES_BLOCK_SIZE);
 4021        AES_ECB_decrypt_AESNI(inBlock, outBlock, WC_AES_BLOCK_SIZE, (byte*)aes->key,
 4022                        (int)aes->rounds);
 4023        return 0;
 4024    }
 4025    else {
 4026        #ifdef DEBUG_AESNI
 4027            printf("Skipping AES-NI\n");
 4028        #endif
 4029    }
 4030#elif defined(WOLFSSL_ARMASM)
 4031#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
 4032#if !defined(__aarch64__)
 4033    AES_decrypt_AARCH32(inBlock, outBlock, (byte*)aes->key, (int)aes->rounds);
 4034#else
 4035    if (aes->use_aes_hw_crypto) {
 4036        AES_decrypt_AARCH64(inBlock, outBlock, (byte*)aes->key,
 4037            (int)aes->rounds);
 4038    }
 4039    else
 4040#endif /* !__aarch64__ */
 4041#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
 4042#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
 4043    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
 4044    {
 4045        AES_ECB_decrypt_NEON(inBlock, outBlock, WC_AES_BLOCK_SIZE,
 4046            (const unsigned char*)aes->key, aes->rounds);
 4047    }
 4048#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 4049    {
 4050        AES_ECB_decrypt(inBlock, outBlock, WC_AES_BLOCK_SIZE,
 4051            (const unsigned char*)aes->key, aes->rounds);
 4052    }
 4053#endif
 4054    return 0;
 4055#endif /* WOLFSSL_AESNI */
 4056#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
 4057    return AES_ECB_decrypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE);
 4058#endif
 4059#if defined(WOLFSSL_IMXRT_DCP)
 4060    if (aes->keylen == 16) {
 4061        DCPAesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
 4062        return 0;
 4063    }
 4064#endif
 4065#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
 4066    if (aes->useSWCrypt == 0) {
 4067        return se050_aes_crypt(aes, inBlock, outBlock, WC_AES_BLOCK_SIZE,
 4068                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
 4069    }
 4070#endif
 4071#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
 4072    if (wc_esp32AesSupportedKeyLen(aes)) {
 4073        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
 4074    }
 4075    else {
 4076        /* For example, the ESP32-S3 does not support HW for len = 24,
 4077         * so fall back to SW */
 4078    #ifdef DEBUG_WOLFSSL
 4079        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
 4080                        "unsupported keylen = %d", aes->keylen);
 4081    #endif
 4082    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
 4083#endif
 4084
 4085#if defined(MAX3266X_AES)
 4086    if (wc_AesGetKeySize(aes, &keySize) == 0) {
 4087        return wc_MXC_TPU_AesDecrypt(inBlock, (byte*)aes->reg, (byte*)aes->key,
 4088                                    MXC_TPU_MODE_ECB, WC_AES_BLOCK_SIZE,
 4089                                    outBlock, (unsigned int)keySize);
 4090    }
 4091#endif
 4092
 4093#if defined(MAX3266X_CB) && defined(HAVE_AES_ECB) /* Can do a basic ECB block */
 4094    #ifndef WOLF_CRYPTO_CB_FIND
 4095    if (aes->devId != INVALID_DEVID)
 4096    #endif
 4097    {
 4098        ret_cb = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock,
 4099                                            WC_AES_BLOCK_SIZE);
 4100        if (ret_cb != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 4101            return ret_cb;
 4102        /* fall-through when unavailable */
 4103    }
 4104#endif
 4105
 4106#ifdef WC_AES_HAVE_PREFETCH_ARG
 4107    AesDecrypt_C(aes, inBlock, outBlock, r, prefetch_ptr);
 4108#else
 4109    AesDecrypt_C(aes, inBlock, outBlock, r);
 4110#endif
 4111
 4112    return 0;
 4113} /* wc_AesDecrypt[_SW]() */
 4114#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
 4115#endif
 4116#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
 4117#endif /* HAVE_AES_DECRYPT */
 4118
 4119#endif /* NEED_AES_TABLES */
 4120
 4121#ifdef WOLF_CRYPTO_CB_ONLY_AES
 4122/* Under WOLF_CRYPTO_CB_ONLY_AES the per-block primitive is a thin shim over
 4123 * the cryptocb ECB callback. When the callback returns CRYPTOCB_UNAVAILABLE
 4124 * there is no software fallback, so the operation fails with NO_VALID_DEVID. */
 4125static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
 4126    byte* outBlock)
 4127{
 4128    int ret;
 4129
 4130    if (aes == NULL || inBlock == NULL || outBlock == NULL)
 4131        return BAD_FUNC_ARG;
 4132#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 4133    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 4134    if (ret < 0)
 4135        return ret;
 4136#endif
 4137
 4138    ret = wc_CryptoCb_AesEcbEncrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
 4139    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 4140        return ret;
 4141    return NO_VALID_DEVID;
 4142}
 4143
 4144#ifdef HAVE_AES_DECRYPT
 4145static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
 4146    byte* outBlock)
 4147{
 4148    int ret;
 4149
 4150    if (aes == NULL || inBlock == NULL || outBlock == NULL)
 4151        return BAD_FUNC_ARG;
 4152#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 4153    ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 4154    if (ret < 0)
 4155        return ret;
 4156#endif
 4157
 4158    ret = wc_CryptoCb_AesEcbDecrypt(aes, outBlock, inBlock, WC_AES_BLOCK_SIZE);
 4159    if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 4160        return ret;
 4161    return NO_VALID_DEVID;
 4162}
 4163#endif /* HAVE_AES_DECRYPT */
 4164#endif /* WOLF_CRYPTO_CB_ONLY_AES */
 4165
 4166#ifndef WC_AES_HAVE_PREFETCH_ARG
 4167    #ifndef AesEncrypt_preFetchOpt
 4168        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
 4169            wc_AesEncrypt(aes, inBlock, outBlock)
 4170    #endif
 4171    #ifndef AesDecrypt_preFetchOpt
 4172        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
 4173            wc_AesDecrypt(aes, inBlock, outBlock)
 4174    #endif
 4175#endif
 4176
 4177/* wc_AesSetKey */
 4178#if defined(STM32_CRYPTO)
 4179
 4180    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
 4181            const byte* iv, int dir)
 4182    {
 4183        word32 *rk;
 4184
 4185        (void)dir;
 4186
 4187        if (aes == NULL || (keylen != 16 &&
 4188        #ifdef WOLFSSL_AES_192
 4189            keylen != 24 &&
 4190        #endif
 4191            keylen != 32)) {
 4192            return BAD_FUNC_ARG;
 4193        }
 4194
 4195#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 4196        {
 4197            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 4198            if (ret < 0)
 4199                return ret;
 4200        }
 4201#endif
 4202
 4203        rk = aes->key;
 4204        aes->keylen = keylen;
 4205        aes->rounds = keylen/4 + 6;
 4206        XMEMCPY(rk, userKey, keylen);
 4207    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
 4208        ByteReverseWords(rk, rk, keylen);
 4209    #endif
 4210    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 4211        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 4212        defined(WOLFSSL_AES_CTS)
 4213        aes->left = 0;
 4214    #endif
 4215        return wc_AesSetIV(aes, iv);
 4216    }
 4217    #if defined(WOLFSSL_AES_DIRECT)
 4218        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
 4219                            const byte* iv, int dir)
 4220        {
 4221            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
 4222        }
 4223    #endif
 4224
 4225#elif defined(HAVE_COLDFIRE_SEC)
 4226    #if defined (HAVE_THREADX)
 4227        #include "memory_pools.h"
 4228        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
 4229    #endif
 4230
 4231    #define AES_BUFFER_SIZE (WC_AES_BLOCK_SIZE * 64)
 4232    static unsigned char *AESBuffIn = NULL;
 4233    static unsigned char *AESBuffOut = NULL;
 4234    static byte *secReg;
 4235    static byte *secKey;
 4236    static volatile SECdescriptorType *secDesc;
 4237
 4238    static wolfSSL_Mutex Mutex_AesSEC;
 4239
 4240    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
 4241    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
 4242
 4243    extern volatile unsigned char __MBAR[];
 4244
 4245    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
 4246        const byte* iv, int dir)
 4247    {
 4248        if (AESBuffIn == NULL) {
 4249        #if defined (HAVE_THREADX)
 4250            int s1, s2, s3, s4, s5;
 4251            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
 4252                                  sizeof(SECdescriptorType), TX_NO_WAIT);
 4253            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
 4254                                  AES_BUFFER_SIZE, TX_NO_WAIT);
 4255            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
 4256                                  AES_BUFFER_SIZE, TX_NO_WAIT);
 4257            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
 4258                                  WC_AES_BLOCK_SIZE*2, TX_NO_WAIT);
 4259            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
 4260                                  WC_AES_BLOCK_SIZE, TX_NO_WAIT);
 4261
 4262            if (s1 || s2 || s3 || s4 || s5)
 4263                return BAD_FUNC_ARG;
 4264        #else
 4265            #warning "Allocate non-Cache buffers"
 4266        #endif
 4267
 4268            wc_InitMutex(&Mutex_AesSEC);
 4269        }
 4270
 4271        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
 4272            return BAD_FUNC_ARG;
 4273
 4274        if (aes == NULL)
 4275            return BAD_FUNC_ARG;
 4276
 4277#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 4278        {
 4279            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 4280            if (ret < 0)
 4281                return ret;
 4282        }
 4283#endif
 4284
 4285        aes->keylen = keylen;
 4286        aes->rounds = keylen/4 + 6;
 4287        XMEMCPY(aes->key, userKey, keylen);
 4288
 4289        if (iv)
 4290            XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
 4291
 4292    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 4293        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 4294        defined(WOLFSSL_AES_CTS)
 4295        aes->left = 0;
 4296    #endif
 4297
 4298        return 0;
 4299    }
 4300#elif defined(FREESCALE_LTC)
 4301    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
 4302        const byte* iv, int dir, int checkKeyLen)
 4303    {
 4304        if (aes == NULL)
 4305            return BAD_FUNC_ARG;
 4306
 4307#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 4308        {
 4309            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 4310            if (ret < 0)
 4311                return ret;
 4312        }
 4313#endif
 4314
 4315        if (checkKeyLen) {
 4316            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
 4317                return BAD_FUNC_ARG;
 4318        }
 4319        (void)dir;
 4320
 4321        aes->rounds = keylen/4 + 6;
 4322        XMEMCPY(aes->key, userKey, keylen);
 4323
 4324    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 4325        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 4326        defined(WOLFSSL_AES_CTS)
 4327        aes->left = 0;
 4328    #endif
 4329
 4330        return wc_AesSetIV(aes, iv);
 4331    }
 4332
 4333    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
 4334        const byte* iv, int dir)
 4335    {
 4336        if (aes == NULL || userKey == NULL) {
 4337            return BAD_FUNC_ARG;
 4338        }
 4339        if (keylen > sizeof(aes->key)) {
 4340            return BAD_FUNC_ARG;
 4341        }
 4342
 4343        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
 4344    }
 4345
 4346    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
 4347                        const byte* iv, int dir)
 4348    {
 4349        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
 4350    }
 4351#elif defined(WOLFSSL_NRF51_AES)
 4352    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
 4353        const byte* iv, int dir)
 4354    {
 4355        int ret;
 4356
 4357        (void)dir;
 4358        (void)iv;
 4359
 4360        if (aes == NULL || keylen != 16)
 4361            return BAD_FUNC_ARG;
 4362
 4363#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 4364        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 4365        if (ret < 0)
 4366            return ret;
 4367#endif
 4368
 4369        aes->keylen = keylen;
 4370        aes->rounds = keylen/4 + 6;
 4371        XMEMCPY(aes->key, userKey, keylen);
 4372        ret = nrf51_aes_set_key(userKey);
 4373
 4374    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 4375        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 4376        defined(WOLFSSL_AES_CTS)
 4377        aes->left = 0;
 4378    #endif
 4379
 4380        return ret;
 4381    }
 4382
 4383    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
 4384                        const byte* iv, int dir)
 4385    {
 4386        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
 4387    }
 4388#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
 4389    /* This is the only definition for HW only.
 4390     * but needs to be renamed when fallback needed.
 4391     * See call in wc_AesSetKey() */
 4392    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
 4393        const byte* iv, int dir)
 4394    {
 4395        (void)dir;
 4396        (void)iv;
 4397        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
 4398        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
 4399            return BAD_FUNC_ARG;
 4400        }
 4401
 4402#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 4403        {
 4404            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 4405            if (ret < 0)
 4406                return ret;
 4407        }
 4408#endif
 4409
 4410    #if !defined(WOLFSSL_AES_128)
 4411        if (keylen == 16) {
 4412            return BAD_FUNC_ARG;
 4413        }
 4414    #endif
 4415
 4416    #if !defined(WOLFSSL_AES_192)
 4417        if (keylen == 24) {
 4418            return BAD_FUNC_ARG;
 4419        }
 4420    #endif
 4421
 4422    #if !defined(WOLFSSL_AES_256)
 4423        if (keylen == 32) {
 4424            return BAD_FUNC_ARG;
 4425        }
 4426    #endif
 4427
 4428        aes->keylen = keylen;
 4429        aes->rounds = keylen/4 + 6;
 4430
 4431        XMEMCPY(aes->key, userKey, keylen);
 4432        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 4433            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 4434            defined(WOLFSSL_AES_CTS)
 4435            aes->left = 0;
 4436        #endif
 4437        return wc_AesSetIV(aes, iv);
 4438    } /* wc_AesSetKey */
 4439
 4440    /* end #elif ESP32 */
 4441#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
 4442
 4443    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
 4444                    int dir)
 4445    {
 4446        SaSiError_t ret = SASI_OK;
 4447        SaSiAesIv_t iv_aes;
 4448
 4449        if (aes == NULL ||
 4450           (keylen != AES_128_KEY_SIZE &&
 4451            keylen != AES_192_KEY_SIZE &&
 4452            keylen != AES_256_KEY_SIZE)) {
 4453            return BAD_FUNC_ARG;
 4454        }
 4455
 4456#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 4457        {
 4458            int ret2 =
 4459                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 4460            if (ret2 < 0)
 4461                return ret2;
 4462        }
 4463#endif
 4464
 4465    #if defined(AES_MAX_KEY_SIZE)
 4466        if (keylen > (AES_MAX_KEY_SIZE/8)) {
 4467            return BAD_FUNC_ARG;
 4468        }
 4469    #endif
 4470        if (dir != AES_ENCRYPTION &&
 4471            dir != AES_DECRYPTION) {
 4472            return BAD_FUNC_ARG;
 4473        }
 4474
 4475        if (dir == AES_ENCRYPTION) {
 4476            aes->ctx.mode = SASI_AES_ENCRYPT;
 4477            SaSi_AesInit(&aes->ctx.user_ctx,
 4478                         SASI_AES_ENCRYPT,
 4479                         SASI_AES_MODE_CBC,
 4480                         SASI_AES_PADDING_NONE);
 4481        }
 4482        else {
 4483            aes->ctx.mode = SASI_AES_DECRYPT;
 4484            SaSi_AesInit(&aes->ctx.user_ctx,
 4485                         SASI_AES_DECRYPT,
 4486                         SASI_AES_MODE_CBC,
 4487                         SASI_AES_PADDING_NONE);
 4488        }
 4489
 4490        aes->keylen = keylen;
 4491        aes->rounds = keylen/4 + 6;
 4492        XMEMCPY(aes->key, userKey, keylen);
 4493
 4494        aes->ctx.key.pKey = (byte*)aes->key;
 4495        aes->ctx.key.keySize= keylen;
 4496
 4497        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
 4498                             SASI_AES_USER_KEY,
 4499                             &aes->ctx.key,
 4500                             sizeof(aes->ctx.key));
 4501        if (ret != SASI_OK) {
 4502            return BAD_FUNC_ARG;
 4503        }
 4504
 4505        ret = wc_AesSetIV(aes, iv);
 4506
 4507        if (iv)
 4508            XMEMCPY(iv_aes, iv, WC_AES_BLOCK_SIZE);
 4509        else
 4510            XMEMSET(iv_aes,  0, WC_AES_BLOCK_SIZE);
 4511
 4512
 4513        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
 4514        if (ret != SASI_OK) {
 4515            return ret;
 4516        }
 4517       return ret;
 4518    }
 4519    #if defined(WOLFSSL_AES_DIRECT)
 4520        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
 4521                            const byte* iv, int dir)
 4522        {
 4523            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
 4524        }
 4525    #endif
 4526
 4527#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
 4528    && !defined(WOLFSSL_QNX_CAAM)
 4529      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
 4530
 4531#elif defined(WOLFSSL_AFALG)
 4532    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
 4533
 4534#elif defined(WOLFSSL_DEVCRYPTO_AES)
 4535    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
 4536
 4537#elif defined(WOLFSSL_SILABS_SE_ACCEL)
 4538    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
 4539
 4540#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
 4541     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
 4542    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
 4543
 4544#elif !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
 4545    static int AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
 4546            const byte* iv, int dir)
 4547    {
 4548    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 4549        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 4550        defined(WOLFSSL_AES_CTS)
 4551        aes->left = 0;
 4552    #endif
 4553
 4554        aes->keylen = (int)keylen;
 4555        aes->rounds = (keylen/4) + 6;
 4556
 4557#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
 4558        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
 4559#else
 4560        AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
 4561
 4562    #ifdef HAVE_AES_DECRYPT
 4563        if (dir == AES_DECRYPTION) {
 4564            AES_invert_key((byte*)aes->key, aes->rounds);
 4565        }
 4566    #else
 4567        (void)dir;
 4568    #endif
 4569#endif
 4570        return wc_AesSetIV(aes, iv);
 4571    }
 4572
 4573    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
 4574            const byte* iv, int dir)
 4575    {
 4576#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
 4577        int cbRet;
 4578#endif
 4579        if ((aes == NULL) || (userKey == NULL)) {
 4580            return BAD_FUNC_ARG;
 4581        }
 4582
 4583        switch (keylen) {
 4584    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
 4585        defined(WOLFSSL_AES_128)
 4586        case 16:
 4587    #endif
 4588    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
 4589        defined(WOLFSSL_AES_192)
 4590        case 24:
 4591    #endif
 4592    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
 4593        defined(WOLFSSL_AES_256)
 4594        case 32:
 4595    #endif
 4596            break;
 4597        default:
 4598            return BAD_FUNC_ARG;
 4599        }
 4600
 4601    #ifdef WOLF_CRYPTO_CB
 4602        if (aes->devId != INVALID_DEVID) {
 4603        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
 4604            int ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
 4605            if (ret == 0) {
 4606                /* Callback succeeded - SE owns the key */
 4607                aes->keylen = (int)keylen;
 4608                if (iv != NULL)
 4609                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
 4610                else
 4611                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
 4612                return 0;
 4613            }
 4614            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
 4615                aes->devCtx = NULL;
 4616                return ret;
 4617            }
 4618            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
 4619        #endif
 4620        #ifdef WOLF_CRYPTO_CB_SETKEY
 4621            cbRet = wc_CryptoCb_SetKey(aes->devId,
 4622                WC_SETKEY_AES, aes, (void*)userKey, keylen,
 4623                (void*)iv,
 4624                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
 4625            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 4626                return cbRet;
 4627            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
 4628        #endif /* WOLF_CRYPTO_CB_SETKEY */
 4629            /* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
 4630            if (keylen > sizeof(aes->devKey)) {
 4631                return BAD_FUNC_ARG;
 4632            }
 4633            XMEMCPY(aes->devKey, userKey, keylen);
 4634        }
 4635    #endif
 4636
 4637        return AesSetKey(aes, userKey, keylen, iv, dir);
 4638    }
 4639
 4640    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
 4641        /* AES-CTR and AES-DIRECT need to use this for key setup */
 4642        /* This function allows key sizes that are not 128/192/256 bits */
 4643    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
 4644                           const byte* iv, int dir)
 4645    {
 4646        if (aes == NULL) {
 4647            return BAD_FUNC_ARG;
 4648        }
 4649        if (keylen > sizeof(aes->key)) {
 4650            return BAD_FUNC_ARG;
 4651        }
 4652
 4653        return AesSetKey(aes, userKey, keylen, iv, dir);
 4654    }
 4655    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
 4656#elif defined(FREESCALE_MMCAU)
 4657    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
 4658        const byte* iv, int dir, int checkKeyLen)
 4659    {
 4660        int ret;
 4661        byte* rk;
 4662        byte* tmpKey = (byte*)userKey;
 4663        int tmpKeyDynamic = 0;
 4664        word32 alignOffset = 0;
 4665
 4666        (void)dir;
 4667
 4668        if (aes == NULL)
 4669            return BAD_FUNC_ARG;
 4670
 4671#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 4672        {
 4673            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 4674            if (ret < 0)
 4675                return ret;
 4676        }
 4677#endif
 4678
 4679        if (checkKeyLen) {
 4680            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
 4681                return BAD_FUNC_ARG;
 4682        }
 4683
 4684        rk = (byte*)aes->key;
 4685        if (rk == NULL)
 4686            return BAD_FUNC_ARG;
 4687
 4688    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 4689        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 4690        defined(WOLFSSL_AES_CTS)
 4691        aes->left = 0;
 4692    #endif
 4693
 4694        aes->rounds = keylen/4 + 6;
 4695
 4696    #ifdef FREESCALE_MMCAU_CLASSIC
 4697        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
 4698        #ifndef NO_WOLFSSL_ALLOC_ALIGN
 4699            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
 4700                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
 4701            if (tmp == NULL) {
 4702                return MEMORY_E;
 4703            }
 4704            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
 4705                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
 4706            tmpKey = tmp + alignOffset;
 4707            XMEMCPY(tmpKey, userKey, keylen);
 4708            tmpKeyDynamic = 1;
 4709        #else
 4710            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
 4711            return BAD_ALIGN_E;
 4712        #endif
 4713        }
 4714    #endif
 4715
 4716        ret = wolfSSL_CryptHwMutexLock();
 4717        if(ret == 0) {
 4718        #ifdef FREESCALE_MMCAU_CLASSIC
 4719            cau_aes_set_key(tmpKey, keylen*8, rk);
 4720        #else
 4721            MMCAU_AES_SetKey(tmpKey, keylen, rk);
 4722        #endif
 4723            wolfSSL_CryptHwMutexUnLock();
 4724
 4725            ret = wc_AesSetIV(aes, iv);
 4726        }
 4727
 4728        if (tmpKeyDynamic == 1) {
 4729            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
 4730        }
 4731
 4732        return ret;
 4733    }
 4734
 4735    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
 4736        const byte* iv, int dir)
 4737    {
 4738        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
 4739    }
 4740
 4741    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
 4742                        const byte* iv, int dir)
 4743    {
 4744        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
 4745    }
 4746
 4747#elif defined(WOLFSSL_PSOC6_CRYPTO)
 4748
 4749    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
 4750        const byte* iv, int dir)
 4751    {
 4752        return wc_Psoc6_Aes_SetKey(aes, userKey, keylen, iv, dir);
 4753    }
 4754
 4755    #if defined(WOLFSSL_AES_DIRECT)
 4756        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
 4757                            const byte* iv, int dir)
 4758        {
 4759            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
 4760        }
 4761    #endif /* WOLFSSL_AES_DIRECT */
 4762#else
 4763    #define NEED_SOFTWARE_AES_SETKEY
 4764#endif
 4765
 4766/* Either we fell though with no HW support at all,
 4767 * or perhaps there's HW support for *some* keylengths
 4768 * and we need both HW and SW. */
 4769#ifdef NEED_SOFTWARE_AES_SETKEY
 4770
 4771#ifdef NEED_AES_TABLES
 4772
 4773#ifndef WC_AES_BITSLICED
 4774#if !defined(WOLFSSL_ARMASM)
 4775/* Set the AES key and expand.
 4776 *
 4777 * @param [in]  aes    AES object.
 4778 * @param [in]  key    Block to encrypt.
 4779 * @param [in]  keySz  Number of bytes in key.
 4780 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
 4781 */
 4782static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
 4783{
 4784#ifdef WC_C_DYNAMIC_FALLBACK
 4785    word32* rk = aes->key_C_fallback;
 4786#else
 4787    word32* rk = aes->key;
 4788#endif
 4789    word32 temp;
 4790    unsigned int i = 0;
 4791
 4792    XMEMCPY(rk, key, keySz);
 4793#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
 4794    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) && \
 4795    !defined(MAX3266X_AES)
 4796    /* Always reverse words when using only SW */
 4797    {
 4798        ByteReverseWords(rk, rk, keySz);
 4799    }
 4800#else
 4801    /* Sometimes reverse words when using supported HW */
 4802    #if defined(WOLFSSL_ESPIDF)
 4803        /* Some platforms may need SW fallback (e.g. AES192) */
 4804        #if defined(NEED_AES_HW_FALLBACK)
 4805        {
 4806            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
 4807            if (wc_esp32AesSupportedKeyLen(aes)) {
 4808                /* don't reverse for HW supported key lengths */
 4809            }
 4810            else {
 4811                ByteReverseWords(rk, rk, keySz);
 4812            }
 4813        }
 4814        #else
 4815            /* If we don't need SW fallback, don't need to reverse words. */
 4816        #endif /* NEED_AES_HW_FALLBACK */
 4817    #endif /* WOLFSSL_ESPIDF */
 4818#endif /* LITTLE_ENDIAN_ORDER, etc */
 4819
 4820    switch (keySz) {
 4821#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
 4822        defined(WOLFSSL_AES_128)
 4823    case 16:
 4824    #ifdef WOLFSSL_CHECK_MEM_ZERO
 4825        temp = (word32)-1;
 4826        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
 4827    #endif
 4828        while (1)
 4829        {
 4830            temp  = rk[3];
 4831            rk[4] = rk[0] ^
 4832        #ifndef WOLFSSL_AES_SMALL_TABLES
 4833                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
 4834                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
 4835                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
 4836                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
 4837        #else
 4838                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
 4839                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
 4840                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
 4841                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
 4842        #endif
 4843                rcon[i];
 4844            rk[5] = rk[1] ^ rk[4];
 4845            rk[6] = rk[2] ^ rk[5];
 4846            rk[7] = rk[3] ^ rk[6];
 4847            if (++i == 10)
 4848                break;
 4849            rk += 4;
 4850        }
 4851        break;
 4852#endif /* 128 */
 4853
 4854#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
 4855        defined(WOLFSSL_AES_192)
 4856    case 24:
 4857    #ifdef WOLFSSL_CHECK_MEM_ZERO
 4858        temp = (word32)-1;
 4859        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
 4860    #endif
 4861        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
 4862        while (1)
 4863        {
 4864            temp = rk[ 5];
 4865            rk[ 6] = rk[ 0] ^
 4866        #ifndef WOLFSSL_AES_SMALL_TABLES
 4867                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
 4868                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
 4869                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
 4870                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
 4871        #else
 4872                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
 4873                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
 4874                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
 4875                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
 4876        #endif
 4877                rcon[i];
 4878            rk[ 7] = rk[ 1] ^ rk[ 6];
 4879            rk[ 8] = rk[ 2] ^ rk[ 7];
 4880            rk[ 9] = rk[ 3] ^ rk[ 8];
 4881            if (++i == 8)
 4882                break;
 4883            rk[10] = rk[ 4] ^ rk[ 9];
 4884            rk[11] = rk[ 5] ^ rk[10];
 4885            rk += 6;
 4886        }
 4887        break;
 4888#endif /* 192 */
 4889
 4890#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
 4891        defined(WOLFSSL_AES_256)
 4892    case 32:
 4893    #ifdef WOLFSSL_CHECK_MEM_ZERO
 4894        temp = (word32)-1;
 4895        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
 4896    #endif
 4897        while (1)
 4898        {
 4899            temp = rk[ 7];
 4900            rk[ 8] = rk[ 0] ^
 4901        #ifndef WOLFSSL_AES_SMALL_TABLES
 4902                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
 4903                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
 4904                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
 4905                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
 4906        #else
 4907                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
 4908                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
 4909                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
 4910                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
 4911        #endif
 4912                rcon[i];
 4913            rk[ 9] = rk[ 1] ^ rk[ 8];
 4914            rk[10] = rk[ 2] ^ rk[ 9];
 4915            rk[11] = rk[ 3] ^ rk[10];
 4916            if (++i == 7)
 4917                break;
 4918            temp = rk[11];
 4919            rk[12] = rk[ 4] ^
 4920        #ifndef WOLFSSL_AES_SMALL_TABLES
 4921                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
 4922                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
 4923                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
 4924                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
 4925        #else
 4926                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
 4927                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
 4928                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
 4929                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
 4930        #endif
 4931            rk[13] = rk[ 5] ^ rk[12];
 4932            rk[14] = rk[ 6] ^ rk[13];
 4933            rk[15] = rk[ 7] ^ rk[14];
 4934
 4935            rk += 8;
 4936        }
 4937        break;
 4938#endif /* 256 */
 4939    } /* switch */
 4940    ForceZero(&temp, sizeof(temp));
 4941
 4942#if defined(HAVE_AES_DECRYPT) && !defined(MAX3266X_AES)
 4943    if (dir == AES_DECRYPTION) {
 4944        unsigned int j;
 4945
 4946#ifdef WC_C_DYNAMIC_FALLBACK
 4947        rk = aes->key_C_fallback;
 4948#else
 4949        rk = aes->key;
 4950#endif
 4951
 4952        /* invert the order of the round keys: */
 4953        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
 4954            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
 4955            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
 4956            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
 4957            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
 4958        }
 4959        ForceZero(&temp, sizeof(temp));
 4960    #if !defined(WOLFSSL_AES_SMALL_TABLES)
 4961        /* apply the inverse MixColumn transform to all round keys but the
 4962           first and the last: */
 4963        for (i = 1; i < aes->rounds; i++) {
 4964            rk += 4;
 4965            rk[0] =
 4966                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
 4967                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
 4968                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
 4969                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
 4970            rk[1] =
 4971                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
 4972                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
 4973                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
 4974                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
 4975            rk[2] =
 4976                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
 4977                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
 4978                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
 4979                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
 4980            rk[3] =
 4981                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
 4982                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
 4983                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
 4984                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
 4985        }
 4986    #endif
 4987    }
 4988#else
 4989    (void)dir;
 4990#endif /* HAVE_AES_DECRYPT */
 4991
 4992#ifdef WOLFSSL_CHECK_MEM_ZERO
 4993    wc_MemZero_Check(&temp, sizeof(temp));
 4994#else
 4995    (void)temp;
 4996#endif
 4997}
 4998#endif
 4999#else /* WC_AES_BITSLICED */
 5000/* Set the AES key and expand.
 5001 *
 5002 * @param [in]  aes    AES object.
 5003 * @param [in]  key    Block to encrypt.
 5004 * @param [in]  keySz  Number of bytes in key.
 5005 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
 5006 */
 5007static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
 5008{
 5009    /* No need to invert when decrypting. */
 5010    (void)dir;
 5011
 5012    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
 5013}
 5014#endif /* WC_AES_BITSLICED */
 5015
 5016#endif /* NEED_AES_TABLES */
 5017
 5018#ifndef WOLFSSL_RISCV_ASM
 5019    /* Software AES - SetKey */
 5020    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
 5021        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
 5022        int checkKeyLen)
 5023    {
 5024        int ret;
 5025#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
 5026        int cbRet;
 5027#endif
 5028    #ifdef WOLFSSL_IMX6_CAAM_BLOB
 5029        byte   local[32];
 5030        word32 localSz = 32;
 5031    #endif
 5032
 5033        if (aes == NULL)
 5034            return BAD_FUNC_ARG;
 5035#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 5036        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 5037        if (ret < 0)
 5038            return ret;
 5039#endif
 5040
 5041        switch (keylen) {
 5042    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
 5043        defined(WOLFSSL_AES_128)
 5044        case 16:
 5045    #endif
 5046    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
 5047        defined(WOLFSSL_AES_192)
 5048        case 24:
 5049    #endif
 5050    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
 5051        defined(WOLFSSL_AES_256)
 5052        case 32:
 5053    #endif
 5054            break;
 5055        default:
 5056            return BAD_FUNC_ARG;
 5057        }
 5058
 5059    #ifdef WOLF_CRYPTO_CB
 5060        #ifndef WOLF_CRYPTO_CB_FIND
 5061        if (aes->devId != INVALID_DEVID)
 5062        #endif
 5063        {
 5064        #ifdef WOLF_CRYPTO_CB_AES_SETKEY
 5065            ret = wc_CryptoCb_AesSetKey(aes, userKey, keylen);
 5066            if (ret == 0) {
 5067                /* Callback succeeded - SE owns the key */
 5068                aes->keylen = (int)keylen;
 5069                if (iv != NULL)
 5070                    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
 5071                else
 5072                    XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
 5073                return 0;
 5074            }
 5075            else if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
 5076                aes->devCtx = NULL;
 5077                return ret;
 5078            }
 5079            /* CRYPTOCB_UNAVAILABLE: continue to software setup */
 5080        #endif
 5081        #ifdef WOLF_CRYPTO_CB_SETKEY
 5082            cbRet = wc_CryptoCb_SetKey(aes->devId,
 5083                WC_SETKEY_AES, aes, (void*)userKey, keylen,
 5084                (void*)iv,
 5085                (iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
 5086            if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 5087                return cbRet;
 5088            /* CRYPTOCB_UNAVAILABLE: fall through to software setup */
 5089        #endif /* WOLF_CRYPTO_CB_SETKEY */
 5090            /* Standard CryptoCB path - copy key to devKey */
 5091            if (keylen > sizeof(aes->devKey)) {
 5092                return BAD_FUNC_ARG;
 5093            }
 5094            XMEMCPY(aes->devKey, userKey, keylen);
 5095        }
 5096    #endif
 5097
 5098    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
 5099        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
 5100            return WC_HW_E;
 5101        }
 5102    #endif
 5103
 5104    #ifdef WOLFSSL_IMX6_CAAM_BLOB
 5105        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
 5106            keylen == (24 + WC_CAAM_BLOB_SZ) ||
 5107            keylen == (32 + WC_CAAM_BLOB_SZ)) {
 5108            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
 5109                return BAD_FUNC_ARG;
 5110            }
 5111
 5112            /* set local values */
 5113            userKey = local;
 5114            keylen = localSz;
 5115        }
 5116    #endif
 5117
 5118    #ifdef WOLFSSL_SECO_CAAM
 5119        /* if set to use hardware than import the key */
 5120        if (aes->devId == WOLFSSL_SECO_DEVID) {
 5121            int keyGroup = 1; /* group one was chosen arbitrarily */
 5122            unsigned int keyIdOut;
 5123            byte importiv[GCM_NONCE_MID_SZ];
 5124            int importivSz = GCM_NONCE_MID_SZ;
 5125            int keyType = 0;
 5126            WC_RNG rng;
 5127
 5128            if (wc_InitRng(&rng) != 0) {
 5129                WOLFSSL_MSG("RNG init for IV failed");
 5130                return WC_HW_E;
 5131            }
 5132
 5133            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
 5134                WOLFSSL_MSG("Generate IV failed");
 5135                wc_FreeRng(&rng);
 5136                return WC_HW_E;
 5137            }
 5138            wc_FreeRng(&rng);
 5139
 5140            if (iv)
 5141                XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
 5142            else
 5143                XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE);
 5144
 5145            switch (keylen) {
 5146                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
 5147                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
 5148                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
 5149            }
 5150
 5151            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
 5152                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
 5153            if (keyIdOut == 0) {
 5154                return WC_HW_E;
 5155            }
 5156            aes->blackKey = keyIdOut;
 5157            return 0;
 5158        }
 5159    #endif
 5160
 5161    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
 5162        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
 5163        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)) || \
 5164        defined(WOLFSSL_NXP_HASHCRYPT_AES)
 5165        #ifdef WOLF_CRYPTO_CB
 5166        #ifndef WOLF_CRYPTO_CB_FIND
 5167        if (aes->devId != INVALID_DEVID)
 5168        #endif
 5169        #endif
 5170        {
 5171            if (keylen > sizeof(aes->devKey)) {
 5172                return BAD_FUNC_ARG;
 5173            }
 5174            XMEMCPY(aes->devKey, userKey, keylen);
 5175        }
 5176    #endif
 5177
 5178    #ifdef WOLF_CRYPTO_CB_ONLY_AES
 5179        /* No software AES schedule under CB_ONLY: aes->key[] (round keys) are
 5180         * unused because the static wc_AesEncrypt/wc_AesDecrypt are cryptocb-
 5181         * ECB shims. aes->rounds is still populated because wc_AesGetKeySize()
 5182         * reads it as the source of truth for the configured key size. */
 5183        aes->keylen = (int)keylen;
 5184        aes->rounds = (keylen / 4) + 6;
 5185        #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 5186            defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 5187            defined(WOLFSSL_AES_CTS)
 5188        aes->left = 0;
 5189        #endif
 5190        (void)dir;
 5191        return wc_AesSetIV(aes, iv);
 5192    #endif
 5193
 5194    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
 5195        if (checkKeyLen) {
 5196            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
 5197             * all key sizes. Otherwise this condition is never true. */
 5198            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
 5199                return BAD_FUNC_ARG;
 5200            }
 5201        }
 5202    #else
 5203        (void) checkKeyLen;
 5204    #endif
 5205
 5206    #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 5207        defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 5208        defined(WOLFSSL_AES_CTS)
 5209        aes->left = 0;
 5210    #endif
 5211
 5212        aes->keylen = (int)keylen;
 5213        aes->rounds = (keylen/4) + 6;
 5214        ret = wc_AesSetIV(aes, iv);
 5215        if (ret != 0)
 5216            return ret;
 5217
 5218#ifdef WC_C_DYNAMIC_FALLBACK
 5219#ifdef NEED_AES_TABLES
 5220        AesSetKey_C(aes, userKey, keylen, dir);
 5221#endif /* NEED_AES_TABLES */
 5222#endif /* WC_C_DYNAMIC_FALLBACK */
 5223
 5224    #ifdef WOLFSSL_AESNI
 5225
 5226       /* The dynamics for determining whether AES-NI will be used are tricky.
 5227        *
 5228        * First, we check for CPU support and cache the result -- if AES-NI is
 5229        * missing, we always shortcut to the AesSetKey_C() path.
 5230        *
 5231        * Second, if the CPU supports AES-NI, we confirm on a per-call basis
 5232        * that it's safe to use in the caller context, using
 5233        * SAVE_VECTOR_REGISTERS2().  This is an always-true no-op in user-space
 5234        * builds, but has substantive logic behind it in kernel module builds.
 5235        *
 5236        * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on
 5237        * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with
 5238        * success but with AES-NI disabled (the earlier AesSetKey_C() allows
 5239        * future encrypt/decrypt calls to succeed), otherwise we fail.
 5240        *
 5241        * Upon successful return, aes->use_aesni will have a zero value if
 5242        * AES-NI is disabled, and a nonzero value if it's enabled.
 5243        *
 5244        * An additional, optional semantic is available via
 5245        * WC_FLAG_DONT_USE_VECTOR_OPS, and is used in some kernel module builds
 5246        * to let the caller inhibit AES-NI.  When this macro is defined,
 5247        * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of
 5248        * uninitialized data in aes->use_aesni.  That's why support for
 5249        * WC_FLAG_DONT_USE_VECTOR_OPS must remain optional -- wc_AesInit() was
 5250        * only added in release 3.11.0, so legacy applications inevitably call
 5251        * wc_AesSetKey() on uninitialized Aes contexts.  This must continue to
 5252        * function correctly with default build settings.
 5253        */
 5254
 5255        if (checkedAESNI == 0) {
 5256            haveAESNI  = Check_CPU_support_AES();
 5257            checkedAESNI = 1;
 5258        }
 5259        if (haveAESNI
 5260#if defined(WC_FLAG_DONT_USE_VECTOR_OPS) && !defined(WC_C_DYNAMIC_FALLBACK)
 5261            && (aes->use_aesni != WC_FLAG_DONT_USE_VECTOR_OPS)
 5262#endif
 5263            )
 5264        {
 5265#if defined(WC_FLAG_DONT_USE_VECTOR_OPS)
 5266            if (aes->use_aesni == WC_FLAG_DONT_USE_VECTOR_OPS) {
 5267                aes->use_aesni = 0;
 5268                return 0;
 5269            }
 5270#endif
 5271            aes->use_aesni = 0;
 5272            #ifdef WOLFSSL_KERNEL_MODE
 5273            /* runtime alignment check */
 5274            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
 5275                ret = BAD_ALIGN_E;
 5276            }
 5277            else
 5278            #endif /* WOLFSSL_KERNEL_MODE */
 5279            {
 5280                ret = SAVE_VECTOR_REGISTERS2();
 5281            }
 5282            if (ret == 0) {
 5283                if (dir == AES_ENCRYPTION)
 5284                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
 5285#ifdef HAVE_AES_DECRYPT
 5286                else
 5287                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
 5288#endif
 5289
 5290                RESTORE_VECTOR_REGISTERS();
 5291
 5292                if (ret == 0)
 5293                    aes->use_aesni = 1;
 5294                else {
 5295#ifdef WC_C_DYNAMIC_FALLBACK
 5296                    ret = 0;
 5297#endif
 5298                }
 5299                return ret;
 5300            } else {
 5301#ifdef WC_C_DYNAMIC_FALLBACK
 5302                return 0;
 5303#else
 5304                return ret;
 5305#endif
 5306            }
 5307        }
 5308        else {
 5309            aes->use_aesni = 0;
 5310#ifdef WC_C_DYNAMIC_FALLBACK
 5311            /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C()
 5312             * above.
 5313             */
 5314            return 0;
 5315#endif
 5316        }
 5317    #endif /* WOLFSSL_AESNI */
 5318
 5319#ifndef WC_C_DYNAMIC_FALLBACK
 5320
 5321#if defined(WOLFSSL_ARMASM)
 5322#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 5323    #ifndef __aarch64__
 5324        AES_set_key_AARCH32(userKey, keylen, (byte*)aes->key, dir);
 5325    #else
 5326        Check_CPU_support_HwCrypto(aes);
 5327        if (aes->use_aes_hw_crypto) {
 5328            AES_set_key_AARCH64(userKey, keylen, (byte*)aes->key, dir);
 5329        }
 5330        else
 5331    #endif /* __aarch64__ */
 5332#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
 5333    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
 5334        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
 5335        {
 5336            AES_set_encrypt_key_NEON(userKey, keylen * 8, (byte*)aes->key);
 5337        #ifdef HAVE_AES_DECRYPT
 5338            if (dir == AES_DECRYPTION) {
 5339                AES_invert_key_NEON((byte*)aes->key, aes->rounds);
 5340            }
 5341        #else
 5342            (void)dir;
 5343        #endif
 5344        }
 5345    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 5346        {
 5347            AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);
 5348        #ifdef HAVE_AES_DECRYPT
 5349            if (dir == AES_DECRYPTION) {
 5350                AES_invert_key((byte*)aes->key, aes->rounds);
 5351            }
 5352        #else
 5353            (void)dir;
 5354        #endif
 5355        }
 5356    #endif
 5357        return 0;
 5358#else
 5359
 5360    #ifdef WOLFSSL_KCAPI_AES
 5361        XMEMCPY(aes->devKey, userKey, keylen);
 5362        if (aes->init != 0) {
 5363            kcapi_cipher_destroy(aes->handle);
 5364            aes->handle = NULL;
 5365            aes->init = 0;
 5366        }
 5367        (void)dir;
 5368    #endif
 5369
 5370        if (keylen > sizeof(aes->key)) {
 5371            return BAD_FUNC_ARG;
 5372        }
 5373#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
 5374        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
 5375                                  ((psa_algorithm_t)0), dir);
 5376#endif
 5377
 5378#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
 5379        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
 5380         * instead of SE05x crypto by setting useSWCrypt */
 5381        if (aes->useSWCrypt == 0) {
 5382            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
 5383            if (ret == 0) {
 5384                ret = wc_AesSetIV(aes, iv);
 5385            }
 5386            return ret;
 5387        }
 5388#endif
 5389#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
 5390        if (keylen == TA_KEY_TYPE_AES128_SIZE) {
 5391            ret = wc_Microchip_aes_set_key(aes, userKey, keylen, iv, dir);
 5392            if (ret != 0) {
 5393                return ret;
 5394            }
 5395            ret = wc_AesSetIV(aes, iv);
 5396            if (ret != 0) {
 5397                return ret;
 5398            }
 5399        }
 5400#endif
 5401        XMEMCPY(aes->key, userKey, keylen);
 5402
 5403#ifndef WC_AES_BITSLICED
 5404    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
 5405        (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES)) \
 5406        && !defined(MAX3266X_AES)
 5407
 5408        /* software */
 5409        ByteReverseWords(aes->key, aes->key, keylen);
 5410
 5411    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
 5412        if (wc_esp32AesSupportedKeyLen(aes)) {
 5413            /* supported lengths don't get reversed */
 5414            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
 5415        }
 5416        else {
 5417            word32* rk = aes->key;
 5418
 5419            /* For example, the ESP32-S3 does not support HW for len = 24,
 5420             * so fall back to SW */
 5421        #ifdef DEBUG_WOLFSSL
 5422            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
 5423        #endif
 5424            XMEMCPY(rk, userKey, keylen);
 5425            /* When not ESP32 HW, we need to reverse endianness */
 5426            ByteReverseWords(rk, rk, keylen);
 5427        }
 5428    #endif
 5429
 5430    #ifdef WOLFSSL_IMXRT_DCP
 5431        {
 5432            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
 5433            word32 temp = 0;
 5434            if (keylen == 16)
 5435                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
 5436            if (temp != 0)
 5437                return WC_HW_E;
 5438        }
 5439    #endif
 5440#endif /* !WC_AES_BITSLICED */
 5441
 5442#ifdef NEED_AES_TABLES
 5443        AesSetKey_C(aes, userKey, keylen, dir);
 5444#endif /* NEED_AES_TABLES */
 5445
 5446#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
 5447        XMEMCPY((byte*)aes->key, userKey, keylen);
 5448        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
 5449            ByteReverseWords(aes->key, aes->key, 32);
 5450        }
 5451#endif
 5452
 5453    #if defined(WOLFSSL_DEVCRYPTO) && \
 5454        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
 5455        aes->ctx.cfd = -1;
 5456    #endif
 5457    #ifdef WOLFSSL_IMX6_CAAM_BLOB
 5458        ForceZero(local, sizeof(local));
 5459    #endif
 5460        return ret;
 5461#endif
 5462
 5463#endif /* !WC_C_DYNAMIC_FALLBACK */
 5464
 5465    } /* wc_AesSetKeyLocal */
 5466
 5467    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
 5468            const byte* iv, int dir)
 5469    {
 5470        if (aes == NULL) {
 5471            return BAD_FUNC_ARG;
 5472        }
 5473        if (keylen > sizeof(aes->key)) {
 5474            return BAD_FUNC_ARG;
 5475        }
 5476
 5477    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
 5478    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
 5479        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
 5480        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
 5481            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
 5482            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
 5483        }
 5484        else {
 5485        #if  defined(WOLFSSL_HW_METRICS)
 5486            /* It is interesting to know how many times we could not complete
 5487             * AES in hardware due to unsupported lengths. */
 5488            wc_esp32AesUnupportedLengthCountAdd();
 5489        #endif
 5490        #ifdef DEBUG_WOLFSSL
 5491            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
 5492                           keylen);
 5493        #endif
 5494        }
 5495    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
 5496
 5497        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
 5498
 5499    } /* wc_AesSetKey() */
 5500#endif
 5501
 5502    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
 5503        /* AES-CTR and AES-DIRECT need to use this for key setup */
 5504        /* This function allows key sizes that are not 128/192/256 bits */
 5505    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
 5506                           const byte* iv, int dir)
 5507    {
 5508        if (aes == NULL) {
 5509            return BAD_FUNC_ARG;
 5510        }
 5511        if (keylen > sizeof(aes->key)) {
 5512            return BAD_FUNC_ARG;
 5513        }
 5514
 5515        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
 5516    }
 5517    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
 5518#endif /* wc_AesSetKey block */
 5519
 5520
 5521/* wc_AesSetIV is shared between software and hardware */
 5522int wc_AesSetIV(Aes* aes, const byte* iv)
 5523{
 5524    if (aes == NULL)
 5525        return BAD_FUNC_ARG;
 5526
 5527#ifdef WC_DEBUG_CIPHER_LIFECYCLE
 5528    {
 5529        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
 5530        if (ret < 0)
 5531            return ret;
 5532    }
 5533#endif
 5534
 5535    if (iv)
 5536        XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
 5537    else
 5538        XMEMSET(aes->reg,  0, WC_AES_BLOCK_SIZE);
 5539
 5540#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
 5541    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \
 5542    defined(WOLFSSL_AES_CTS)
 5543    /* Clear any unused bytes from last cipher op. */
 5544    aes->left = 0;
 5545#endif
 5546
 5547    return 0;
 5548}
 5549
 5550#ifdef WOLFSSL_AESNI
 5551
 5552#ifdef WC_C_DYNAMIC_FALLBACK
 5553
 5554#define VECTOR_REGISTERS_PUSH {                                      \
 5555        int orig_use_aesni = aes->use_aesni;                         \
 5556        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
 5557            aes->use_aesni = 0;                                      \
 5558        }                                                            \
 5559        WC_DO_NOTHING
 5560
 5561#define VECTOR_REGISTERS_POP                                         \
 5562        if (aes->use_aesni)                                          \
 5563            RESTORE_VECTOR_REGISTERS();                              \
 5564        else                                                         \
 5565            aes->use_aesni = orig_use_aesni;                         \
 5566    }                                                                \
 5567    WC_DO_NOTHING
 5568
 5569#elif defined(SAVE_VECTOR_REGISTERS2_DOES_NOTHING)
 5570
 5571#define VECTOR_REGISTERS_PUSH { \
 5572        WC_DO_NOTHING
 5573
 5574#define VECTOR_REGISTERS_POP                                         \
 5575    }                                                                \
 5576    WC_DO_NOTHING
 5577
 5578#else
 5579
 5580#define VECTOR_REGISTERS_PUSH { \
 5581        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
 5582            return ret;                                                  \
 5583        }                                                                \
 5584        WC_DO_NOTHING
 5585
 5586#define VECTOR_REGISTERS_POP \
 5587        if (aes->use_aesni) {                                            \
 5588            RESTORE_VECTOR_REGISTERS();                                  \
 5589        }                                                                \
 5590    }                                                                    \
 5591    WC_DO_NOTHING
 5592
 5593#endif
 5594
 5595#else /* !WOLFSSL_AESNI */
 5596
 5597#define VECTOR_REGISTERS_PUSH WC_DO_NOTHING
 5598#define VECTOR_REGISTERS_POP WC_DO_NOTHING
 5599
 5600#endif /* !WOLFSSL_AESNI */
 5601
 5602
 5603/* AES-DIRECT */
 5604#if defined(WOLFSSL_AES_DIRECT)
 5605    #if defined(HAVE_COLDFIRE_SEC)
 5606        #error "Coldfire SEC doesn't yet support AES direct"
 5607
 5608    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
 5609        !defined(WOLFSSL_QNX_CAAM)
 5610        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
 5611
 5612    #elif defined(WOLFSSL_AFALG)
 5613        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
 5614
 5615    #elif defined(WOLFSSL_DEVCRYPTO_AES)
 5616        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
 5617
 5618    #else
 5619
 5620        /* Allow direct access to one block encrypt */
 5621        /* Note, the in and out args are swapped compared to wc_AesEncrypt(). */
 5622        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
 5623        {
 5624            int ret;
 5625
 5626            if (aes == NULL || out == NULL || in == NULL)
 5627                return BAD_FUNC_ARG;
 5628            VECTOR_REGISTERS_PUSH;
 5629            ret = wc_AesEncrypt(aes, in, out);
 5630            VECTOR_REGISTERS_POP;
 5631            return ret;
 5632        }
 5633
 5634        /* vector reg save/restore is explicit in all below calls to
 5635         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
 5636         * macro.
 5637         */
 5638        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
 5639
 5640        #ifdef HAVE_AES_DECRYPT
 5641        /* Allow direct access to one block decrypt */
 5642        /* Note, the in and out args are swapped compared to wc_AesDecrypt(). */
 5643        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
 5644        {
 5645            int ret;
 5646
 5647            if (aes == NULL)
 5648                return BAD_FUNC_ARG;
 5649            VECTOR_REGISTERS_PUSH;
 5650            ret = wc_AesDecrypt(aes, in, out);
 5651            VECTOR_REGISTERS_POP;
 5652            return ret;
 5653        }
 5654
 5655        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
 5656
 5657        #endif /* HAVE_AES_DECRYPT */
 5658    #endif /* AES direct block */
 5659#endif /* WOLFSSL_AES_DIRECT */
 5660
 5661
 5662/* AES-CBC */
 5663#ifdef HAVE_AES_CBC
 5664#if defined(STM32_CRYPTO)
 5665
 5666#ifdef WOLFSSL_STM32U5_DHUK
 5667    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 5668    {
 5669        int ret = 0;
 5670        CRYP_HandleTypeDef hcryp;
 5671        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 5672
 5673#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 5674        if (sz % WC_AES_BLOCK_SIZE) {
 5675            return BAD_LENGTH_E;
 5676        }
 5677#endif
 5678        if (blocks == 0)
 5679            return 0;
 5680
 5681        ret = wolfSSL_CryptHwMutexLock();
 5682        if (ret != 0) {
 5683            return ret;
 5684        }
 5685
 5686        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
 5687            CRYP_ConfigTypeDef Config;
 5688
 5689            XMEMSET(&Config, 0, sizeof(Config));
 5690            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen,
 5691                (const byte*)aes->dhukIV, aes->dhukIVLen);
 5692
 5693            /* reconfigure for using unwrapped key now */
 5694            HAL_CRYP_GetConfig(&hcryp, &Config);
 5695            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
 5696            Config.KeySelect = CRYP_KEYSEL_NORMAL;
 5697            Config.Algorithm = CRYP_AES_CBC;
 5698            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
 5699            Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
 5700            HAL_CRYP_SetConfig(&hcryp, &Config);
 5701        }
 5702        else {
 5703            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
 5704            if (ret != 0) {
 5705                wolfSSL_CryptHwMutexUnLock();
 5706                return ret;
 5707            }
 5708            hcryp.Init.Algorithm  = CRYP_AES_CBC;
 5709            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
 5710            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
 5711            ret = HAL_CRYP_Init(&hcryp);
 5712        }
 5713
 5714        if (ret == HAL_OK) {
 5715            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
 5716                (uint32_t*)out, STM32_HAL_TIMEOUT);
 5717            if (ret != HAL_OK) {
 5718                ret = WC_TIMEOUT_E;
 5719            }
 5720
 5721            /* store iv for next call */
 5722            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 5723        }
 5724
 5725        HAL_CRYP_DeInit(&hcryp);
 5726
 5727        wolfSSL_CryptHwMutexUnLock();
 5728        wc_Stm32_Aes_Cleanup();
 5729
 5730        return ret;
 5731    }
 5732    #ifdef HAVE_AES_DECRYPT
 5733    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 5734    {
 5735        int ret = 0;
 5736        CRYP_HandleTypeDef hcryp;
 5737        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 5738
 5739#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 5740        if (sz % WC_AES_BLOCK_SIZE) {
 5741            return BAD_LENGTH_E;
 5742        }
 5743#endif
 5744        if (blocks == 0)
 5745            return 0;
 5746
 5747        ret = wolfSSL_CryptHwMutexLock();
 5748        if (ret != 0) {
 5749            return ret;
 5750        }
 5751
 5752        if (aes->devId == WOLFSSL_STM32U5_DHUK_WRAPPED_DEVID) {
 5753            CRYP_ConfigTypeDef Config;
 5754
 5755            XMEMSET(&Config, 0, sizeof(Config));
 5756            ret = wc_Stm32_Aes_UnWrap(aes, &hcryp, (const byte*)aes->key, aes->keylen,
 5757                aes->dhukIV, aes->dhukIVLen);
 5758
 5759            /* reconfigure for using unwrapped key now */
 5760            HAL_CRYP_GetConfig(&hcryp, &Config);
 5761            Config.KeyMode   = CRYP_KEYMODE_NORMAL;
 5762            Config.KeySelect = CRYP_KEYSEL_NORMAL;
 5763            Config.Algorithm = CRYP_AES_CBC;
 5764            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
 5765            Config.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
 5766            HAL_CRYP_SetConfig(&hcryp, &Config);
 5767        }
 5768        else {
 5769            ret = wc_Stm32_Aes_Init(aes, &hcryp, 1);
 5770            if (ret != 0) {
 5771                wolfSSL_CryptHwMutexUnLock();
 5772                return ret;
 5773            }
 5774            hcryp.Init.Algorithm  = CRYP_AES_CBC;
 5775            ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
 5776            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
 5777            ret = HAL_CRYP_Init(&hcryp);
 5778        }
 5779
 5780        if (ret == HAL_OK) {
 5781            /* if input and output same will overwrite input iv */
 5782            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 5783            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
 5784                (uint32_t*)out, STM32_HAL_TIMEOUT);
 5785            if (ret != HAL_OK) {
 5786                ret = WC_TIMEOUT_E;
 5787            }
 5788
 5789            /* store iv for next call */
 5790            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
 5791        }
 5792
 5793        HAL_CRYP_DeInit(&hcryp);
 5794        wolfSSL_CryptHwMutexUnLock();
 5795        wc_Stm32_Aes_Cleanup();
 5796
 5797        return ret;
 5798    }
 5799    #endif /* HAVE_AES_DECRYPT */
 5800
 5801#elif defined(WOLFSSL_STM32_CUBEMX)
 5802    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 5803    {
 5804        int ret = 0;
 5805        CRYP_HandleTypeDef hcryp;
 5806        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 5807
 5808#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 5809        if (sz % WC_AES_BLOCK_SIZE) {
 5810            return BAD_LENGTH_E;
 5811        }
 5812#endif
 5813        if (blocks == 0)
 5814            return 0;
 5815
 5816        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
 5817        if (ret != 0)
 5818            return ret;
 5819
 5820        ret = wolfSSL_CryptHwMutexLock();
 5821        if (ret != 0) {
 5822            return ret;
 5823        }
 5824
 5825    #if defined(STM32_HAL_V2)
 5826        hcryp.Init.Algorithm  = CRYP_AES_CBC;
 5827        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
 5828    #elif defined(STM32_CRYPTO_AES_ONLY)
 5829        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
 5830        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
 5831        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
 5832    #endif
 5833        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
 5834        ret = HAL_CRYP_Init(&hcryp);
 5835
 5836        if (ret == HAL_OK) {
 5837        #if defined(STM32_HAL_V2)
 5838            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
 5839                (uint32_t*)out, STM32_HAL_TIMEOUT);
 5840        #elif defined(STM32_CRYPTO_AES_ONLY)
 5841            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
 5842                out, STM32_HAL_TIMEOUT);
 5843        #else
 5844            ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
 5845                                        blocks * WC_AES_BLOCK_SIZE,
 5846                                        out, STM32_HAL_TIMEOUT);
 5847        #endif
 5848        }
 5849        if (ret != HAL_OK) {
 5850            ret = WC_TIMEOUT_E;
 5851        }
 5852
 5853        /* store iv for next call */
 5854        XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 5855
 5856        HAL_CRYP_DeInit(&hcryp);
 5857
 5858        wolfSSL_CryptHwMutexUnLock();
 5859        wc_Stm32_Aes_Cleanup();
 5860
 5861        return ret;
 5862    }
 5863    #ifdef HAVE_AES_DECRYPT
 5864    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 5865    {
 5866        int ret = 0;
 5867        CRYP_HandleTypeDef hcryp;
 5868        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 5869
 5870#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 5871        if (sz % WC_AES_BLOCK_SIZE) {
 5872            return BAD_LENGTH_E;
 5873        }
 5874#endif
 5875        if (blocks == 0)
 5876            return 0;
 5877
 5878        ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
 5879        if (ret != 0)
 5880            return ret;
 5881
 5882        ret = wolfSSL_CryptHwMutexLock();
 5883        if (ret != 0) {
 5884            return ret;
 5885        }
 5886
 5887        /* if input and output same will overwrite input iv */
 5888        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 5889
 5890    #if defined(STM32_HAL_V2)
 5891        hcryp.Init.Algorithm  = CRYP_AES_CBC;
 5892        ByteReverseWords(aes->reg, aes->reg, WC_AES_BLOCK_SIZE);
 5893    #elif defined(STM32_CRYPTO_AES_ONLY)
 5894        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
 5895        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
 5896        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
 5897    #endif
 5898
 5899        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
 5900        ret = HAL_CRYP_Init(&hcryp);
 5901
 5902        if (ret == HAL_OK) {
 5903        #if defined(STM32_HAL_V2)
 5904            ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * WC_AES_BLOCK_SIZE,
 5905                (uint32_t*)out, STM32_HAL_TIMEOUT);
 5906        #elif defined(STM32_CRYPTO_AES_ONLY)
 5907            ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * WC_AES_BLOCK_SIZE,
 5908                out, STM32_HAL_TIMEOUT);
 5909        #else
 5910            ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
 5911                                        blocks * WC_AES_BLOCK_SIZE,
 5912                out, STM32_HAL_TIMEOUT);
 5913        #endif
 5914        }
 5915        if (ret != HAL_OK) {
 5916            ret = WC_TIMEOUT_E;
 5917        }
 5918
 5919        /* store iv for next call */
 5920        XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
 5921
 5922        HAL_CRYP_DeInit(&hcryp);
 5923        wolfSSL_CryptHwMutexUnLock();
 5924        wc_Stm32_Aes_Cleanup();
 5925
 5926        return ret;
 5927    }
 5928    #endif /* HAVE_AES_DECRYPT */
 5929
 5930#else /* Standard Peripheral Library */
 5931    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 5932    {
 5933        int ret;
 5934        word32 *iv;
 5935        CRYP_InitTypeDef cryptInit;
 5936        CRYP_KeyInitTypeDef keyInit;
 5937        CRYP_IVInitTypeDef ivInit;
 5938        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 5939
 5940#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 5941        if (sz % WC_AES_BLOCK_SIZE) {
 5942            return BAD_LENGTH_E;
 5943        }
 5944#endif
 5945        if (blocks == 0)
 5946            return 0;
 5947
 5948        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
 5949        if (ret != 0)
 5950            return ret;
 5951
 5952        ret = wolfSSL_CryptHwMutexLock();
 5953        if (ret != 0) {
 5954            return ret;
 5955        }
 5956
 5957        /* reset registers to their default values */
 5958        CRYP_DeInit();
 5959
 5960        /* set key */
 5961        CRYP_KeyInit(&keyInit);
 5962
 5963        /* set iv */
 5964        iv = aes->reg;
 5965        CRYP_IVStructInit(&ivInit);
 5966        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
 5967        ivInit.CRYP_IV0Left  = iv[0];
 5968        ivInit.CRYP_IV0Right = iv[1];
 5969        ivInit.CRYP_IV1Left  = iv[2];
 5970        ivInit.CRYP_IV1Right = iv[3];
 5971        CRYP_IVInit(&ivInit);
 5972
 5973        /* set direction and mode */
 5974        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
 5975        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
 5976        CRYP_Init(&cryptInit);
 5977
 5978        /* enable crypto processor */
 5979        CRYP_Cmd(ENABLE);
 5980
 5981        while (blocks--) {
 5982            /* flush IN/OUT FIFOs */
 5983            CRYP_FIFOFlush();
 5984
 5985            CRYP_DataIn(*(uint32_t*)&in[0]);
 5986            CRYP_DataIn(*(uint32_t*)&in[4]);
 5987            CRYP_DataIn(*(uint32_t*)&in[8]);
 5988            CRYP_DataIn(*(uint32_t*)&in[12]);
 5989
 5990            /* wait until the complete message has been processed */
 5991            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
 5992
 5993            *(uint32_t*)&out[0]  = CRYP_DataOut();
 5994            *(uint32_t*)&out[4]  = CRYP_DataOut();
 5995            *(uint32_t*)&out[8]  = CRYP_DataOut();
 5996            *(uint32_t*)&out[12] = CRYP_DataOut();
 5997
 5998            /* store iv for next call */
 5999            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6000
 6001            sz  -= WC_AES_BLOCK_SIZE;
 6002            in  += WC_AES_BLOCK_SIZE;
 6003            out += WC_AES_BLOCK_SIZE;
 6004        }
 6005
 6006        /* disable crypto processor */
 6007        CRYP_Cmd(DISABLE);
 6008        wolfSSL_CryptHwMutexUnLock();
 6009        wc_Stm32_Aes_Cleanup();
 6010
 6011        return ret;
 6012    }
 6013
 6014    #ifdef HAVE_AES_DECRYPT
 6015    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6016    {
 6017        int ret;
 6018        word32 *iv;
 6019        CRYP_InitTypeDef cryptInit;
 6020        CRYP_KeyInitTypeDef keyInit;
 6021        CRYP_IVInitTypeDef ivInit;
 6022        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 6023
 6024#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6025        if (sz % WC_AES_BLOCK_SIZE) {
 6026            return BAD_LENGTH_E;
 6027        }
 6028#endif
 6029        if (blocks == 0)
 6030            return 0;
 6031
 6032        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
 6033        if (ret != 0)
 6034            return ret;
 6035
 6036        ret = wolfSSL_CryptHwMutexLock();
 6037        if (ret != 0) {
 6038            return ret;
 6039        }
 6040
 6041        /* if input and output same will overwrite input iv */
 6042        XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6043
 6044        /* reset registers to their default values */
 6045        CRYP_DeInit();
 6046
 6047        /* set direction and key */
 6048        CRYP_KeyInit(&keyInit);
 6049        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
 6050        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
 6051        CRYP_Init(&cryptInit);
 6052
 6053        /* enable crypto processor */
 6054        CRYP_Cmd(ENABLE);
 6055
 6056        /* wait until key has been prepared */
 6057        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
 6058
 6059        /* set direction and mode */
 6060        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
 6061        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
 6062        CRYP_Init(&cryptInit);
 6063
 6064        /* set iv */
 6065        iv = aes->reg;
 6066        CRYP_IVStructInit(&ivInit);
 6067        ByteReverseWords(iv, iv, WC_AES_BLOCK_SIZE);
 6068        ivInit.CRYP_IV0Left  = iv[0];
 6069        ivInit.CRYP_IV0Right = iv[1];
 6070        ivInit.CRYP_IV1Left  = iv[2];
 6071        ivInit.CRYP_IV1Right = iv[3];
 6072        CRYP_IVInit(&ivInit);
 6073
 6074        /* enable crypto processor */
 6075        CRYP_Cmd(ENABLE);
 6076
 6077        while (blocks--) {
 6078            /* flush IN/OUT FIFOs */
 6079            CRYP_FIFOFlush();
 6080
 6081            CRYP_DataIn(*(uint32_t*)&in[0]);
 6082            CRYP_DataIn(*(uint32_t*)&in[4]);
 6083            CRYP_DataIn(*(uint32_t*)&in[8]);
 6084            CRYP_DataIn(*(uint32_t*)&in[12]);
 6085
 6086            /* wait until the complete message has been processed */
 6087            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
 6088
 6089            *(uint32_t*)&out[0]  = CRYP_DataOut();
 6090            *(uint32_t*)&out[4]  = CRYP_DataOut();
 6091            *(uint32_t*)&out[8]  = CRYP_DataOut();
 6092            *(uint32_t*)&out[12] = CRYP_DataOut();
 6093
 6094            /* store iv for next call */
 6095            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
 6096
 6097            in  += WC_AES_BLOCK_SIZE;
 6098            out += WC_AES_BLOCK_SIZE;
 6099        }
 6100
 6101        /* disable crypto processor */
 6102        CRYP_Cmd(DISABLE);
 6103        wolfSSL_CryptHwMutexUnLock();
 6104        wc_Stm32_Aes_Cleanup();
 6105
 6106        return ret;
 6107    }
 6108    #endif /* HAVE_AES_DECRYPT */
 6109#endif /* WOLFSSL_STM32_CUBEMX */
 6110
 6111#elif defined(HAVE_COLDFIRE_SEC)
 6112    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
 6113        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
 6114    {
 6115        #ifdef DEBUG_WOLFSSL
 6116            int i; int stat1, stat2; int ret;
 6117        #endif
 6118
 6119        int size;
 6120        volatile int v;
 6121
 6122        if ((pi == NULL) || (po == NULL))
 6123            return BAD_FUNC_ARG;    /*wrong pointer*/
 6124
 6125#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6126        if (sz % WC_AES_BLOCK_SIZE) {
 6127            return BAD_LENGTH_E;
 6128        }
 6129#endif
 6130
 6131        wc_LockMutex(&Mutex_AesSEC);
 6132
 6133        /* Set descriptor for SEC */
 6134        secDesc->length1 = 0x0;
 6135        secDesc->pointer1 = NULL;
 6136
 6137        secDesc->length2 = WC_AES_BLOCK_SIZE;
 6138        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
 6139
 6140        switch(aes->rounds) {
 6141            case 10: secDesc->length3 = 16; break;
 6142            case 12: secDesc->length3 = 24; break;
 6143            case 14: secDesc->length3 = 32; break;
 6144        }
 6145        XMEMCPY(secKey, aes->key, secDesc->length3);
 6146
 6147        secDesc->pointer3 = (byte *)secKey;
 6148        secDesc->pointer4 = AESBuffIn;
 6149        secDesc->pointer5 = AESBuffOut;
 6150        secDesc->length6 = 0x0;
 6151        secDesc->pointer6 = NULL;
 6152        secDesc->length7 = 0x0;
 6153        secDesc->pointer7 = NULL;
 6154        secDesc->nextDescriptorPtr = NULL;
 6155
 6156#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6157        size = AES_BUFFER_SIZE;
 6158#endif
 6159        while (sz) {
 6160            secDesc->header = descHeader;
 6161            XMEMCPY(secReg, aes->reg, WC_AES_BLOCK_SIZE);
 6162#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6163            sz -= AES_BUFFER_SIZE;
 6164#else
 6165            if (sz < AES_BUFFER_SIZE) {
 6166                size = sz;
 6167                sz = 0;
 6168            } else {
 6169                size = AES_BUFFER_SIZE;
 6170                sz -= AES_BUFFER_SIZE;
 6171            }
 6172#endif
 6173
 6174            secDesc->length4 = size;
 6175            secDesc->length5 = size;
 6176
 6177            XMEMCPY(AESBuffIn, pi, size);
 6178            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
 6179                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-WC_AES_BLOCK_SIZE]),
 6180                        WC_AES_BLOCK_SIZE);
 6181            }
 6182
 6183            /* Point SEC to the location of the descriptor */
 6184            MCF_SEC_FR0 = (uint32)secDesc;
 6185            /* Initialize SEC and wait for encryption to complete */
 6186            MCF_SEC_CCCR0 = 0x0000001a;
 6187            /* poll SISR to determine when channel is complete */
 6188            v=0;
 6189
 6190            while ((secDesc->header>> 24) != 0xff) v++;
 6191
 6192            #ifdef DEBUG_WOLFSSL
 6193                ret = MCF_SEC_SISRH;
 6194                stat1 = MCF_SEC_AESSR;
 6195                stat2 = MCF_SEC_AESISR;
 6196                if (ret & 0xe0000000) {
 6197                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
 6198                              "AESISR=%08x\n", i, ret, stat1, stat2);
 6199                }
 6200            #endif
 6201
 6202            XMEMCPY(po, AESBuffOut, size);
 6203
 6204            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
 6205                XMEMCPY((void*)aes->reg, (void*)&(po[size-WC_AES_BLOCK_SIZE]),
 6206                        WC_AES_BLOCK_SIZE);
 6207            } else {
 6208                XMEMCPY((void*)aes->reg, (void*)aes->tmp, WC_AES_BLOCK_SIZE);
 6209            }
 6210
 6211            pi += size;
 6212            po += size;
 6213        }
 6214
 6215        wc_UnLockMutex(&Mutex_AesSEC);
 6216        return 0;
 6217    }
 6218
 6219    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
 6220    {
 6221        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
 6222    }
 6223
 6224    #ifdef HAVE_AES_DECRYPT
 6225    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
 6226    {
 6227        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
 6228    }
 6229    #endif /* HAVE_AES_DECRYPT */
 6230
 6231#elif defined(FREESCALE_LTC)
 6232    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6233    {
 6234        word32 keySize;
 6235        status_t status;
 6236        byte *iv, *enc_key;
 6237        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 6238
 6239#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6240        if (sz % WC_AES_BLOCK_SIZE) {
 6241            return BAD_LENGTH_E;
 6242        }
 6243#endif
 6244        if (blocks == 0)
 6245            return 0;
 6246
 6247        iv      = (byte*)aes->reg;
 6248        enc_key = (byte*)aes->key;
 6249
 6250        status = wc_AesGetKeySize(aes, &keySize);
 6251        if (status != 0) {
 6252            return status;
 6253        }
 6254
 6255        status = wolfSSL_CryptHwMutexLock();
 6256        if (status != 0)
 6257            return status;
 6258        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
 6259            iv, enc_key, keySize);
 6260        wolfSSL_CryptHwMutexUnLock();
 6261
 6262        /* store iv for next call */
 6263        if (status == kStatus_Success) {
 6264            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6265        }
 6266
 6267        return (status == kStatus_Success) ? 0 : -1;
 6268    }
 6269
 6270    #ifdef HAVE_AES_DECRYPT
 6271    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6272    {
 6273        word32 keySize;
 6274        status_t status;
 6275        byte* iv, *dec_key;
 6276        byte temp_block[WC_AES_BLOCK_SIZE];
 6277        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 6278
 6279#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6280        if (sz % WC_AES_BLOCK_SIZE) {
 6281            return BAD_LENGTH_E;
 6282        }
 6283#endif
 6284        if (blocks == 0)
 6285            return 0;
 6286
 6287        iv      = (byte*)aes->reg;
 6288        dec_key = (byte*)aes->key;
 6289
 6290        status = wc_AesGetKeySize(aes, &keySize);
 6291        if (status != 0) {
 6292            return status;
 6293        }
 6294
 6295        /* get IV for next call */
 6296        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6297
 6298        status = wolfSSL_CryptHwMutexLock();
 6299        if (status != 0)
 6300            return status;
 6301        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * WC_AES_BLOCK_SIZE,
 6302            iv, dec_key, keySize, kLTC_EncryptKey);
 6303        wolfSSL_CryptHwMutexUnLock();
 6304
 6305        /* store IV for next call */
 6306        if (status == kStatus_Success) {
 6307            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
 6308        }
 6309
 6310        return (status == kStatus_Success) ? 0 : -1;
 6311    }
 6312    #endif /* HAVE_AES_DECRYPT */
 6313
 6314#elif defined(FREESCALE_MMCAU) && !defined(WOLFSSL_ARMASM)
 6315    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6316    {
 6317        int offset = 0;
 6318        byte *iv;
 6319        byte temp_block[WC_AES_BLOCK_SIZE];
 6320        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 6321        int ret;
 6322
 6323#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6324        if (sz % WC_AES_BLOCK_SIZE) {
 6325            return BAD_LENGTH_E;
 6326        }
 6327#endif
 6328        if (blocks == 0)
 6329            return 0;
 6330
 6331        iv = (byte*)aes->reg;
 6332
 6333        while (blocks--) {
 6334            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
 6335
 6336            /* XOR block with IV for CBC */
 6337            xorbuf(temp_block, iv, WC_AES_BLOCK_SIZE);
 6338
 6339            ret = wc_AesEncrypt(aes, temp_block, out + offset);
 6340            if (ret != 0)
 6341                return ret;
 6342
 6343            offset += WC_AES_BLOCK_SIZE;
 6344
 6345            /* store IV for next block */
 6346            XMEMCPY(iv, out + offset - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6347        }
 6348
 6349        return 0;
 6350    }
 6351    #ifdef HAVE_AES_DECRYPT
 6352    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6353    {
 6354        int ret;
 6355        int offset = 0;
 6356        byte* iv;
 6357        byte temp_block[WC_AES_BLOCK_SIZE];
 6358        word32 blocks = (sz / WC_AES_BLOCK_SIZE);
 6359
 6360#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6361        if (sz % WC_AES_BLOCK_SIZE) {
 6362            return BAD_LENGTH_E;
 6363        }
 6364#endif
 6365        if (blocks == 0)
 6366            return 0;
 6367
 6368        iv = (byte*)aes->reg;
 6369
 6370        while (blocks--) {
 6371            XMEMCPY(temp_block, in + offset, WC_AES_BLOCK_SIZE);
 6372
 6373            ret = wc_AesDecrypt(aes, in + offset, out + offset);
 6374            if (ret != 0)
 6375                return ret;
 6376
 6377            /* XOR block with IV for CBC */
 6378            xorbuf(out + offset, iv, WC_AES_BLOCK_SIZE);
 6379
 6380            /* store IV for next block */
 6381            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
 6382
 6383            offset += WC_AES_BLOCK_SIZE;
 6384        }
 6385        return 0;
 6386    }
 6387    #endif /* HAVE_AES_DECRYPT */
 6388
 6389#elif defined(MAX3266X_AES)
 6390    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6391    {
 6392        word32 keySize;
 6393        int status;
 6394        byte *iv;
 6395
 6396        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
 6397            return BAD_FUNC_ARG;
 6398        }
 6399
 6400        /* Always enforce a length check */
 6401        if (sz % WC_AES_BLOCK_SIZE) {
 6402        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6403            return BAD_LENGTH_E;
 6404        #else
 6405            return BAD_FUNC_ARG;
 6406        #endif
 6407        }
 6408        if (sz == 0) {
 6409            return 0;
 6410        }
 6411
 6412        iv = (byte*)aes->reg;
 6413        status = wc_AesGetKeySize(aes, &keySize);
 6414        if (status != 0) {
 6415            return status;
 6416        }
 6417
 6418        status = wc_MXC_TPU_AesEncrypt(in, iv, (byte*)aes->key,
 6419                                        MXC_TPU_MODE_CBC, sz, out,
 6420                                        (unsigned int)keySize);
 6421        /* store iv for next call */
 6422        if (status == 0) {
 6423            XMEMCPY(iv, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6424        }
 6425        return (status == 0) ? 0 : -1;
 6426    }
 6427
 6428    #ifdef HAVE_AES_DECRYPT
 6429    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6430    {
 6431        word32 keySize;
 6432        int status;
 6433        byte *iv;
 6434        byte temp_block[WC_AES_BLOCK_SIZE];
 6435
 6436        if ((in == NULL) || (out == NULL) || (aes == NULL)) {
 6437            return BAD_FUNC_ARG;
 6438        }
 6439
 6440        /* Always enforce a length check */
 6441        if (sz % WC_AES_BLOCK_SIZE) {
 6442        #ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6443            return BAD_LENGTH_E;
 6444        #else
 6445            return BAD_FUNC_ARG;
 6446        #endif
 6447        }
 6448        if (sz == 0) {
 6449            return 0;
 6450        }
 6451
 6452        iv = (byte*)aes->reg;
 6453        status = wc_AesGetKeySize(aes, &keySize);
 6454        if (status != 0) {
 6455            return status;
 6456        }
 6457
 6458        /* get IV for next call */
 6459        XMEMCPY(temp_block, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6460        status = wc_MXC_TPU_AesDecrypt(in, iv, (byte*)aes->key,
 6461                                        MXC_TPU_MODE_CBC, sz, out,
 6462                                        keySize);
 6463
 6464        /* store iv for next call */
 6465        if (status == 0) {
 6466            XMEMCPY(iv, temp_block, WC_AES_BLOCK_SIZE);
 6467        }
 6468        return (status == 0) ? 0 : -1;
 6469    }
 6470    #endif /* HAVE_AES_DECRYPT */
 6471
 6472
 6473
 6474#elif defined(WOLFSSL_PIC32MZ_CRYPT)
 6475
 6476    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6477    {
 6478        int ret;
 6479
 6480        if (sz == 0)
 6481            return 0;
 6482
 6483        /* hardware fails on input that is not a multiple of AES block size */
 6484        if (sz % WC_AES_BLOCK_SIZE != 0) {
 6485#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6486            return BAD_LENGTH_E;
 6487#else
 6488            return BAD_FUNC_ARG;
 6489#endif
 6490        }
 6491
 6492        ret = wc_Pic32AesCrypt(
 6493            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
 6494            out, in, sz, PIC32_ENCRYPTION,
 6495            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
 6496
 6497        /* store iv for next call */
 6498        if (ret == 0) {
 6499            XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6500        }
 6501
 6502        return ret;
 6503    }
 6504    #ifdef HAVE_AES_DECRYPT
 6505    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6506    {
 6507        int ret;
 6508        byte scratch[WC_AES_BLOCK_SIZE];
 6509
 6510        if (sz == 0)
 6511            return 0;
 6512
 6513        /* hardware fails on input that is not a multiple of AES block size */
 6514        if (sz % WC_AES_BLOCK_SIZE != 0) {
 6515#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6516            return BAD_LENGTH_E;
 6517#else
 6518            return BAD_FUNC_ARG;
 6519#endif
 6520        }
 6521        XMEMCPY(scratch, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6522
 6523        ret = wc_Pic32AesCrypt(
 6524            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
 6525            out, in, sz, PIC32_DECRYPTION,
 6526            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
 6527
 6528        /* store iv for next call */
 6529        if (ret == 0) {
 6530            XMEMCPY((byte*)aes->reg, scratch, WC_AES_BLOCK_SIZE);
 6531        }
 6532
 6533        return ret;
 6534    }
 6535    #endif /* HAVE_AES_DECRYPT */
 6536#elif defined(WOLFSSL_ESP32_CRYPT) && \
 6537    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
 6538
 6539    /* We'll use SW for fall back:
 6540     *   unsupported key lengths
 6541     *   hardware busy */
 6542    #define NEED_SW_AESCBC
 6543    #define NEED_AESCBC_HW_FALLBACK
 6544
 6545#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
 6546    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6547    {
 6548        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
 6549    }
 6550    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6551    {
 6552        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
 6553    }
 6554#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
 6555        !defined(WOLFSSL_QNX_CAAM)
 6556      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
 6557
 6558#elif defined(WOLFSSL_AFALG)
 6559    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
 6560
 6561#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
 6562    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
 6563
 6564#elif defined(WOLFSSL_DEVCRYPTO_CBC)
 6565    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
 6566
 6567#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
 6568    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
 6569
 6570#elif defined(WOLFSSL_SILABS_SE_ACCEL)
 6571    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
 6572
 6573#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
 6574    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
 6575
 6576#elif defined(WOLFSSL_PSOC6_CRYPTO)
 6577
 6578    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6579    {
 6580        return wc_Psoc6_Aes_CbcEncrypt(aes, out, in, sz);
 6581    }
 6582
 6583    #if defined(HAVE_AES_DECRYPT)
 6584    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6585    {
 6586        return wc_Psoc6_Aes_CbcDecrypt(aes, out, in, sz);
 6587    }
 6588    #endif /* HAVE_AES_DECRYPT */
 6589
 6590#else
 6591    /* Reminder: Some HW implementations may also define this as needed.
 6592     * (e.g. for unsupported key length fallback)  */
 6593    #define NEED_SW_AESCBC
 6594#endif
 6595
 6596#ifdef NEED_SW_AESCBC
 6597    /* Software AES - CBC Encrypt */
 6598
 6599int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6600    {
 6601#if !defined(WOLFSSL_ARMASM)
 6602        word32 blocks;
 6603        int ret;
 6604#endif
 6605
 6606        if (aes == NULL || out == NULL || in == NULL) {
 6607            return BAD_FUNC_ARG;
 6608        }
 6609
 6610        if (sz == 0) {
 6611            return 0;
 6612        }
 6613
 6614#if !defined(WOLFSSL_ARMASM)
 6615        blocks = sz / WC_AES_BLOCK_SIZE;
 6616#endif
 6617#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6618        if (sz % WC_AES_BLOCK_SIZE) {
 6619            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
 6620            return BAD_LENGTH_E;
 6621        }
 6622#endif
 6623
 6624    #ifdef WOLFSSL_IMXRT_DCP
 6625        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
 6626        if (aes->keylen == 16)
 6627            return DCPAesCbcEncrypt(aes, out, in, sz);
 6628    #endif
 6629
 6630    #ifdef WOLF_CRYPTO_CB
 6631        #ifndef WOLF_CRYPTO_CB_FIND
 6632        if (aes->devId != INVALID_DEVID)
 6633        #endif
 6634        {
 6635            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
 6636            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 6637                return crypto_cb_ret;
 6638            /* fall-through when unavailable */
 6639        }
 6640    #endif
 6641    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
 6642        /* if async and byte count above threshold */
 6643        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
 6644                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
 6645        #if defined(HAVE_CAVIUM)
 6646            return NitroxAesCbcEncrypt(aes, out, in, sz);
 6647        #elif defined(HAVE_INTEL_QA)
 6648            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
 6649                (const byte*)aes->devKey, aes->keylen,
 6650                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
 6651        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
 6652            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
 6653                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
 6654                sw->aes.aes = aes;
 6655                sw->aes.out = out;
 6656                sw->aes.in = in;
 6657                sw->aes.sz = sz;
 6658                return WC_PENDING_E;
 6659            }
 6660        #endif
 6661        }
 6662    #endif /* WOLFSSL_ASYNC_CRYPT */
 6663
 6664#if defined(WOLFSSL_ARMASM)
 6665#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
 6666    #if !defined(__aarch64__)
 6667        AES_CBC_encrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
 6668            (int)aes->rounds);
 6669    #else
 6670        if (aes->use_aes_hw_crypto) {
 6671            AES_CBC_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
 6672                (byte*)aes->key, (int)aes->rounds);
 6673        }
 6674        else
 6675    #endif /* __aarch64__ */
 6676#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
 6677    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
 6678        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
 6679        {
 6680            AES_CBC_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
 6681                aes->rounds, (unsigned char*)aes->reg);
 6682        }
 6683    #elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 6684        {
 6685            AES_CBC_encrypt(in, out, sz, (const unsigned char*)aes->key,
 6686                aes->rounds, (unsigned char*)aes->reg);
 6687        }
 6688    #endif
 6689        return 0;
 6690#else
 6691    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
 6692        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
 6693        if (aes->useSWCrypt == 0) {
 6694            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
 6695                                   kAlgorithm_SSS_AES_CBC);
 6696        }
 6697        else
 6698    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
 6699        if (wc_esp32AesSupportedKeyLen(aes)) {
 6700            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
 6701            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
 6702        }
 6703        else {
 6704            /* For example, the ESP32-S3 does not support HW for len = 24,
 6705             * so fall back to SW */
 6706        #ifdef DEBUG_WOLFSSL
 6707            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
 6708                          "unsupported keylen = %d", aes->keylen);
 6709        #endif
 6710        }
 6711    #elif defined(WOLFSSL_AESNI)
 6712        VECTOR_REGISTERS_PUSH;
 6713        if (aes->use_aesni) {
 6714            #ifdef DEBUG_AESNI
 6715                printf("about to aes cbc encrypt\n");
 6716                printf("in  = %p\n", in);
 6717                printf("out = %p\n", out);
 6718                printf("aes->key = %p\n", aes->key);
 6719                printf("aes->reg = %p\n", aes->reg);
 6720                printf("aes->rounds = %d\n", aes->rounds);
 6721                printf("sz = %d\n", sz);
 6722            #endif
 6723
 6724            /* check alignment, decrypt doesn't need alignment */
 6725            if ((wc_ptr_t)in % AESNI_ALIGN) {
 6726            #ifndef NO_WOLFSSL_ALLOC_ALIGN
 6727                byte* tmp = (byte*)XMALLOC(sz + WC_AES_BLOCK_SIZE + AESNI_ALIGN,
 6728                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
 6729                byte* tmp_align;
 6730                if (tmp == NULL)
 6731                    ret = MEMORY_E;
 6732                else {
 6733                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
 6734                    XMEMCPY(tmp_align, in, sz);
 6735                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
 6736                                          (byte*)aes->key, (int)aes->rounds);
 6737                    /* store iv for next call */
 6738                    XMEMCPY(aes->reg, tmp_align + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6739
 6740                    XMEMCPY(out, tmp_align, sz);
 6741                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
 6742                    ret = 0;
 6743                }
 6744            #else
 6745                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
 6746                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
 6747                ret = BAD_ALIGN_E;
 6748            #endif
 6749            } else {
 6750                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
 6751                                      (int)aes->rounds);
 6752                /* store iv for next call */
 6753                XMEMCPY(aes->reg, out + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6754
 6755                ret = 0;
 6756            }
 6757        }
 6758        else
 6759    #endif
 6760        {
 6761#ifdef WC_AES_HAVE_PREFETCH_ARG
 6762            int did_prefetches = 0;
 6763#endif
 6764            ret = 0;
 6765            while (blocks--) {
 6766                xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
 6767                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
 6768                                                (byte*)aes->reg,
 6769                                                &did_prefetches);
 6770                if (ret != 0)
 6771                    break;
 6772                XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
 6773
 6774                out += WC_AES_BLOCK_SIZE;
 6775                in  += WC_AES_BLOCK_SIZE;
 6776            }
 6777        }
 6778
 6779    #ifdef WOLFSSL_AESNI
 6780        VECTOR_REGISTERS_POP;
 6781    #endif
 6782
 6783        return ret;
 6784#endif
 6785    } /* wc_AesCbcEncrypt */
 6786
 6787#ifdef HAVE_AES_DECRYPT
 6788    /* Software AES - CBC Decrypt */
 6789    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 6790    {
 6791#if !defined(WOLFSSL_ARMASM)
 6792        word32 blocks;
 6793        int ret;
 6794#endif
 6795
 6796        if (aes == NULL || out == NULL || in == NULL) {
 6797            return BAD_FUNC_ARG;
 6798        }
 6799
 6800        if (sz == 0) {
 6801            return 0;
 6802        }
 6803
 6804    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
 6805        if (wc_esp32AesSupportedKeyLen(aes)) {
 6806            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
 6807            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
 6808        }
 6809        else {
 6810            /* For example, the ESP32-S3 does not support HW for len = 24,
 6811             * so fall back to SW */
 6812        #ifdef DEBUG_WOLFSSL
 6813            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
 6814                          "unsupported keylen = %d", aes->keylen);
 6815        #endif
 6816        }
 6817    #endif
 6818
 6819#if !defined(WOLFSSL_ARMASM)
 6820        blocks = sz / WC_AES_BLOCK_SIZE;
 6821#endif
 6822        if (sz % WC_AES_BLOCK_SIZE) {
 6823#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
 6824            return BAD_LENGTH_E;
 6825#else
 6826            return BAD_FUNC_ARG;
 6827#endif
 6828        }
 6829
 6830    #ifdef WOLFSSL_IMXRT_DCP
 6831        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
 6832        if (aes->keylen == 16)
 6833            return DCPAesCbcDecrypt(aes, out, in, sz);
 6834    #endif
 6835
 6836    #ifdef WOLF_CRYPTO_CB
 6837        #ifndef WOLF_CRYPTO_CB_FIND
 6838        if (aes->devId != INVALID_DEVID)
 6839        #endif
 6840        {
 6841            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
 6842            if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 6843                return crypto_cb_ret;
 6844            /* fall-through when unavailable */
 6845        }
 6846    #endif
 6847    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
 6848        /* if async and byte count above threshold */
 6849        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
 6850                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
 6851        #if defined(HAVE_CAVIUM)
 6852            return NitroxAesCbcDecrypt(aes, out, in, sz);
 6853        #elif defined(HAVE_INTEL_QA)
 6854            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
 6855                (const byte*)aes->devKey, aes->keylen,
 6856                (byte*)aes->reg, WC_AES_BLOCK_SIZE);
 6857        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
 6858            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
 6859                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
 6860                sw->aes.aes = aes;
 6861                sw->aes.out = out;
 6862                sw->aes.in = in;
 6863                sw->aes.sz = sz;
 6864                return WC_PENDING_E;
 6865            }
 6866        #endif
 6867        }
 6868    #endif
 6869
 6870    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
 6871        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
 6872        if (aes->useSWCrypt == 0) {
 6873            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
 6874                                   kAlgorithm_SSS_AES_CBC);
 6875        }
 6876    #endif
 6877
 6878#if defined(WOLFSSL_ARMASM)
 6879#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
 6880    #if !defined(__aarch64__)
 6881        AES_CBC_decrypt_AARCH32(in, out, sz, (byte*)aes->reg, (byte*)aes->key,
 6882            (int)aes->rounds);
 6883    #else
 6884        if (aes->use_aes_hw_crypto) {
 6885            AES_CBC_decrypt_AARCH64(in, out, sz, (byte*)aes->reg,
 6886                (byte*)aes->key, (int)aes->rounds);
 6887        }
 6888        else
 6889    #endif /* !__aarch64__ */
 6890#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
 6891    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
 6892    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
 6893        if (sz >= 64)
 6894    #endif
 6895        {
 6896            AES_CBC_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
 6897                aes->rounds, (unsigned char*)aes->reg);
 6898        }
 6899    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
 6900        else
 6901    #endif
 6902    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
 6903    #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 6904    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
 6905        {
 6906            AES_CBC_decrypt(in, out, sz, (const unsigned char*)aes->key,
 6907                aes->rounds, (unsigned char*)aes->reg);
 6908        }
 6909    #endif
 6910    #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
 6911        return 0;
 6912#else
 6913        VECTOR_REGISTERS_PUSH;
 6914
 6915    #ifdef WOLFSSL_AESNI
 6916        if (aes->use_aesni) {
 6917            #ifdef DEBUG_AESNI
 6918                printf("about to aes cbc decrypt\n");
 6919                printf("in  = %p\n", in);
 6920                printf("out = %p\n", out);
 6921                printf("aes->key = %p\n", aes->key);
 6922                printf("aes->reg = %p\n", aes->reg);
 6923                printf("aes->rounds = %d\n", aes->rounds);
 6924                printf("sz = %d\n", sz);
 6925            #endif
 6926
 6927            /* if input and output same will overwrite input iv */
 6928            XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
 6929            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
 6930            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
 6931                            aes->rounds);
 6932            #elif defined(WOLFSSL_AESNI_BY6)
 6933            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
 6934                            aes->rounds);
 6935            #else /* WOLFSSL_AESNI_BYx */
 6936            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
 6937                            (int)aes->rounds);
 6938            #endif /* WOLFSSL_AESNI_BYx */
 6939            /* store iv for next call */
 6940            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
 6941            ret = 0;
 6942        }
 6943        else
 6944    #endif
 6945        {
 6946            ret = 0;
 6947#ifdef WC_AES_BITSLICED
 6948            if (in != out) {
 6949                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
 6950
 6951                while (blocks > BS_WORD_SIZE) {
 6952                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
 6953                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
 6954                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
 6955                              WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
 6956                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
 6957                            WC_AES_BLOCK_SIZE);
 6958                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
 6959                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
 6960                    blocks -= BS_WORD_SIZE;
 6961                }
 6962                if (blocks > 0) {
 6963                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
 6964                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
 6965                    xorbufout(out + WC_AES_BLOCK_SIZE, dec + WC_AES_BLOCK_SIZE, in,
 6966                              WC_AES_BLOCK_SIZE * (blocks - 1));
 6967                    XMEMCPY(aes->reg, in + (WC_AES_BLOCK_SIZE * (blocks - 1)),
 6968                            WC_AES_BLOCK_SIZE);
 6969                    blocks = 0;
 6970                }
 6971            }
 6972            else {
 6973                unsigned char dec[WC_AES_BLOCK_SIZE * BS_WORD_SIZE];
 6974                int i;
 6975
 6976                while (blocks > BS_WORD_SIZE) {
 6977                    AesDecryptBlocks_C(aes, in, dec, WC_AES_BLOCK_SIZE * BS_WORD_SIZE);
 6978                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * WC_AES_BLOCK_SIZE,
 6979                            WC_AES_BLOCK_SIZE);
 6980                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
 6981                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
 6982                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
 6983                                  WC_AES_BLOCK_SIZE);
 6984                    }
 6985                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
 6986                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
 6987
 6988                    in += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
 6989                    out += WC_AES_BLOCK_SIZE * BS_WORD_SIZE;
 6990                    blocks -= BS_WORD_SIZE;
 6991                }
 6992                if (blocks > 0) {
 6993                    AesDecryptBlocks_C(aes, in, dec, blocks * WC_AES_BLOCK_SIZE);
 6994                    XMEMCPY(aes->tmp, in + (blocks - 1) * WC_AES_BLOCK_SIZE,
 6995                            WC_AES_BLOCK_SIZE);
 6996                    for (i = blocks-1; i >= 1; i--) {
 6997                        xorbufout(out + i * WC_AES_BLOCK_SIZE,
 6998                                  dec + i * WC_AES_BLOCK_SIZE, in + (i - 1) * WC_AES_BLOCK_SIZE,
 6999                                  WC_AES_BLOCK_SIZE);
 7000                    }
 7001                    xorbufout(out, dec, aes->reg, WC_AES_BLOCK_SIZE);
 7002                    XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
 7003
 7004                    blocks = 0;
 7005                }
 7006            }
 7007#else
 7008#ifdef WC_AES_HAVE_PREFETCH_ARG
 7009            {
 7010            int did_prefetches = 0;
 7011#endif
 7012            while (blocks--) {
 7013                XMEMCPY(aes->tmp, in, WC_AES_BLOCK_SIZE);
 7014                ret = AesDecrypt_preFetchOpt(aes, in, out, &did_prefetches);
 7015                if (ret != 0)
 7016                    return ret;
 7017                xorbuf(out, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
 7018                /* store iv for next call */
 7019                XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
 7020
 7021                out += WC_AES_BLOCK_SIZE;
 7022                in  += WC_AES_BLOCK_SIZE;
 7023            }
 7024#ifdef WC_AES_HAVE_PREFETCH_ARG
 7025            }
 7026#endif
 7027#endif
 7028        }
 7029
 7030        VECTOR_REGISTERS_POP;
 7031
 7032        return ret;
 7033#endif
 7034    }
 7035#endif /* HAVE_AES_DECRYPT */
 7036
 7037#endif /* AES-CBC block */
 7038#endif /* HAVE_AES_CBC */
 7039
 7040/* AES-CTR */
 7041#if defined(WOLFSSL_AES_COUNTER)
 7042
 7043    #ifdef STM32_CRYPTO
 7044        #define NEED_AES_CTR_SOFT
 7045        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
 7046
 7047        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
 7048        {
 7049            int ret = 0;
 7050        #ifdef WOLFSSL_STM32_CUBEMX
 7051            CRYP_HandleTypeDef hcryp;
 7052            #ifdef STM32_HAL_V2
 7053            word32 iv[WC_AES_BLOCK_SIZE/sizeof(word32)];
 7054            #endif
 7055        #else
 7056            word32 *iv;
 7057            CRYP_InitTypeDef cryptInit;
 7058            CRYP_KeyInitTypeDef keyInit;
 7059            CRYP_IVInitTypeDef ivInit;
 7060        #endif
 7061
 7062        #ifdef WOLFSSL_STM32_CUBEMX
 7063            ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
 7064            if (ret != 0) {
 7065                return ret;
 7066            }
 7067
 7068            ret = wolfSSL_CryptHwMutexLock();
 7069            if (ret != 0) {
 7070                return ret;
 7071            }
 7072
 7073        #if defined(STM32_HAL_V2)
 7074            hcryp.Init.Algorithm  = CRYP_AES_CTR;
 7075            ByteReverseWords(iv, aes->reg, WC_AES_BLOCK_SIZE);
 7076            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
 7077        #elif defined(STM32_CRYPTO_AES_ONLY)
 7078            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
 7079            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
 7080            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
 7081            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
 7082        #else
 7083            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
 7084        #endif
 7085            HAL_CRYP_Init(&hcryp);
 7086
 7087        #if defined(STM32_HAL_V2)
 7088            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, WC_AES_BLOCK_SIZE,
 7089                (uint32_t*)out, STM32_HAL_TIMEOUT);
 7090        #elif defined(STM32_CRYPTO_AES_ONLY)
 7091            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
 7092                out, STM32_HAL_TIMEOUT);
 7093        #else
 7094            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, WC_AES_BLOCK_SIZE,
 7095                out, STM32_HAL_TIMEOUT);
 7096        #endif
 7097            if (ret != HAL_OK) {
 7098                ret = WC_TIMEOUT_E;
 7099            }
 7100            HAL_CRYP_DeInit(&hcryp);
 7101
 7102        #else /* Standard Peripheral Library */
 7103            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
 7104            if (ret != 0) {
 7105                return ret;
 7106            }
 7107
 7108            ret = wolfSSL_CryptHwMutexLock();
 7109            if (ret != 0) {
 7110                return ret;
 7111            }
 7112
 7113            /* reset registers to their default values */
 7114            CRYP_DeInit();
 7115
 7116            /* set key */
 7117            CRYP_KeyInit(&keyInit);
 7118
 7119            /* set iv */
 7120            iv = aes->reg;
 7121            CRYP_IVStructInit(&ivInit);
 7122            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
 7123            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
 7124            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
 7125            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
 7126            CRYP_IVInit(&ivInit);
 7127
 7128            /* set direction and mode */
 7129            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
 7130            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
 7131            CRYP_Init(&cryptInit);
 7132
 7133            /* enable crypto processor */
 7134            CRYP_Cmd(ENABLE);
 7135
 7136            /* flush IN/OUT FIFOs */
 7137            CRYP_FIFOFlush();
 7138
 7139            CRYP_DataIn(*(uint32_t*)&in[0]);
 7140            CRYP_DataIn(*(uint32_t*)&in[4]);
 7141            CRYP_DataIn(*(uint32_t*)&in[8]);
 7142            CRYP_DataIn(*(uint32_t*)&in[12]);
 7143
 7144            /* wait until the complete message has been processed */
 7145            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
 7146
 7147            *(uint32_t*)&out[0]  = CRYP_DataOut();
 7148            *(uint32_t*)&out[4]  = CRYP_DataOut();
 7149            *(uint32_t*)&out[8]  = CRYP_DataOut();
 7150            *(uint32_t*)&out[12] = CRYP_DataOut();
 7151
 7152            /* disable crypto processor */
 7153            CRYP_Cmd(DISABLE);
 7154        #endif /* WOLFSSL_STM32_CUBEMX */
 7155
 7156            wolfSSL_CryptHwMutexUnLock();
 7157            wc_Stm32_Aes_Cleanup();
 7158            return ret;
 7159        }
 7160
 7161
 7162    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
 7163
 7164        #define NEED_AES_CTR_SOFT
 7165        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
 7166
 7167        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
 7168        {
 7169            word32 tmpIv[WC_AES_BLOCK_SIZE / sizeof(word32)];
 7170            XMEMCPY(tmpIv, aes->reg, WC_AES_BLOCK_SIZE);
 7171            return wc_Pic32AesCrypt(
 7172                aes->key, aes->keylen, tmpIv, WC_AES_BLOCK_SIZE,
 7173                out, in, WC_AES_BLOCK_SIZE,
 7174                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
 7175        }
 7176
 7177    #elif defined(HAVE_COLDFIRE_SEC)
 7178        #error "Coldfire SEC doesn't currently support AES-CTR mode"
 7179
 7180    #elif defined(FREESCALE_LTC)
 7181        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 7182        {
 7183            int ret = 0;
 7184            word32 keySize;
 7185            byte *iv, *enc_key;
 7186            byte* tmp;
 7187
 7188            if (aes == NULL || out == NULL || in == NULL) {
 7189                return BAD_FUNC_ARG;
 7190            }
 7191
 7192            /* consume any unused bytes left in aes->tmp */
 7193            tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
 7194            while (aes->left && sz) {
 7195                *(out++) = *(in++) ^ *(tmp++);
 7196                aes->left--;
 7197                sz--;
 7198            }
 7199
 7200            if (sz) {
 7201                iv      = (byte*)aes->reg;
 7202                enc_key = (byte*)aes->key;
 7203
 7204                ret = wc_AesGetKeySize(aes, &keySize);
 7205                if (ret != 0)
 7206                    return ret;
 7207
 7208                ret = wolfSSL_CryptHwMutexLock();
 7209                if (ret != 0)
 7210                    return ret;
 7211                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
 7212                    iv, enc_key, keySize, (byte*)aes->tmp,
 7213                    (uint32_t*)&aes->left);
 7214                wolfSSL_CryptHwMutexUnLock();
 7215            }
 7216
 7217            return ret;
 7218        }
 7219
 7220    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
 7221        !defined(WOLFSSL_QNX_CAAM)
 7222        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
 7223
 7224    #elif defined(WOLFSSL_AFALG)
 7225        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
 7226
 7227    #elif defined(WOLFSSL_DEVCRYPTO_AES)
 7228        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
 7229
 7230    #elif defined(WOLFSSL_ESP32_CRYPT) && \
 7231        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
 7232        /* esp32 doesn't support CRT mode by hw.     */
 7233        /* use aes ecnryption plus sw implementation */
 7234        #define NEED_AES_CTR_SOFT
 7235
 7236    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
 7237        /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
 7238
 7239    #elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
 7240        /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
 7241
 7242    #else
 7243
 7244        /* Use software based AES counter */
 7245        #define NEED_AES_CTR_SOFT
 7246    #endif
 7247
 7248    #ifdef NEED_AES_CTR_SOFT
 7249        #ifndef WOLFSSL_ARMASM
 7250        /* Increment AES counter */
 7251        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
 7252        {
 7253            /* in network byte order so start at end and work back */
 7254            int i;
 7255            for (i = WC_AES_BLOCK_SIZE - 1; i >= 0; i--) {
 7256                if (++inOutCtr[i])  /* we're done unless we overflow */
 7257                    return;
 7258            }
 7259        }
 7260        #endif
 7261
 7262        /* Software AES - CTR Encrypt */
 7263        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
 7264        {
 7265    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
 7266          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
 7267            byte scratch[WC_AES_BLOCK_SIZE];
 7268    #endif
 7269    #if !defined(WOLFSSL_ARMASM)
 7270            int ret = 0;
 7271    #endif
 7272            word32 processed;
 7273#ifdef WC_AES_HAVE_PREFETCH_ARG
 7274            int did_prefetches = 0;
 7275#endif
 7276
 7277    #if !(!defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
 7278          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
 7279            XMEMSET(scratch, 0, sizeof(scratch));
 7280    #endif
 7281
 7282            if (aes == NULL || out == NULL || in == NULL) {
 7283                return BAD_FUNC_ARG;
 7284            }
 7285
 7286        #ifdef WOLF_CRYPTO_CB
 7287            #ifndef WOLF_CRYPTO_CB_FIND
 7288            if (aes->devId != INVALID_DEVID)
 7289            #endif
 7290            {
 7291                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
 7292                if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
 7293                    return crypto_cb_ret;
 7294                /* fall-through when unavailable */
 7295            }
 7296        #endif
 7297
 7298            /* consume any unused bytes left in aes->tmp */
 7299            processed = min(aes->left, sz);
 7300            xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
 7301                      processed);
 7302            out += processed;
 7303            in += processed;
 7304            aes->left -= processed;
 7305            sz -= processed;
 7306
 7307    #if defined(WOLFSSL_ARMASM)
 7308        #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
 7309            #ifndef __aarch64__
 7310            AES_CTR_encrypt_AARCH32(in, out, sz, (byte*)aes->reg,
 7311                (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
 7312            #else
 7313            if (aes->use_aes_hw_crypto) {
 7314                AES_CTR_encrypt_AARCH64(in, out, sz, (byte*)aes->reg,
 7315                    (byte*)aes->key, (byte*)aes->tmp, &aes->left, aes->rounds);
 7316                return 0;
 7317            }
 7318            else
 7319            #endif /* !__aarch64__ */
 7320        #endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
 7321        #if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 7322            {
 7323                word32 numBlocks;
 7324                byte* tmp = (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left;
 7325                /* consume any unused bytes left in aes->tmp */
 7326                while ((aes->left != 0) && (sz != 0)) {
 7327                   *(out++) = *(in++) ^ *(tmp++);
 7328                   aes->left--;
 7329                   sz--;
 7330                }
 7331
 7332                /* do as many block size ops as possible */
 7333                numBlocks = sz / WC_AES_BLOCK_SIZE;
 7334                if (numBlocks > 0) {
 7335                #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
 7336                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
 7337                    if (sz >= 32)
 7338                #endif
 7339                    {
 7340                        AES_CTR_encrypt_NEON(in, out,
 7341                            numBlocks * WC_AES_BLOCK_SIZE, (byte*)aes->key,
 7342                            aes->rounds, (byte*)aes->reg);
 7343                    }
 7344                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
 7345                    else
 7346                #endif
 7347                #endif
 7348                #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
 7349                    {
 7350                        AES_CTR_encrypt(in, out, numBlocks * WC_AES_BLOCK_SIZE,
 7351                            (byte*)aes->key, aes->rounds, (byte*)aes->reg);
 7352                    }
 7353                #endif
 7354
 7355                    sz  -= numBlocks * WC_AES_BLOCK_SIZE;
 7356                    out += numBlocks * WC_AES_BLOCK_SIZE;
 7357                    in  += numBlocks * WC_AES_BLOCK_SIZE;
 7358                }
 7359
 7360                /* handle non block size remaining */
 7361                if (sz) {
 7362                    byte zeros[WC_AES_BLOCK_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0,
 7363                                                      0, 0, 0, 0, 0, 0, 0, 0 };
 7364
 7365                #if defined(__aarch64__) && \
 7366                    !defined(WOLFSSL_ARMASM_NO_NEON) && \
 7367                    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
 7368                    {
 7369                        AES_CTR_encrypt_NEON(zeros, (byte*)aes->tmp,
 7370                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
 7371                            (byte*)aes->reg);
 7372                    }
 7373                #else
 7374                    {
 7375                        AES_CTR_encrypt(zeros, (byte*)aes->tmp,
 7376                            WC_AES_BLOCK_SIZE, (byte*)aes->key, aes->rounds,
 7377                            (byte*)aes->reg);
 7378                    }
 7379                #endif
 7380
 7381                    aes->left = WC_AES_BLOCK_SIZE;
 7382                    tmp = (byte*)aes->tmp;
 7383
 7384                    while (sz--) {
 7385                        *(out++) = *(in++) ^ *(tmp++);
 7386                        aes->left--;
 7387                    }
 7388                }
 7389            }
 7390        #endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
 7391            return 0;
 7392    #else
 7393            VECTOR_REGISTERS_PUSH;
 7394
 7395        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
 7396            !defined(XTRANSFORM_AESCTRBLOCK)
 7397            if (in != out && sz >= WC_AES_BLOCK_SIZE) {
 7398                word32 blocks = sz / WC_AES_BLOCK_SIZE;
 7399                byte* counter = (byte*)aes->reg;
 7400                byte* c = out;
 7401                while (blocks--) {
 7402                    XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
 7403                    c += WC_AES_BLOCK_SIZE;
 7404                    IncrementAesCounter(counter);
 7405                }
 7406
 7407                /* reset number of blocks and then do encryption */
 7408                blocks = sz / WC_AES_BLOCK_SIZE;
 7409                wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
 7410                xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
 7411                in += WC_AES_BLOCK_SIZE * blocks;
 7412                out += WC_AES_BLOCK_SIZE * blocks;
 7413                sz -= blocks * WC_AES_BLOCK_SIZE;
 7414            }
 7415            else
 7416        #endif
 7417            {
 7418            #ifdef WOLFSSL_CHECK_MEM_ZERO
 7419                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
 7420                    WC_AES_BLOCK_SIZE);
 7421            #endif
 7422                /* do as many block size ops as possible */
 7423                while (sz >= WC_AES_BLOCK_SIZE) {
 7424                #ifdef XTRANSFORM_AESCTRBLOCK
 7425                    XTRANSFORM_AESCTRBLOCK(aes, out, in);
 7426                #else
 7427                    ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
 7428                                                    scratch,
 7429                                                    &did_prefetches);
 7430                    if (ret != 0)
 7431                        break;
 7432                    xorbuf(scratch, in, WC_AES_BLOCK_SIZE);
 7433                    XMEMCPY(out, scratch, WC_AES_BLOCK_SIZE);
 7434                #endif
 7435                    IncrementAesCounter((byte*)aes->reg);
 7436
 7437                    out += WC_AES_BLOCK_SIZE;
 7438                    in  += WC_AES_BLOCK_SIZE;
 7439                    sz  -= WC_AES_BLOCK_SIZE;
 7440                    aes->left = 0;
 7441                }
 7442                ForceZero(scratch, WC_AES_BLOCK_SIZE);
 7443            }
 7444
 7445            /* handle non block size remaining and store unused byte count in left */
 7446            if ((ret == 0) && sz) {
 7447                ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg,
 7448                                                (byte*)aes->tmp,
 7449                                                &did_prefetches);
 7450                if (ret == 0) {
 7451                    IncrementAesCounter((byte*)aes->reg);
 7452                    aes->left = WC_AES_BLOCK_SIZE - sz;
 7453                    xorbufout(out, in, aes->tmp, sz);
 7454                }
 7455            }
 7456
 7457            if (ret < 0)
 7458                ForceZero(scratch, WC_AES_BLOCK_SIZE);
 7459
 7460        #ifdef WOLFSSL_CHECK_MEM_ZERO
 7461            wc_MemZero_Check(scratch, WC_AES_BLOCK_SIZE);
 7462        #endif
 7463
 7464            VECTOR_REGISTERS_POP;
 7465
 7466            return ret;
 7467    #endif
 7468        }
 7469
 7470        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
 7471                                        const byte* iv, int dir)
 7472        {
 7473            if (aes == NULL) {
 7474                return BAD_FUNC_ARG;
 7475            }
 7476            if (len > sizeof(aes->key)) {
 7477                return BAD_FUNC_ARG;
 7478            }
 7479
 7480            return wc_AesSetKey(aes, key, len, iv, dir);
 7481        }
 7482
 7483    #endif /* NEED_AES_CTR_SOFT */
 7484
 7485#endif /* WOLFSSL_AES_COUNTER */
 7486
 7487#ifndef WC_AES_HAVE_PREFETCH_ARG
 7488    #ifndef AesEncrypt_preFetchOpt
 7489        #define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
 7490            wc_AesEncrypt(aes, inBlock, outBlock)
 7491    #endif
 7492    #ifndef AesDecrypt_preFetchOpt
 7493        #define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
 7494            wc_AesDecrypt(aes, inBlock, outBlock)
 7495    #endif
 7496#endif
 7497
 7498#else  /* WOLFSSL_RISCV_ASM */
 7499
 7500#define AesEncrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
 7501    wc_AesEncryptDirect(aes, outBlock, inBlock)
 7502#define AesDecrypt_preFetchOpt(aes, inBlock, outBlock, do_preFetch) \
 7503    wc_AesDecryptDirect(aes, outBlock, inBlock)
 7504
 7505#endif /* WOLFSSL_RISCV_ASM */
 7506
 7507/*
 7508 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
 7509 * of two parts in order:
 7510 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
 7511 *      to the implicit IV.
 7512 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
 7513 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
 7514 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
 7515 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
 7516 * block counter during the encryption.
 7517 */
 7518
 7519#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
 7520static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
 7521{
 7522    int i;
 7523    for (i = (int)ctrSz - 1; i >= 0; i--) {
 7524        if (++ctr[i])
 7525            break;
 7526    }
 7527}
 7528#endif /* HAVE_AESGCM || HAVE_AESCCM */
 7529
 7530
 7531#ifdef HAVE_AESGCM
 7532
 7533#ifdef WOLFSSL_AESGCM_STREAM
 7534    /* Access initialization counter data. */
 7535    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * WC_AES_BLOCK_SIZE)
 7536    /* Access counter data. */
 7537    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * WC_AES_BLOCK_SIZE)
 7538    /* Access tag data. */
 7539    #define AES_TAG(aes)            ((aes)->streamData + 2 * WC_AES_BLOCK_SIZE)
 7540    /* Access last GHASH block. */
 7541    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE)
 7542    /* Access last encrypted block. */
 7543    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE)
 7544
 7545    #define GHASH_ONE_BLOCK     GHASH_ONE_BLOCK_SW
 7546#endif
 7547
 7548#if defined(HAVE_COLDFIRE_SEC)
 7549    #error "Coldfire SEC doesn't currently support AES-GCM mode"
 7550
 7551#endif
 7552
 7553#if defined(WOLFSSL_RISCV_ASM)
 7554    /* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */
 7555
 7556#elif defined(WOLFSSL_AFALG)
 7557    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
 7558
 7559#elif defined(WOLFSSL_KCAPI_AES)
 7560    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
 7561
 7562#elif defined(WOLFSSL_DEVCRYPTO_AES)
 7563    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
 7564
 7565#else /* software + AESNI implementation */
 7566
 7567#if !defined(FREESCALE_LTC_AES_GCM)
 7568#if (!(defined(__aarch64__) && defined(WOLFSSL_ARMASM))) || \
 7569    defined(WOLFSSL_AESGCM_STREAM)
 7570static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
 7571{
 7572    int i;
 7573
 7574    /* in network byte order so start at end and work back */
 7575    for (i = WC_AES_BLOCK_SIZE - 1; i >= WC_AES_BLOCK_SIZE - CTR_SZ; i--) {
 7576        if (++inOutCtr[i])  /* we're done unless we overflow */
 7577            return;
 7578    }
 7579}
 7580#endif
 7581#endif /* !FREESCALE_LTC_AES_GCM */
 7582
 7583#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
 7584    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 7585#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
 7586
 7587static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
 7588{
 7589    /* Multiply the sz by 8 */
 7590    word32 szHi = (sz >> (8*sizeof(sz) - 3));
 7591    sz <<= 3;
 7592
 7593    /* copy over the words of the sz into the destination buffer */
 7594    buf[0] = (byte)(szHi >> 24);
 7595    buf[1] = (byte)(szHi >> 16);
 7596    buf[2] = (byte)(szHi >>  8);
 7597    buf[3] = (byte)szHi;
 7598    buf[4] = (byte)(sz >> 24);
 7599    buf[5] = (byte)(sz >> 16);
 7600    buf[6] = (byte)(sz >>  8);
 7601    buf[7] = (byte)sz;
 7602}
 7603
 7604
 7605static WC_INLINE void RIGHTSHIFTX(byte* x)
 7606{
 7607    int i;
 7608    int carryIn = 0;
 7609    volatile byte borrow = (byte)((0x00U - (x[15] & 0x01U)) & 0xE1U);
 7610
 7611    for (i = 0; i < WC_AES_BLOCK_SIZE; i++) {
 7612        int carryOut = (x[i] & 0x01) << 7;
 7613        x[i] = (byte) ((x[i] >> 1) | carryIn);
 7614        carryIn = carryOut;
 7615    }
 7616    x[0] ^= borrow;
 7617}
 7618
 7619#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
 7620
 7621
 7622#ifdef GCM_TABLE
 7623
 7624void GenerateM0(Gcm* gcm)
 7625{
 7626    int i, j;
 7627    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
 7628
 7629    XMEMCPY(m[128], gcm->H, WC_AES_BLOCK_SIZE);
 7630
 7631    for (i = 64; i > 0; i /= 2) {
 7632        XMEMCPY(m[i], m[i*2], WC_AES_BLOCK_SIZE);
 7633        RIGHTSHIFTX(m[i]);
 7634    }
 7635
 7636    for (i = 2; i < 256; i *= 2) {
 7637        for (j = 1; j < i; j++) {
 7638            XMEMCPY(m[i+j], m[i], WC_AES_BLOCK_SIZE);
 7639            xorbuf(m[i+j], m[j], WC_AES_BLOCK_SIZE);
 7640        }
 7641    }
 7642
 7643    XMEMSET(m[0], 0, WC_AES_BLOCK_SIZE);
 7644}
 7645
 7646#elif defined(GCM_TABLE_4BIT)
 7647
 7648#if !defined(WC_16BIT_CPU)
 7649static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
 7650{
 7651    int i;
 7652    for (i = 15; i > 0; i--)
 7653        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
 7654    r8[0] = (byte)(z8[0] >> 4);
 7655}
 7656#endif
 7657
 7658void GenerateM0(Gcm* gcm)
 7659{
 7660#if !defined(WC_16BIT_CPU)
 7661    int i;
 7662#endif
 7663    byte (*m)[WC_AES_BLOCK_SIZE] = gcm->M0;
 7664
 7665    /* 0 times -> 0x0 */
 7666    XMEMSET(m[0x0], 0, WC_AES_BLOCK_SIZE);
 7667    /* 1 times -> 0x8 */
 7668    XMEMCPY(m[0x8], gcm->H, WC_AES_BLOCK_SIZE);
 7669    /* 2 times -> 0x4 */
 7670    XMEMCPY(m[0x4], m[0x8], WC_AES_BLOCK_SIZE);
 7671    RIGHTSHIFTX(m[0x4]);
 7672    /* 4 times -> 0x2 */
 7673    XMEMCPY(m[0x2], m[0x4], WC_AES_BLOCK_SIZE);
 7674    RIGHTSHIFTX(m[0x2]);
 7675    /* 8 times -> 0x1 */
 7676    XMEMCPY(m[0x1], m[0x2], WC_AES_BLOCK_SIZE);
 7677    RIGHTSHIFTX(m[0x1]);
 7678
 7679    /* 0x3 */
 7680    XMEMCPY(m[0x3], m[0x2], WC_AES_BLOCK_SIZE);
 7681    xorbuf (m[0x3], m[0x1], WC_AES_BLOCK_SIZE);
 7682
 7683    /* 0x5 -> 0x7 */
 7684    XMEMCPY(m[0x5], m[0x4], WC_AES_BLOCK_SIZE);
 7685    xorbuf (m[0x5], m[0x1], WC_AES_BLOCK_SIZE);
 7686    XMEMCPY(m[0x6], m[0x4], WC_AES_BLOCK_SIZE);
 7687    xorbuf (m[0x6], m[0x2], WC_AES_BLOCK_SIZE);
 7688    XMEMCPY(m[0x7], m[0x4], WC_AES_BLOCK_SIZE);
 7689    xorbuf (m[0x7], m[0x3], WC_AES_BLOCK_SIZE);
 7690
 7691    /* 0x9 -> 0xf */
 7692    XMEMCPY(m[0x9], m[0x8], WC_AES_BLOCK_SIZE);
 7693    xorbuf (m[0x9], m[0x1], WC_AES_BLOCK_SIZE);
 7694    XMEMCPY(m[0xa], m[0x8], WC_AES_BLOCK_SIZE);
 7695    xorbuf (m[0xa], m[0x2], WC_AES_BLOCK_SIZE);
 7696    XMEMCPY(m[0xb], m[0x8], WC_AES_BLOCK_SIZE);
 7697    xorbuf (m[0xb], m[0x3], WC_AES_BLOCK_SIZE);
 7698    XMEMCPY(m[0xc], m[0x8], WC_AES_BLOCK_SIZE);
 7699    xorbuf (m[0xc], m[0x4], WC_AES_BLOCK_SIZE);
 7700    XMEMCPY(m[0xd], m[0x8], WC_AES_BLOCK_SIZE);
 7701    xorbuf (m[0xd], m[0x5], WC_AES_BLOCK_SIZE);
 7702    XMEMCPY(m[0xe], m[0x8], WC_AES_BLOCK_SIZE);
 7703    xorbuf (m[0xe], m[0x6], WC_AES_BLOCK_SIZE);
 7704    XMEMCPY(m[0xf], m[0x8], WC_AES_BLOCK_SIZE);
 7705    xorbuf (m[0xf], m[0x7], WC_AES_BLOCK_SIZE);
 7706
 7707#if !defined(WC_16BIT_CPU)
 7708    for (i = 0; i < 16; i++) {
 7709        Shift4_M0(m[16+i], m[i]);
 7710    }
 7711#endif
 7712
 7713#if defined(WOLFSSL_ARMASM) && defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 7714    for (i = 0; i < 32; i++) {
 7715    #if !defined(__aarch64__)
 7716        word32* m32 = (word32*)gcm->M0[i];
 7717        m32[0] = ByteReverseWord32(m32[0]);
 7718        m32[1] = ByteReverseWord32(m32[1]);
 7719        m32[2] = ByteReverseWord32(m32[2]);
 7720        m32[3] = ByteReverseWord32(m32[3]);
 7721    #else
 7722        word64* m64 = (word64*)gcm->M0[i];
 7723        m64[0] = ByteReverseWord64(m64[0]);
 7724        m64[1] = ByteReverseWord64(m64[1]);
 7725    #endif
 7726    }
 7727#endif
 7728
 7729}
 7730
 7731#endif /* GCM_TABLE */
 7732#endif
 7733
 7734#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP)
 7735    #define HAVE_INTEL_AVX1
 7736    #define HAVE_INTEL_AVX2
 7737#endif
 7738
 7739#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \
 7740    defined(WC_C_DYNAMIC_FALLBACK)
 7741void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m)
 7742                           XASM_LINK("GCM_generate_m0_aesni");
 7743#ifdef HAVE_INTEL_AVX1
 7744void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m)
 7745                          XASM_LINK("GCM_generate_m0_avx1");
 7746#endif
 7747#ifdef HAVE_INTEL_AVX2
 7748void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m)
 7749                          XASM_LINK("GCM_generate_m0_avx2");
 7750#endif
 7751#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */
 7752
 7753/* Software AES - GCM SetKey */
 7754int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
 7755{
 7756    int  ret;
 7757    byte iv[WC_AES_BLOCK_SIZE];
 7758
 7759    #ifdef WOLFSSL_IMX6_CAAM_BLOB
 7760        byte   local[32];
 7761        word32 localSz = 32;
 7762
 7763        if (len == (16 + WC_CAAM_BLOB_SZ) ||
 7764          len == (24 + WC_CAAM_BLOB_SZ) ||
 7765          len == (32 + WC_CAAM_BLOB_SZ)) {
 7766            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
 7767                 return BAD_FUNC_ARG;
 7768            }
 7769
 7770            /* set local values */
 7771            key = local;
 7772            len = localSz;
 7773        }
 7774    #endif
 7775
 7776    if (!((len == 16) || (len == 24) || (len == 32)))
 7777        return BAD_FUNC_ARG;
 7778
 7779    if (aes == NULL || key == NULL) {
 7780#ifdef WOLFSSL_IMX6_CAAM_BLOB
 7781        ForceZero(local, sizeof(local));
 7782#endif
 7783        return BAD_FUNC_ARG;
 7784    }
 7785#ifdef OPENSSL_EXTRA
 7786    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
 7787    aes->gcm.aadLen = 0;
 7788#endif
 7789    XMEMSET(iv, 0, WC_AES_BLOCK_SIZE);
 7790    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
 7791#ifdef WOLF_CRYPTO_CB_ONLY_AES
 7792    /* do key scheduling so that ECB-only devices can still do GCM */
 7793    if (ret == 0) {
 7794        ret = wc_CryptoCb_AesEcbEncrypt(aes, aes->gcm.H, iv, WC_AES_BLOCK_SIZE);
 7795#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
 7796        if (ret == 0)
 7797            GenerateM0(&aes->gcm);
 7798#endif
 7799    }
 7800    return ret;
 7801#endif
 7802#ifdef WOLFSSL_AESGCM_STREAM
 7803    aes->gcmKeySet = 1;
 7804#endif
 7805    #if defined(WOLFSSL_SECO_CAAM)
 7806        if (aes->devId == WOLFSSL_SECO_DEVID) {
 7807            return ret;
 7808        }
 7809    #endif /* WOLFSSL_SECO_CAAM */
 7810
 7811    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
 7812        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
 7813        return ret;
 7814    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
 7815
 7816/* GCM setup needs one AES block encrypt of the all-zero IV to generate
 7817 * the hash subkey H. STM32_CRYPTO stores only the raw key (no expanded
 7818 * key schedule), so the ARMASM AES_ECB_encrypt helpers used here cannot
 7819 * be used. Excluding STM32_CRYPTO from this block falls back to the
 7820 * non-ARMASM wc_AesEncrypt implementation, which on STM32 routes to
 7821 * CRYP. */
 7822#if defined(WOLFSSL_ARMASM) && !defined(STM32_CRYPTO)
 7823    if (ret == 0) {
 7824#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
 7825    #if !defined(__aarch64__)
 7826        AES_GCM_set_key_AARCH32(iv, (byte*)aes->key, aes->gcm.H, aes->rounds);
 7827    #else
 7828        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
 7829            AES_GCM_set_key_AARCH64(iv, (byte*)aes->key, aes->gcm.H,
 7830                aes->rounds);
 7831        }
 7832        else
 7833    #endif /* !__aarch64__ */
 7834#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
 7835#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
 7836    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
 7837        {
 7838            AES_ECB_encrypt_NEON(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
 7839                (const unsigned char*)aes->key, aes->rounds);
 7840        }
 7841#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 7842        {
 7843            AES_ECB_encrypt(iv, aes->gcm.H, WC_AES_BLOCK_SIZE,
 7844                (const unsigned char*)aes->key, aes->rounds);
 7845        #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
 7846            GenerateM0(&aes->gcm);
 7847        #endif /* GCM_TABLE */
 7848        }
 7849#endif
 7850    }
 7851#else
 7852#if !defined(FREESCALE_LTC_AES_GCM) && !defined(WOLFSSL_PSOC6_CRYPTO)
 7853
 7854
 7855#ifdef WOLF_CRYPTO_CB_AES_SETKEY
 7856    if ((ret == 0) && (aes->devId != INVALID_DEVID && aes->devCtx != NULL)) {
 7857        /* SE owns key - skip H and M table generation */
 7858    }
 7859    else
 7860#endif
 7861    if (ret == 0) {
 7862        VECTOR_REGISTERS_PUSH;
 7863
 7864        /* Generate H = AES_Encrypt(key, 0^128) */
 7865        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
 7866
 7867        if (ret == 0) {
 7868#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
 7869    #if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT)
 7870            if (aes->use_aesni) {
 7871        #if defined(WC_C_DYNAMIC_FALLBACK)
 7872            #ifdef HAVE_INTEL_AVX2
 7873                if (IS_INTEL_AVX2(intel_flags)) {
 7874                    GCM_generate_m0_avx2(aes->gcm.H,
 7875                        (byte*)aes->gcm.M0);
 7876                }
 7877                else
 7878            #endif
 7879            #if defined(HAVE_INTEL_AVX1)
 7880                if (IS_INTEL_AVX1(intel_flags)) {
 7881                    GCM_generate_m0_avx1(aes->gcm.H,
 7882                        (byte*)aes->gcm.M0);
 7883                }
 7884                else
 7885            #endif
 7886                {
 7887                    GCM_generate_m0_aesni(aes->gcm.H,
 7888                        (byte*)aes->gcm.M0);
 7889                }
 7890        #endif /* WC_C_DYNAMIC_FALLBACK */
 7891            }
 7892            else
 7893    #endif /* AESNI */
 7894            {
 7895                GenerateM0(&aes->gcm);
 7896            }
 7897#endif /* GCM_TABLE || GCM_TABLE_4BIT */
 7898        }
 7899
 7900        VECTOR_REGISTERS_POP;
 7901    }
 7902#endif /* !FREESCALE_LTC_AES_GCM && !WOLFSSL_PSOC6_CRYPTO */
 7903#endif
 7904
 7905#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
 7906    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
 7907#endif
 7908
 7909#ifdef WOLF_CRYPTO_CB
 7910    if (aes->devId != INVALID_DEVID) {
 7911    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
 7912        if (aes->devCtx != NULL) {
 7913            /* SE owns key - don't copy to devKey */
 7914        }
 7915        else
 7916    #endif
 7917        {
 7918            XMEMCPY(aes->devKey, key, len);
 7919        }
 7920    }
 7921#endif
 7922
 7923#ifdef WOLFSSL_IMX6_CAAM_BLOB
 7924    ForceZero(local, sizeof(local));
 7925#endif
 7926    return ret;
 7927}
 7928
 7929
 7930#ifdef WOLFSSL_AESNI
 7931
 7932void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
 7933                     const unsigned char* addt, const unsigned char* ivec,
 7934                     unsigned char *tag, word32 nbytes,
 7935                     word32 abytes, word32 ibytes,
 7936                     word32 tbytes, const unsigned char* key, int nr)
 7937                     XASM_LINK("AES_GCM_encrypt_aesni");
 7938#ifdef HAVE_INTEL_AVX1
 7939void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
 7940                          const unsigned char* addt, const unsigned char* ivec,
 7941                          unsigned char *tag, word32 nbytes,
 7942                          word32 abytes, word32 ibytes,
 7943                          word32 tbytes, const unsigned char* key,
 7944                          int nr)
 7945                          XASM_LINK("AES_GCM_encrypt_avx1");
 7946#ifdef HAVE_INTEL_AVX2
 7947void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
 7948                          const unsigned char* addt, const unsigned char* ivec,
 7949                          unsigned char *tag, word32 nbytes,
 7950                          word32 abytes, word32 ibytes,
 7951                          word32 tbytes, const unsigned char* key,
 7952                          int nr)
 7953                          XASM_LINK("AES_GCM_encrypt_avx2");
 7954#endif /* HAVE_INTEL_AVX2 */
 7955#endif /* HAVE_INTEL_AVX1 */
 7956
 7957#ifdef HAVE_AES_DECRYPT
 7958void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
 7959                     const unsigned char* addt, const unsigned char* ivec,
 7960                     const unsigned char *tag, word32 nbytes, word32 abytes,
 7961                     word32 ibytes, word32 tbytes, const unsigned char* key,
 7962                     int nr, int* res)
 7963                     XASM_LINK("AES_GCM_decrypt_aesni");
 7964#ifdef HAVE_INTEL_AVX1
 7965void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
 7966                          const unsigned char* addt, const unsigned char* ivec,
 7967                          const unsigned char *tag, word32 nbytes,
 7968                          word32 abytes, word32 ibytes, word32 tbytes,
 7969                          const unsigned char* key, int nr, int* res)
 7970                          XASM_LINK("AES_GCM_decrypt_avx1");
 7971#ifdef HAVE_INTEL_AVX2
 7972void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
 7973                          const unsigned char* addt, const unsigned char* ivec,
 7974                          const unsigned char *tag, word32 nbytes,
 7975                          word32 abytes, word32 ibytes, word32 tbytes,
 7976                          const unsigned char* key, int nr, int* res)
 7977                          XASM_LINK("AES_GCM_decrypt_avx2");
 7978#endif /* HAVE_INTEL_AVX2 */
 7979#endif /* HAVE_INTEL_AVX1 */
 7980#endif /* HAVE_AES_DECRYPT */
 7981
 7982#endif /* WOLFSSL_AESNI */
 7983
 7984#if !defined(WOLFSSL_ARMASM) || defined(__aarch64__) || \
 7985    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 7986#if defined(GCM_SMALL)
 7987static void GMULT(byte* X, byte* Y)
 7988{
 7989    byte Z[WC_AES_BLOCK_SIZE];
 7990    byte V[WC_AES_BLOCK_SIZE];
 7991    int i, j;
 7992
 7993    XMEMSET(Z, 0, WC_AES_BLOCK_SIZE);
 7994    XMEMCPY(V, X, WC_AES_BLOCK_SIZE);
 7995    for (i = 0; i < WC_AES_BLOCK_SIZE; i++)
 7996    {
 7997        byte y = Y[i];
 7998        for (j = 0; j < 8; j++)
 7999        {
 8000            if (y & 0x80) {
 8001                xorbuf(Z, V, WC_AES_BLOCK_SIZE);
 8002            }
 8003
 8004            RIGHTSHIFTX(V);
 8005            y = y << 1;
 8006        }
 8007    }
 8008    XMEMCPY(X, Z, WC_AES_BLOCK_SIZE);
 8009}
 8010
 8011
 8012void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
 8013    word32 cSz, byte* s, word32 sSz)
 8014{
 8015    byte x[WC_AES_BLOCK_SIZE];
 8016    byte scratch[WC_AES_BLOCK_SIZE];
 8017    word32 blocks, partial;
 8018    byte* h;
 8019
 8020    if (gcm == NULL) {
 8021        return;
 8022    }
 8023
 8024    h = gcm->H;
 8025    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
 8026
 8027    /* Hash in A, the Additional Authentication Data */
 8028    if (aSz != 0 && a != NULL) {
 8029        blocks = aSz / WC_AES_BLOCK_SIZE;
 8030        partial = aSz % WC_AES_BLOCK_SIZE;
 8031        while (blocks--) {
 8032            xorbuf(x, a, WC_AES_BLOCK_SIZE);
 8033            GMULT(x, h);
 8034            a += WC_AES_BLOCK_SIZE;
 8035        }
 8036        if (partial != 0) {
 8037            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8038            XMEMCPY(scratch, a, partial);
 8039            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
 8040            GMULT(x, h);
 8041        }
 8042    }
 8043
 8044    /* Hash in C, the Ciphertext */
 8045    if (cSz != 0 && c != NULL) {
 8046        blocks = cSz / WC_AES_BLOCK_SIZE;
 8047        partial = cSz % WC_AES_BLOCK_SIZE;
 8048        while (blocks--) {
 8049            xorbuf(x, c, WC_AES_BLOCK_SIZE);
 8050            GMULT(x, h);
 8051            c += WC_AES_BLOCK_SIZE;
 8052        }
 8053        if (partial != 0) {
 8054            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8055            XMEMCPY(scratch, c, partial);
 8056            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
 8057            GMULT(x, h);
 8058        }
 8059    }
 8060
 8061    /* Hash in the lengths of A and C in bits */
 8062    FlattenSzInBits(&scratch[0], aSz);
 8063    FlattenSzInBits(&scratch[8], cSz);
 8064    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
 8065    GMULT(x, h);
 8066
 8067    /* Copy the result into s. */
 8068    XMEMCPY(s, x, sSz);
 8069}
 8070
 8071#ifdef WOLFSSL_AESGCM_STREAM
 8072/* No extra initialization for small implementation.
 8073 *
 8074 * @param [in] aes  AES GCM object.
 8075 */
 8076#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
 8077
 8078/* GHASH one block of data..
 8079 *
 8080 * XOR block into tag and GMULT with H.
 8081 *
 8082 * @param [in, out] aes    AES GCM object.
 8083 * @param [in]      block  Block of AAD or cipher text.
 8084 */
 8085#define GHASH_ONE_BLOCK_SW(aes, block)                  \
 8086    do {                                                \
 8087        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
 8088        GMULT(AES_TAG(aes), (aes)->gcm.H);              \
 8089    }                                                   \
 8090    while (0)
 8091#endif /* WOLFSSL_AESGCM_STREAM */
 8092
 8093#if defined(WOLFSSL_ARMASM) && (!defined(__aarch64__) || \
 8094    defined(WOLFSSL_ARMASM_NO_NEON))
 8095static void GCM_gmult_len_armasm_C(
 8096    byte* x, const byte* h, const unsigned char* a, unsigned long len)
 8097{
 8098    byte Z[AES_BLOCK_SIZE];
 8099    byte V[AES_BLOCK_SIZE];
 8100    int i;
 8101    int j;
 8102
 8103    while (len >= AES_BLOCK_SIZE) {
 8104        xorbuf(x, a, AES_BLOCK_SIZE);
 8105        XMEMSET(Z, 0, AES_BLOCK_SIZE);
 8106        XMEMCPY(V, x, AES_BLOCK_SIZE);
 8107        for (i = 0; i < AES_BLOCK_SIZE; i++) {
 8108            byte y = h[i];
 8109            for (j = 0; j < 8; j++) {
 8110                if (y & 0x80) {
 8111                    xorbuf(Z, V, AES_BLOCK_SIZE);
 8112                }
 8113                RIGHTSHIFTX(V);
 8114                y = y << 1;
 8115            }
 8116        }
 8117        XMEMCPY(x, Z, AES_BLOCK_SIZE);
 8118        len -= AES_BLOCK_SIZE;
 8119        a += AES_BLOCK_SIZE;
 8120    }
 8121}
 8122
 8123#define GCM_GMULT_LEN(gcm, x, a, len) \
 8124    GCM_gmult_len_armasm_C(x, (gcm)->H, a, len)
 8125#elif defined(WOLFSSL_ARMASM)
 8126#define GCM_GMULT_LEN(gcm, x, a, len) \
 8127    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
 8128#endif
 8129
 8130#elif defined(GCM_TABLE)
 8131
 8132#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
 8133    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
 8134#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
 8135#define GCM_GMULT_LEN(gcm, x, a, len) \
 8136    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
 8137#else
 8138#define GCM_GMULT_LEN(gcm, x, a, len) \
 8139    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
 8140#endif
 8141#else
 8142ALIGN16 static const byte R[256][2] = {
 8143    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
 8144    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
 8145    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
 8146    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
 8147    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
 8148    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
 8149    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
 8150    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
 8151    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
 8152    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
 8153    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
 8154    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
 8155    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
 8156    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
 8157    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
 8158    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
 8159    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
 8160    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
 8161    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
 8162    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
 8163    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
 8164    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
 8165    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
 8166    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
 8167    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
 8168    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
 8169    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
 8170    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
 8171    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
 8172    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
 8173    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
 8174    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
 8175    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
 8176    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
 8177    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
 8178    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
 8179    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
 8180    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
 8181    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
 8182    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
 8183    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
 8184    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
 8185    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
 8186    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
 8187    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
 8188    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
 8189    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
 8190    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
 8191    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
 8192    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
 8193    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
 8194    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
 8195    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
 8196    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
 8197    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
 8198    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
 8199    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
 8200    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
 8201    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
 8202    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
 8203    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
 8204    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
 8205    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
 8206    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
 8207
 8208
 8209static void GMULT(byte *x, byte m[256][WC_AES_BLOCK_SIZE])
 8210{
 8211#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
 8212    int i, j;
 8213    byte Z[WC_AES_BLOCK_SIZE];
 8214    byte a;
 8215
 8216    XMEMSET(Z, 0, sizeof(Z));
 8217
 8218    for (i = 15; i > 0; i--) {
 8219        xorbuf(Z, m[x[i]], WC_AES_BLOCK_SIZE);
 8220        a = Z[15];
 8221
 8222        for (j = 15; j > 0; j--) {
 8223            Z[j] = Z[j-1];
 8224        }
 8225
 8226        Z[0]  = R[a][0];
 8227        Z[1] ^= R[a][1];
 8228    }
 8229    xorbuf(Z, m[x[0]], WC_AES_BLOCK_SIZE);
 8230
 8231    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
 8232#elif defined(WC_32BIT_CPU)
 8233    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
 8234    byte a;
 8235    word32* pZ;
 8236    word32* pm;
 8237    word32* px = (word32*)(x);
 8238    int i;
 8239
 8240    pZ = (word32*)(Z + 15 + 1);
 8241    pm = (word32*)(m[x[15]]);
 8242    pZ[0] = pm[0];
 8243    pZ[1] = pm[1];
 8244    pZ[2] = pm[2];
 8245    pZ[3] = pm[3];
 8246    a = Z[16 + 15];
 8247    Z[15]  = R[a][0];
 8248    Z[16] ^= R[a][1];
 8249    for (i = 14; i > 0; i--) {
 8250        pZ = (word32*)(Z + i + 1);
 8251        pm = (word32*)(m[x[i]]);
 8252        pZ[0] ^= pm[0];
 8253        pZ[1] ^= pm[1];
 8254        pZ[2] ^= pm[2];
 8255        pZ[3] ^= pm[3];
 8256        a = Z[16 + i];
 8257        Z[i]    = R[a][0];
 8258        Z[i+1] ^= R[a][1];
 8259    }
 8260    pZ = (word32*)(Z + 1);
 8261    pm = (word32*)(m[x[0]]);
 8262    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
 8263    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
 8264#else
 8265    byte Z[WC_AES_BLOCK_SIZE + WC_AES_BLOCK_SIZE];
 8266    byte a;
 8267    word64* pZ;
 8268    word64* pm;
 8269    word64* px = (word64*)(x);
 8270    int i;
 8271
 8272    pZ = (word64*)(Z + 15 + 1);
 8273    pm = (word64*)(m[x[15]]);
 8274    pZ[0] = pm[0];
 8275    pZ[1] = pm[1];
 8276    a = Z[16 + 15];
 8277    Z[15]  = R[a][0];
 8278    Z[16] ^= R[a][1];
 8279    for (i = 14; i > 0; i--) {
 8280        pZ = (word64*)(Z + i + 1);
 8281        pm = (word64*)(m[x[i]]);
 8282        pZ[0] ^= pm[0];
 8283        pZ[1] ^= pm[1];
 8284        a = Z[16 + i];
 8285        Z[i]    = R[a][0];
 8286        Z[i+1] ^= R[a][1];
 8287    }
 8288    pZ = (word64*)(Z + 1);
 8289    pm = (word64*)(m[x[0]]);
 8290    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
 8291#endif
 8292}
 8293#endif
 8294
 8295void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
 8296    word32 cSz, byte* s, word32 sSz)
 8297{
 8298    byte x[WC_AES_BLOCK_SIZE];
 8299    byte scratch[WC_AES_BLOCK_SIZE];
 8300    word32 blocks, partial;
 8301
 8302    if (gcm == NULL) {
 8303        return;
 8304    }
 8305
 8306    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
 8307
 8308    /* Hash in A, the Additional Authentication Data */
 8309    if (aSz != 0 && a != NULL) {
 8310        blocks = aSz / WC_AES_BLOCK_SIZE;
 8311        partial = aSz % WC_AES_BLOCK_SIZE;
 8312    #ifdef GCM_GMULT_LEN
 8313        if (blocks > 0) {
 8314            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
 8315            a += blocks * WC_AES_BLOCK_SIZE;
 8316        }
 8317        if (partial != 0) {
 8318            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8319            XMEMCPY(scratch, a, partial);
 8320            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
 8321        }
 8322    #else
 8323        while (blocks--) {
 8324            xorbuf(x, a, WC_AES_BLOCK_SIZE);
 8325            GMULT(x, gcm->M0);
 8326            a += WC_AES_BLOCK_SIZE;
 8327        }
 8328        if (partial != 0) {
 8329            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8330            XMEMCPY(scratch, a, partial);
 8331            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
 8332            GMULT(x, gcm->M0);
 8333        }
 8334    #endif
 8335    }
 8336
 8337    /* Hash in C, the Ciphertext */
 8338    if (cSz != 0 && c != NULL) {
 8339        blocks = cSz / WC_AES_BLOCK_SIZE;
 8340        partial = cSz % WC_AES_BLOCK_SIZE;
 8341    #ifdef GCM_GMULT_LEN
 8342        if (blocks > 0) {
 8343            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
 8344            c += blocks * WC_AES_BLOCK_SIZE;
 8345        }
 8346        if (partial != 0) {
 8347            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8348            XMEMCPY(scratch, c, partial);
 8349            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
 8350        }
 8351    #else
 8352        while (blocks--) {
 8353            xorbuf(x, c, WC_AES_BLOCK_SIZE);
 8354            GMULT(x, gcm->M0);
 8355            c += WC_AES_BLOCK_SIZE;
 8356        }
 8357        if (partial != 0) {
 8358            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8359            XMEMCPY(scratch, c, partial);
 8360            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
 8361            GMULT(x, gcm->M0);
 8362        }
 8363    #endif
 8364    }
 8365
 8366    /* Hash in the lengths of A and C in bits */
 8367    FlattenSzInBits(&scratch[0], aSz);
 8368    FlattenSzInBits(&scratch[8], cSz);
 8369#ifdef GCM_GMULT_LEN
 8370    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
 8371#else
 8372    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
 8373    GMULT(x, gcm->M0);
 8374#endif
 8375
 8376    /* Copy the result into s. */
 8377    XMEMCPY(s, x, sSz);
 8378}
 8379
 8380#ifdef WOLFSSL_AESGCM_STREAM
 8381/* No extra initialization for table implementation.
 8382 *
 8383 * @param [in] aes  AES GCM object.
 8384 */
 8385#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
 8386
 8387/* GHASH one block of data..
 8388 *
 8389 * XOR block into tag and GMULT with H using pre-computed table.
 8390 *
 8391 * @param [in, out] aes    AES GCM object.
 8392 * @param [in]      block  Block of AAD or cipher text.
 8393 */
 8394#define GHASH_ONE_BLOCK_SW(aes, block)                  \
 8395    do {                                                \
 8396        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
 8397        GMULT(AES_TAG(aes), aes->gcm.M0);               \
 8398    }                                                   \
 8399    while (0)
 8400#endif /* WOLFSSL_AESGCM_STREAM */
 8401/* end GCM_TABLE */
 8402#elif defined(GCM_TABLE_4BIT)
 8403
 8404#if defined(WOLFSSL_ARMASM) && (defined(__aarch64__) || \
 8405    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
 8406#if !defined(WOLFSSL_ARMASM_NO_NEON) && defined(__aarch64__)
 8407#define GCM_GMULT_LEN(gcm, x, a, len) \
 8408    GCM_gmult_len_NEON(x, (const byte*)((gcm)->H), a, len)
 8409#define GMULT(x, m)                                                      \
 8410    GCM_gmult_NEON(x, (const byte**)m)
 8411#else
 8412#define GCM_GMULT_LEN(gcm, x, a, len) \
 8413    GCM_gmult_len(x, (const byte**)((gcm)->M0), a, len)
 8414#define GMULT(x, m)                                                      \
 8415    GCM_gmult(x, (const byte**)m)
 8416#endif
 8417#else
 8418/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
 8419 *  R shifts right a reverse bit pair of bytes such that:
 8420 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
 8421 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
 8422 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
 8423 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
 8424 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
 8425 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
 8426 *  To calculate te rest, XOR result for each bit.
 8427 *   e.g. 6 = 4 ^ 2 => 48,c0
 8428 *
 8429 * Second half is same values rotated by 4-bits.
 8430 */
 8431#if defined(WC_16BIT_CPU)
 8432static const byte R[16][2] = {
 8433    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
 8434    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
 8435    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
 8436    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
 8437};
 8438#elif defined(BIG_ENDIAN_ORDER)
 8439static const word16 R[32] = {
 8440          0x0000,       0x1c20,       0x3840,       0x2460,
 8441          0x7080,       0x6ca0,       0x48c0,       0x54e0,
 8442          0xe100,       0xfd20,       0xd940,       0xc560,
 8443          0x9180,       0x8da0,       0xa9c0,       0xb5e0,
 8444
 8445          0x0000,       0x01c2,       0x0384,       0x0246,
 8446          0x0708,       0x06ca,       0x048c,       0x054e,
 8447          0x0e10,       0x0fd2,       0x0d94,       0x0c56,
 8448          0x0918,       0x08da,       0x0a9c,       0x0b5e,
 8449};
 8450#else
 8451static const word16 R[32] = {
 8452          0x0000,       0x201c,       0x4038,       0x6024,
 8453          0x8070,       0xa06c,       0xc048,       0xe054,
 8454          0x00e1,       0x20fd,       0x40d9,       0x60c5,
 8455          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
 8456
 8457          0x0000,       0xc201,       0x8403,       0x4602,
 8458          0x0807,       0xca06,       0x8c04,       0x4e05,
 8459          0x100e,       0xd20f,       0x940d,       0x560c,
 8460          0x1809,       0xda08,       0x9c0a,       0x5e0b,
 8461};
 8462#endif
 8463
 8464/* Multiply in GF(2^128) defined by polynomial:
 8465 *   x^128 + x^7 + x^2 + x^1 + 1.
 8466 *
 8467 * H: hash key = encrypt(key, 0)
 8468 * x = x * H in field
 8469 *
 8470 * x: cumulative result
 8471 * m: 4-bit table
 8472 *    [0..15] * H
 8473 */
 8474#if defined(WC_16BIT_CPU)
 8475static void GMULT(byte *x, byte m[16][WC_AES_BLOCK_SIZE])
 8476{
 8477    int i, j, n;
 8478    byte Z[WC_AES_BLOCK_SIZE];
 8479    byte a;
 8480
 8481    XMEMSET(Z, 0, sizeof(Z));
 8482
 8483    for (i = 15; i >= 0; i--) {
 8484        for (n = 0; n < 2; n++) {
 8485            if (n == 0)
 8486                xorbuf(Z, m[x[i] & 0xf], WC_AES_BLOCK_SIZE);
 8487            else {
 8488                xorbuf(Z, m[x[i] >> 4], WC_AES_BLOCK_SIZE);
 8489                if (i == 0)
 8490                    break;
 8491            }
 8492            a = Z[15] & 0xf;
 8493
 8494            for (j = 15; j > 0; j--)
 8495                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
 8496            Z[0] >>= 4;
 8497
 8498            Z[0] ^= R[a][0];
 8499            Z[1] ^= R[a][1];
 8500        }
 8501    }
 8502
 8503    XMEMCPY(x, Z, WC_AES_BLOCK_SIZE);
 8504}
 8505#elif defined(WC_32BIT_CPU) && defined(BIG_ENDIAN_ORDER)
 8506static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
 8507{
 8508    int i;
 8509    word32 z8[4] = {0, 0, 0, 0};
 8510    byte a;
 8511    word32* x8 = (word32*)x;
 8512    word32* m8;
 8513    byte xi;
 8514
 8515    for (i = 15; i > 0; i--) {
 8516        xi = x[i];
 8517
 8518        /* XOR in (msn * H) */
 8519        m8 = (word32*)m[xi & 0xf];
 8520        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
 8521
 8522        /* Cache top byte for remainder calculations - lost in rotate. */
 8523        a = (byte)(z8[3] & 0xff);
 8524
 8525        /* Rotate Z by 8-bits */
 8526        z8[3] = (z8[2] << 24) | (z8[3] >> 8);
 8527        z8[2] = (z8[1] << 24) | (z8[2] >> 8);
 8528        z8[1] = (z8[0] << 24) | (z8[1] >> 8);
 8529        z8[0] >>= 8;
 8530
 8531        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
 8532        z8[0] ^= ((word32)R[16 + (a & 0xf)]) << 16;
 8533
 8534        xi >>= 4;
 8535        /* XOR in next significant nibble (XORed with H) * remainder */
 8536        m8 = (word32*)m[xi];
 8537        a ^= (byte)(m8[3] >> 12) & 0xf;
 8538        a ^= (byte)((m8[3] << 4) & 0xf0);
 8539        z8[0] ^= ((word32)R[a >> 4]) << 16;
 8540
 8541        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
 8542        m8 = (word32*)m[16 + xi];
 8543        z8[0] ^= m8[0]; z8[1] ^= m8[1];
 8544        z8[2] ^= m8[2]; z8[3] ^= m8[3];
 8545    }
 8546
 8547    xi = x[0];
 8548
 8549    /* XOR in most significant nibble * H */
 8550    m8 = (word32*)m[xi & 0xf];
 8551    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
 8552
 8553    /* Cache top byte for remainder calculations - lost in rotate. */
 8554    a = (byte)(z8[3] & 0x0f);
 8555
 8556    z8[3] = (z8[2] << 28) | (z8[3] >> 4);
 8557    z8[2] = (z8[1] << 28) | (z8[2] >> 4);
 8558    z8[1] = (z8[0] << 28) | (z8[1] >> 4);
 8559    z8[0] >>= 4;
 8560
 8561    /* XOR in most significant nibble * remainder */
 8562    z8[0] ^= ((word32)R[a]) << 16;
 8563    /* XOR in next significant nibble * H */
 8564    m8 = (word32*)m[xi >> 4];
 8565    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
 8566
 8567    /* Write back result. */
 8568    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
 8569}
 8570#elif defined(WC_32BIT_CPU)
 8571static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
 8572{
 8573    int i;
 8574    word32 z8[4] = {0, 0, 0, 0};
 8575    byte a;
 8576    word32* x8 = (word32*)x;
 8577    word32* m8;
 8578    byte xi;
 8579    word32 n7, n6, n5, n4, n3, n2, n1, n0;
 8580
 8581    for (i = 15; i > 0; i--) {
 8582        xi = x[i];
 8583
 8584        /* XOR in (msn * H) */
 8585        m8 = (word32*)m[xi & 0xf];
 8586        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
 8587
 8588        /* Cache top byte for remainder calculations - lost in rotate. */
 8589        a = (byte)(z8[3] >> 24);
 8590
 8591        /* Rotate Z by 8-bits */
 8592        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
 8593        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
 8594        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
 8595        z8[0] <<= 8;
 8596
 8597        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
 8598        z8[0] ^= (word32)R[16 + (a & 0xf)];
 8599
 8600        xi >>= 4;
 8601        /* XOR in next significant nibble (XORed with H) * remainder */
 8602        m8 = (word32*)m[xi];
 8603        a ^= (byte)(m8[3] >> 20);
 8604        z8[0] ^= (word32)R[a >> 4];
 8605
 8606        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
 8607        m8 = (word32*)m[16 + xi];
 8608        z8[0] ^= m8[0]; z8[1] ^= m8[1];
 8609        z8[2] ^= m8[2]; z8[3] ^= m8[3];
 8610    }
 8611
 8612    xi = x[0];
 8613
 8614    /* XOR in most significant nibble * H */
 8615    m8 = (word32*)m[xi & 0xf];
 8616    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
 8617
 8618    /* Cache top byte for remainder calculations - lost in rotate. */
 8619    a = (z8[3] >> 24) & 0xf;
 8620
 8621    /* Rotate z by 4-bits */
 8622    n7 = z8[3] & 0xf0f0f0f0ULL;
 8623    n6 = z8[3] & 0x0f0f0f0fULL;
 8624    n5 = z8[2] & 0xf0f0f0f0ULL;
 8625    n4 = z8[2] & 0x0f0f0f0fULL;
 8626    n3 = z8[1] & 0xf0f0f0f0ULL;
 8627    n2 = z8[1] & 0x0f0f0f0fULL;
 8628    n1 = z8[0] & 0xf0f0f0f0ULL;
 8629    n0 = z8[0] & 0x0f0f0f0fULL;
 8630    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
 8631    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
 8632    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
 8633    z8[0] = (n1 >> 4) | (n0 << 12);
 8634
 8635    /* XOR in most significant nibble * remainder */
 8636    z8[0] ^= (word32)R[a];
 8637    /* XOR in next significant nibble * H */
 8638    m8 = (word32*)m[xi >> 4];
 8639    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
 8640
 8641    /* Write back result. */
 8642    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
 8643}
 8644#elif defined(WC_64BIT_CPU) && defined(BIG_ENDIAN_ORDER)
 8645static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
 8646{
 8647    int i;
 8648    word64 z8[2] = {0, 0};
 8649    byte a;
 8650    word64* x8 = (word64*)x;
 8651    word64* m8;
 8652    byte xi;
 8653
 8654    for (i = 15; i > 0; i--) {
 8655        xi = x[i];
 8656
 8657        /* XOR in (msn * H) */
 8658        m8 = (word64*)m[xi & 0xf];
 8659        z8[0] ^= m8[0];
 8660        z8[1] ^= m8[1];
 8661
 8662        /* Cache top byte for remainder calculations - lost in rotate. */
 8663        a = (byte)(z8[1] & 0xff);
 8664
 8665        /* Rotate Z by 8-bits */
 8666        z8[1] = (z8[0] << 56) | (z8[1] >> 8);
 8667        z8[0] >>= 8;
 8668
 8669        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
 8670        m8 = (word64*)m[16 + (xi >> 4)];
 8671        z8[0] ^= m8[0];
 8672        z8[1] ^= m8[1];
 8673
 8674        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
 8675        z8[0] ^= ((word64)R[16 + (a & 0xf)]) << 48;
 8676        /* XOR in next significant nibble (XORed with H) * remainder */
 8677        m8 = (word64*)m[xi >> 4];
 8678        a ^= (byte)(m8[1] >> 12) & 0xf;
 8679        a ^= (byte)((m8[1] << 4) & 0xf0);
 8680        z8[0] ^= ((word64)R[a >> 4]) << 48;
 8681    }
 8682
 8683    xi = x[0];
 8684
 8685    /* XOR in most significant nibble * H */
 8686    m8 = (word64*)m[xi & 0xf];
 8687    z8[0] ^= m8[0];
 8688    z8[1] ^= m8[1];
 8689
 8690    /* Cache top byte for remainder calculations - lost in rotate. */
 8691    a = (byte)(z8[1] & 0x0f);
 8692
 8693    /* Rotate z by 4-bits */
 8694    z8[1] = (z8[0] << 60) | (z8[1] >> 4);
 8695    z8[0] >>= 4;
 8696
 8697    /* XOR in next significant nibble * H */
 8698    m8 = (word64*)m[xi >> 4];
 8699    z8[0] ^= m8[0];
 8700    z8[1] ^= m8[1];
 8701    /* XOR in most significant nibble * remainder */
 8702    z8[0] ^= ((word64)R[a]) << 48;
 8703
 8704    /* Write back result. */
 8705    x8[0] = z8[0];
 8706    x8[1] = z8[1];
 8707}
 8708#else
 8709static WC_INLINE void GMULT(byte *x, byte m[32][WC_AES_BLOCK_SIZE])
 8710{
 8711    int i;
 8712    word64 z8[2] = {0, 0};
 8713    byte a;
 8714    word64* x8 = (word64*)x;
 8715    word64* m8;
 8716    word64 n0, n1, n2, n3;
 8717    byte xi;
 8718
 8719    for (i = 15; i > 0; i--) {
 8720        xi = x[i];
 8721
 8722        /* XOR in (msn * H) */
 8723        m8 = (word64*)m[xi & 0xf];
 8724        z8[0] ^= m8[0];
 8725        z8[1] ^= m8[1];
 8726
 8727        /* Cache top byte for remainder calculations - lost in rotate. */
 8728        a = (byte)(z8[1] >> 56);
 8729
 8730        /* Rotate Z by 8-bits */
 8731        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
 8732        z8[0] <<= 8;
 8733
 8734        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
 8735        m8 = (word64*)m[16 + (xi >> 4)];
 8736        z8[0] ^= m8[0];
 8737        z8[1] ^= m8[1];
 8738
 8739        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
 8740        z8[0] ^= (word64)R[16 + (a & 0xf)];
 8741        /* XOR in next significant nibble (XORed with H) * remainder */
 8742        m8 = (word64*)m[xi >> 4];
 8743        a ^= (byte)(m8[1] >> 52);
 8744        z8[0] ^= (word64)R[a >> 4];
 8745    }
 8746
 8747    xi = x[0];
 8748
 8749    /* XOR in most significant nibble * H */
 8750    m8 = (word64*)m[xi & 0xf];
 8751    z8[0] ^= m8[0];
 8752    z8[1] ^= m8[1];
 8753
 8754    /* Cache top byte for remainder calculations - lost in rotate. */
 8755    a = (z8[1] >> 56) & 0xf;
 8756
 8757    /* Rotate z by 4-bits */
 8758    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
 8759    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
 8760    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
 8761    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
 8762    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
 8763    z8[0] = (n1 >> 4) | (n0 << 12);
 8764
 8765    /* XOR in next significant nibble * H */
 8766    m8 = (word64*)m[xi >> 4];
 8767    z8[0] ^= m8[0];
 8768    z8[1] ^= m8[1];
 8769    /* XOR in most significant nibble * remainder */
 8770    z8[0] ^= (word64)R[a];
 8771
 8772    /* Write back result. */
 8773    x8[0] = z8[0];
 8774    x8[1] = z8[1];
 8775}
 8776#endif
 8777#endif
 8778
 8779void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
 8780    word32 cSz, byte* s, word32 sSz)
 8781{
 8782    byte x[WC_AES_BLOCK_SIZE];
 8783    byte scratch[WC_AES_BLOCK_SIZE];
 8784    word32 blocks, partial;
 8785
 8786    if (gcm == NULL) {
 8787        return;
 8788    }
 8789
 8790    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
 8791
 8792    /* Hash in A, the Additional Authentication Data */
 8793    if (aSz != 0 && a != NULL) {
 8794        blocks = aSz / WC_AES_BLOCK_SIZE;
 8795        partial = aSz % WC_AES_BLOCK_SIZE;
 8796    #ifdef GCM_GMULT_LEN
 8797        if (blocks > 0) {
 8798            GCM_GMULT_LEN(gcm, x, a, blocks * WC_AES_BLOCK_SIZE);
 8799            a += blocks * WC_AES_BLOCK_SIZE;
 8800        }
 8801        if (partial != 0) {
 8802            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8803            XMEMCPY(scratch, a, partial);
 8804            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
 8805        }
 8806    #else
 8807        while (blocks--) {
 8808            xorbuf(x, a, WC_AES_BLOCK_SIZE);
 8809            GMULT(x, gcm->M0);
 8810            a += WC_AES_BLOCK_SIZE;
 8811        }
 8812        if (partial != 0) {
 8813            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8814            XMEMCPY(scratch, a, partial);
 8815            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
 8816            GMULT(x, gcm->M0);
 8817        }
 8818    #endif
 8819    }
 8820
 8821    /* Hash in C, the Ciphertext */
 8822    if (cSz != 0 && c != NULL) {
 8823        blocks = cSz / WC_AES_BLOCK_SIZE;
 8824        partial = cSz % WC_AES_BLOCK_SIZE;
 8825    #ifdef GCM_GMULT_LEN
 8826        if (blocks > 0) {
 8827            GCM_GMULT_LEN(gcm, x, c, blocks * WC_AES_BLOCK_SIZE);
 8828            c += blocks * WC_AES_BLOCK_SIZE;
 8829        }
 8830        if (partial != 0) {
 8831            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8832            XMEMCPY(scratch, c, partial);
 8833            GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
 8834        }
 8835    #else
 8836        while (blocks--) {
 8837            xorbuf(x, c, WC_AES_BLOCK_SIZE);
 8838            GMULT(x, gcm->M0);
 8839            c += WC_AES_BLOCK_SIZE;
 8840        }
 8841        if (partial != 0) {
 8842            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
 8843            XMEMCPY(scratch, c, partial);
 8844            xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
 8845            GMULT(x, gcm->M0);
 8846        }
 8847    #endif
 8848    }
 8849
 8850    /* Hash in the lengths of A and C in bits */
 8851    FlattenSzInBits(&scratch[0], aSz);
 8852    FlattenSzInBits(&scratch[8], cSz);
 8853#ifdef GCM_GMULT_LEN
 8854    GCM_GMULT_LEN(gcm, x, scratch, WC_AES_BLOCK_SIZE);
 8855#else
 8856    xorbuf(x, scratch, WC_AES_BLOCK_SIZE);
 8857    GMULT(x, gcm->M0);
 8858#endif
 8859
 8860    /* Copy the result into s. */
 8861    XMEMCPY(s, x, sSz);
 8862}
 8863
 8864#ifdef WOLFSSL_AESGCM_STREAM
 8865/* No extra initialization for 4-bit table implementation.
 8866 *
 8867 * @param [in] aes  AES GCM object.
 8868 */
 8869#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
 8870
 8871#ifdef GCM_GMULT_LEN
 8872/* GHASH one block of data.
 8873 *
 8874 * @param [in, out] aes    AES GCM object.
 8875 * @param [in]      block  Block of AAD or cipher text.
 8876 */
 8877#define GHASH_ONE_BLOCK_SW(aes, block)                                  \
 8878   GCM_GMULT_LEN(&(aes)->gcm, AES_TAG(aes), block, WC_AES_BLOCK_SIZE)
 8879#else
 8880/* GHASH one block of data.
 8881 *
 8882 * XOR block into tag and GMULT with H using pre-computed table.
 8883 *
 8884 * @param [in, out] aes    AES GCM object.
 8885 * @param [in]      block  Block of AAD or cipher text.
 8886 */
 8887#define GHASH_ONE_BLOCK_SW(aes, block)                  \
 8888    do {                                                \
 8889        xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \
 8890        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
 8891    }                                                   \
 8892    while (0)
 8893#endif
 8894#endif /* WOLFSSL_AESGCM_STREAM */
 8895#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
 8896
 8897#if !defined(FREESCALE_LTC_AES_GCM)
 8898static void GMULT(word64* X, word64* Y)
 8899{
 8900    word64 Z[2] = {0,0};
 8901    word64 V[2];
 8902    int i, j;
 8903    word64 v1;
 8904    V[0] = X[0];  V[1] = X[1];
 8905
 8906    for (i = 0; i < 2; i++)
 8907    {
 8908        word64 y = Y[i];
 8909        for (j = 0; j < 64; j++)
 8910        {
 8911#ifndef AES_GCM_GMULT_NCT
 8912            word64 mask = 0 - (y >> 63);
 8913            Z[0] ^= V[0] & mask;
 8914            Z[1] ^= V[1] & mask;
 8915#else
 8916            if (y & 0x8000000000000000ULL) {
 8917                Z[0] ^= V[0];
 8918                Z[1] ^= V[1];
 8919            }
 8920#endif
 8921
 8922            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
 8923            V[1] >>= 1;
 8924            V[1] |= V[0] << 63;
 8925            V[0] >>= 1;
 8926            V[0] ^= v1;
 8927            y <<= 1;
 8928        }
 8929    }
 8930    X[0] = Z[0];
 8931    X[1] = Z[1];
 8932}
 8933
 8934
 8935void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
 8936    word32 cSz, byte* s, word32 sSz)
 8937{
 8938    word64 x[2] = {0,0};
 8939    word32 blocks, partial;
 8940    word64 bigH[2];
 8941
 8942    if (gcm == NULL) {
 8943        return;
 8944    }
 8945
 8946    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
 8947    #ifdef LITTLE_ENDIAN_ORDER
 8948        ByteReverseWords64(bigH, bigH, WC_AES_BLOCK_SIZE);
 8949    #endif
 8950
 8951    /* Hash in A, the Additional Authentication Data */
 8952    if (aSz != 0 && a != NULL) {
 8953        word64 bigA[2];
 8954        blocks = aSz / WC_AES_BLOCK_SIZE;
 8955        partial = aSz % WC_AES_BLOCK_SIZE;
 8956        while (blocks--) {
 8957            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
 8958            #ifdef LITTLE_ENDIAN_ORDER
 8959                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
 8960            #endif
 8961            x[0] ^= bigA[0];
 8962            x[1] ^= bigA[1];
 8963            GMULT(x, bigH);
 8964            a += WC_AES_BLOCK_SIZE;
 8965        }
 8966        if (partial != 0) {
 8967            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
 8968            XMEMCPY(bigA, a, partial);
 8969            #ifdef LITTLE_ENDIAN_ORDER
 8970                ByteReverseWords64(bigA, bigA, WC_AES_BLOCK_SIZE);
 8971            #endif
 8972            x[0] ^= bigA[0];
 8973            x[1] ^= bigA[1];
 8974            GMULT(x, bigH);
 8975        }
 8976#ifdef OPENSSL_EXTRA
 8977        /* store AAD partial tag for next call */
 8978        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
 8979        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
 8980        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
 8981        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
 8982#endif
 8983    }
 8984
 8985    /* Hash in C, the Ciphertext */
 8986    if (cSz != 0 && c != NULL) {
 8987        word64 bigC[2];
 8988        blocks = cSz / WC_AES_BLOCK_SIZE;
 8989        partial = cSz % WC_AES_BLOCK_SIZE;
 8990#ifdef OPENSSL_EXTRA
 8991        /* Start from last AAD partial tag */
 8992        if(gcm->aadLen) {
 8993            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
 8994            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
 8995         }
 8996#endif
 8997        while (blocks--) {
 8998            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
 8999            #ifdef LITTLE_ENDIAN_ORDER
 9000                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
 9001            #endif
 9002            x[0] ^= bigC[0];
 9003            x[1] ^= bigC[1];
 9004            GMULT(x, bigH);
 9005            c += WC_AES_BLOCK_SIZE;
 9006        }
 9007        if (partial != 0) {
 9008            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
 9009            XMEMCPY(bigC, c, partial);
 9010            #ifdef LITTLE_ENDIAN_ORDER
 9011                ByteReverseWords64(bigC, bigC, WC_AES_BLOCK_SIZE);
 9012            #endif
 9013            x[0] ^= bigC[0];
 9014            x[1] ^= bigC[1];
 9015            GMULT(x, bigH);
 9016        }
 9017    }
 9018
 9019    /* Hash in the lengths in bits of A and C */
 9020    {
 9021        word64 len[2];
 9022        len[0] = aSz; len[1] = cSz;
 9023#ifdef OPENSSL_EXTRA
 9024        if (gcm->aadLen)
 9025            len[0] = (word64)gcm->aadLen;
 9026#endif
 9027        /* Lengths are in bytes. Convert to bits. */
 9028        len[0] *= 8;
 9029        len[1] *= 8;
 9030
 9031        x[0] ^= len[0];
 9032        x[1] ^= len[1];
 9033        GMULT(x, bigH);
 9034    }
 9035    #ifdef LITTLE_ENDIAN_ORDER
 9036        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);
 9037    #endif
 9038    XMEMCPY(s, x, sSz);
 9039}
 9040#endif /* !FREESCALE_LTC_AES_GCM */
 9041
 9042#ifdef WOLFSSL_AESGCM_STREAM
 9043
 9044#ifdef LITTLE_ENDIAN_ORDER
 9045
 9046/* No extra initialization for small implementation.
 9047 *
 9048 * @param [in] aes  AES GCM object.
 9049 */
 9050#define GHASH_INIT_EXTRA(aes)                                               \
 9051    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, WC_AES_BLOCK_SIZE)
 9052
 9053/* GHASH one block of data..
 9054 *
 9055 * XOR block into tag and GMULT with H.
 9056 *
 9057 * @param [in, out] aes    AES GCM object.
 9058 * @param [in]      block  Block of AAD or cipher text.
 9059 */
 9060#define GHASH_ONE_BLOCK_SW(aes, block)                              \
 9061    do {                                                            \
 9062        word64* x = (word64*)AES_TAG(aes);                          \
 9063        word64* h = (word64*)aes->gcm.H;                            \
 9064        word64 block64[2];                                          \
 9065        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);                 \
 9066        ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE);    \
 9067        x[0] ^= block64[0];                                         \
 9068        x[1] ^= block64[1];                                         \
 9069        GMULT(x, h);                                                \
 9070    }                                                               \
 9071    while (0)
 9072
 9073#ifdef OPENSSL_EXTRA
 9074/* GHASH in AAD and cipher text lengths in bits.
 9075 *
 9076 * Convert tag back to little-endian.
 9077 *
 9078 * @param [in, out] aes  AES GCM object.
 9079 */
 9080#define GHASH_LEN_BLOCK(aes)                            \
 9081    do {                                                \
 9082        word64* x = (word64*)AES_TAG(aes);              \
 9083        word64* h = (word64*)aes->gcm.H;                \
 9084        word64 len[2];                                  \
 9085        len[0] = aes->aSz; len[1] = aes->cSz;           \
 9086        if (aes->gcm.aadLen)                            \
 9087            len[0] = (word64)aes->gcm.aadLen;           \
 9088        /* Lengths are in bytes. Convert to bits. */    \
 9089        len[0] *= 8;                                    \
 9090        len[1] *= 8;                                    \
 9091                                                        \
 9092        x[0] ^= len[0];                                 \
 9093        x[1] ^= len[1];                                 \
 9094        GMULT(x, h);                                    \
 9095        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
 9096    }                                                   \
 9097    while (0)
 9098#else
 9099/* GHASH in AAD and cipher text lengths in bits.
 9100 *
 9101 * Convert tag back to little-endian.
 9102 *
 9103 * @param [in, out] aes  AES GCM object.
 9104 */
 9105#define GHASH_LEN_BLOCK(aes)                            \
 9106    do {                                                \
 9107        word64* x = (word64*)AES_TAG(aes);              \
 9108        word64* h = (word64*)aes->gcm.H;                \
 9109        word64 len[2];                                  \
 9110        len[0] = aes->aSz; len[1] = aes->cSz;           \
 9111        /* Lengths are in bytes. Convert to bits. */    \
 9112        len[0] *= 8;                                    \
 9113        len[1] *= 8;                                    \
 9114                                                        \
 9115        x[0] ^= len[0];                                 \
 9116        x[1] ^= len[1];                                 \
 9117        GMULT(x, h);                                    \
 9118        ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE);    \
 9119    }                                                   \
 9120    while (0)
 9121#endif
 9122
 9123#else
 9124
 9125/* No extra initialization for small implementation.
 9126 *
 9127 * @param [in] aes  AES GCM object.
 9128 */
 9129#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
 9130
 9131/* GHASH one block of data..
 9132 *
 9133 * XOR block into tag and GMULT with H.
 9134 *
 9135 * @param [in, out] aes    AES GCM object.
 9136 * @param [in]      block  Block of AAD or cipher text.
 9137 */
 9138#define GHASH_ONE_BLOCK_SW(aes, block)                  \
 9139    do {                                                \
 9140        word64* x = (word64*)AES_TAG(aes);              \
 9141        word64* h = (word64*)aes->gcm.H;                \
 9142        word64 block64[2];                              \
 9143        XMEMCPY(block64, block, WC_AES_BLOCK_SIZE);        \
 9144        x[0] ^= block64[0];                             \
 9145        x[1] ^= block64[1];                             \
 9146        GMULT(x, h);                                    \
 9147    }                                                   \
 9148    while (0)
 9149
 9150#ifdef OPENSSL_EXTRA
 9151/* GHASH in AAD and cipher text lengths in bits.
 9152 *
 9153 * Convert tag back to little-endian.
 9154 *
 9155 * @param [in, out] aes  AES GCM object.
 9156 */
 9157#define GHASH_LEN_BLOCK(aes)                            \
 9158    do {                                                \
 9159        word64* x = (word64*)AES_TAG(aes);              \
 9160        word64* h = (word64*)aes->gcm.H;                \
 9161        word64 len[2];                                  \
 9162        len[0] = aes->aSz; len[1] = aes->cSz;           \
 9163        if (aes->gcm.aadLen)                            \
 9164            len[0] = (word64)aes->gcm.aadLen;           \
 9165        /* Lengths are in bytes. Convert to bits. */    \
 9166        len[0] *= 8;                                    \
 9167        len[1] *= 8;                                    \
 9168                                                        \
 9169        x[0] ^= len[0];                                 \
 9170        x[1] ^= len[1];                                 \
 9171        GMULT(x, h);                                    \
 9172    }                                                   \
 9173    while (0)
 9174#else
 9175/* GHASH in AAD and cipher text lengths in bits.
 9176 *
 9177 * Convert tag back to little-endian.
 9178 *
 9179 * @param [in, out] aes  AES GCM object.
 9180 */
 9181#define GHASH_LEN_BLOCK(aes)                            \
 9182    do {                                                \
 9183        word64* x = (word64*)AES_TAG(aes);              \
 9184        word64* h = (word64*)aes->gcm.H;                \
 9185        word64 len[2];                                  \
 9186        len[0] = aes->aSz; len[1] = aes->cSz;           \
 9187        /* Lengths are in bytes. Convert to bits. */    \
 9188        len[0] *= 8;                                    \
 9189        len[1] *= 8;                                    \
 9190                                                        \
 9191        x[0] ^= len[0];                                 \
 9192        x[1] ^= len[1];                                 \
 9193        GMULT(x, h);                                    \
 9194    }                                                   \
 9195    while (0)
 9196#endif
 9197
 9198#endif /* !LITTLE_ENDIAN_ORDER */
 9199
 9200#endif /* WOLFSSL_AESGCM_STREAM */
 9201/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
 9202#else /* GCM_WORD32 */
 9203
 9204static void GMULT(word32* X, word32* Y)
 9205{
 9206    word32 Z[4] = {0,0,0,0};
 9207    word32 V[4];
 9208    int i, j;
 9209
 9210    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
 9211
 9212    for (i = 0; i < 4; i++)
 9213    {
 9214        word32 y = Y[i];
 9215        for (j = 0; j < 32; j++)
 9216        {
 9217            if (y & 0x80000000) {
 9218                Z[0] ^= V[0];
 9219                Z[1] ^= V[1];
 9220                Z[2] ^= V[2];
 9221                Z[3] ^= V[3];
 9222            }
 9223
 9224            if (V[3] & 0x00000001) {
 9225                V[3] >>= 1;
 9226                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
 9227                V[2] >>= 1;
 9228                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
 9229                V[1] >>= 1;
 9230                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
 9231                V[0] >>= 1;
 9232                V[0] ^= 0xE1000000;
 9233            } else {
 9234                V[3] >>= 1;
 9235                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
 9236                V[2] >>= 1;
 9237                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
 9238                V[1] >>= 1;
 9239                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
 9240                V[0] >>= 1;
 9241            }
 9242            y <<= 1;
 9243        }
 9244    }
 9245    X[0] = Z[0];
 9246    X[1] = Z[1];
 9247    X[2] = Z[2];
 9248    X[3] = Z[3];
 9249}
 9250
 9251
 9252void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
 9253    word32 cSz, byte* s, word32 sSz)
 9254{
 9255    word32 x[4] = {0,0,0,0};
 9256    word32 blocks, partial;
 9257    word32 bigH[4];
 9258
 9259    if (gcm == NULL) {
 9260        return;
 9261    }
 9262
 9263    XMEMCPY(bigH, gcm->H, WC_AES_BLOCK_SIZE);
 9264    #ifdef LITTLE_ENDIAN_ORDER
 9265        ByteReverseWords(bigH, bigH, WC_AES_BLOCK_SIZE);
 9266    #endif
 9267
 9268    /* Hash in A, the Additional Authentication Data */
 9269    if (aSz != 0 && a != NULL) {
 9270        word32 bigA[4];
 9271        blocks = aSz / WC_AES_BLOCK_SIZE;
 9272        partial = aSz % WC_AES_BLOCK_SIZE;
 9273        while (blocks--) {
 9274            XMEMCPY(bigA, a, WC_AES_BLOCK_SIZE);
 9275            #ifdef LITTLE_ENDIAN_ORDER
 9276                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
 9277            #endif
 9278            x[0] ^= bigA[0];
 9279            x[1] ^= bigA[1];
 9280            x[2] ^= bigA[2];
 9281            x[3] ^= bigA[3];
 9282            GMULT(x, bigH);
 9283            a += WC_AES_BLOCK_SIZE;
 9284        }
 9285        if (partial != 0) {
 9286            XMEMSET(bigA, 0, WC_AES_BLOCK_SIZE);
 9287            XMEMCPY(bigA, a, partial);
 9288            #ifdef LITTLE_ENDIAN_ORDER
 9289                ByteReverseWords(bigA, bigA, WC_AES_BLOCK_SIZE);
 9290            #endif
 9291            x[0] ^= bigA[0];
 9292            x[1] ^= bigA[1];
 9293            x[2] ^= bigA[2];
 9294            x[3] ^= bigA[3];
 9295            GMULT(x, bigH);
 9296        }
 9297    }
 9298
 9299    /* Hash in C, the Ciphertext */
 9300    if (cSz != 0 && c != NULL) {
 9301        word32 bigC[4];
 9302        blocks = cSz / WC_AES_BLOCK_SIZE;
 9303        partial = cSz % WC_AES_BLOCK_SIZE;
 9304        while (blocks--) {
 9305            XMEMCPY(bigC, c, WC_AES_BLOCK_SIZE);
 9306            #ifdef LITTLE_ENDIAN_ORDER
 9307                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
 9308            #endif
 9309            x[0] ^= bigC[0];
 9310            x[1] ^= bigC[1];
 9311            x[2] ^= bigC[2];
 9312            x[3] ^= bigC[3];
 9313            GMULT(x, bigH);
 9314            c += WC_AES_BLOCK_SIZE;
 9315        }
 9316        if (partial != 0) {
 9317            XMEMSET(bigC, 0, WC_AES_BLOCK_SIZE);
 9318            XMEMCPY(bigC, c, partial);
 9319            #ifdef LITTLE_ENDIAN_ORDER
 9320                ByteReverseWords(bigC, bigC, WC_AES_BLOCK_SIZE);
 9321            #endif
 9322            x[0] ^= bigC[0];
 9323            x[1] ^= bigC[1];
 9324            x[2] ^= bigC[2];
 9325            x[3] ^= bigC[3];
 9326            GMULT(x, bigH);
 9327        }
 9328    }
 9329
 9330    /* Hash in the lengths in bits of A and C */
 9331    {
 9332        word32 len[4];
 9333
 9334        /* Lengths are in bytes. Convert to bits. */
 9335        len[0] = (aSz >> (8*sizeof(aSz) - 3));
 9336        len[1] = aSz << 3;
 9337        len[2] = (cSz >> (8*sizeof(cSz) - 3));
 9338        len[3] = cSz << 3;
 9339
 9340        x[0] ^= len[0];
 9341        x[1] ^= len[1];
 9342        x[2] ^= len[2];
 9343        x[3] ^= len[3];
 9344        GMULT(x, bigH);
 9345    }
 9346    #ifdef LITTLE_ENDIAN_ORDER
 9347        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);
 9348    #endif
 9349    XMEMCPY(s, x, sSz);
 9350}
 9351
 9352#ifdef WOLFSSL_AESGCM_STREAM
 9353#ifdef LITTLE_ENDIAN_ORDER
 9354/* Little-endian 32-bit word implementation requires byte reversal of H.
 9355 *
 9356 * H is all-zeros block encrypted with key.
 9357 *
 9358 * @param [in, out] aes  AES GCM object.
 9359 */
 9360#define GHASH_INIT_EXTRA(aes) \
 9361    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, WC_AES_BLOCK_SIZE)
 9362
 9363/* GHASH one block of data..
 9364 *
 9365 * XOR block, in big-endian form, into tag and GMULT with H.
 9366 *
 9367 * @param [in, out] aes    AES GCM object.
 9368 * @param [in]      block  Block of AAD or cipher text.
 9369 */
 9370#define GHASH_ONE_BLOCK_SW(aes, block)                          \
 9371    do {                                                        \
 9372        word32* x = (word32*)AES_TAG(aes);                      \
 9373        word32* h = (word32*)aes->gcm.H;                        \
 9374        word32 bigEnd[4];                                       \
 9375        XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE);              \
 9376        ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE);    \
 9377        x[0] ^= bigEnd[0];                                      \
 9378        x[1] ^= bigEnd[1];                                      \
 9379        x[2] ^= bigEnd[2];                                      \
 9380        x[3] ^= bigEnd[3];                                      \
 9381        GMULT(x, h);                                            \
 9382    }                                                           \
 9383    while (0)
 9384
 9385/* GHASH in AAD and cipher text lengths in bits.
 9386 *
 9387 * Convert tag back to little-endian.
 9388 *
 9389 * @param [in, out] aes  AES GCM object.
 9390 */
 9391#define GHASH_LEN_BLOCK(aes)                                \
 9392    do {                                                    \
 9393        word32 len[4];                                      \
 9394        word32* x = (word32*)AES_TAG(aes);                  \
 9395        word32* h = (word32*)aes->gcm.H;                    \
 9396        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
 9397        len[1] = aes->aSz << 3;                             \
 9398        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
 9399        len[3] = aes->cSz << 3;                             \
 9400        x[0] ^= len[0];                                     \
 9401        x[1] ^= len[1];                                     \
 9402        x[2] ^= len[2];                                     \
 9403        x[3] ^= len[3];                                     \
 9404        GMULT(x, h);                                        \
 9405        ByteReverseWords(x, x, WC_AES_BLOCK_SIZE);          \
 9406    }                                                       \
 9407    while (0)
 9408#else
 9409/* No extra initialization for 32-bit word implementation.
 9410 *
 9411 * @param [in] aes  AES GCM object.
 9412 */
 9413#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
 9414
 9415/* GHASH one block of data..
 9416 *
 9417 * XOR block into tag and GMULT with H.
 9418 *
 9419 * @param [in, out] aes    AES GCM object.
 9420 * @param [in]      block  Block of AAD or cipher text.
 9421 */
 9422#define GHASH_ONE_BLOCK_SW(aes, block)                      \
 9423    do {                                                    \
 9424        word32* x = (word32*)AES_TAG(aes);                  \
 9425        word32* h = (word32*)aes->gcm.H;                    \
 9426        word32 block32[4];                                  \
 9427        XMEMCPY(block32, block, WC_AES_BLOCK_SIZE);         \
 9428        x[0] ^= block32[0];                                 \
 9429        x[1] ^= block32[1];                                 \
 9430        x[2] ^= block32[2];                                 \
 9431        x[3] ^= block32[3];                                 \
 9432        GMULT(x, h);                                        \
 9433    }                                                       \
 9434    while (0)
 9435
 9436/* GHASH in AAD and cipher text lengths in bits.
 9437 *
 9438 * @param [in, out] aes  AES GCM object.
 9439 */
 9440#define GHASH_LEN_BLOCK(aes)                                \
 9441    do {                                                    \
 9442        word32 len[4];                                      \
 9443        word32* x = (word32*)AES_TAG(aes);                  \
 9444        word32* h = (word32*)aes->gcm.H;                    \
 9445        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
 9446        len[1] = aes->aSz << 3;                             \
 9447        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
 9448        len[3] = aes->cSz << 3;                             \
 9449        x[0] ^= len[0];                                     \
 9450        x[1] ^= len[1];                                     \
 9451        x[2] ^= len[2];                                     \
 9452        x[3] ^= len[3];                                     \
 9453        GMULT(x, h);                                        \
 9454    }                                                       \
 9455    while (0)
 9456#endif /* LITTLE_ENDIAN_ORDER */
 9457#endif /* WOLFSSL_AESGCM_STREAM */
 9458#endif /* end GCM_WORD32 */
 9459#endif
 9460
 9461#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
 9462#ifdef WOLFSSL_AESGCM_STREAM
 9463#ifndef GHASH_LEN_BLOCK
 9464/* Hash in the lengths of the AAD and cipher text in bits.
 9465 *
 9466 * Default implementation.
 9467 *
 9468 * @param [in, out] aes  AES GCM object.
 9469 */
 9470#define GHASH_LEN_BLOCK(aes)                      \
 9471    do {                                          \
 9472        byte scratch[WC_AES_BLOCK_SIZE];          \
 9473        FlattenSzInBits(&scratch[0], (aes)->aSz); \
 9474        FlattenSzInBits(&scratch[8], (aes)->cSz); \
 9475        GHASH_ONE_BLOCK(aes, scratch);            \
 9476    }                                             \
 9477    while (0)
 9478#endif
 9479
 9480/* Initialize a GHASH for streaming operations.
 9481 *
 9482 * @param [in, out] aes  AES GCM object.
 9483 */
 9484static void GHASH_INIT(Aes* aes) {
 9485    /* Set tag to all zeros as initial value. */
 9486    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
 9487    /* Reset counts of AAD and cipher text. */
 9488    aes->aOver = 0;
 9489    aes->cOver = 0;
 9490#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
 9491    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
 9492    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
 9493        ; /* Don't do extra initialization. */
 9494    }
 9495    else
 9496#endif
 9497    {
 9498        /* Extra initialization based on implementation. */
 9499        GHASH_INIT_EXTRA(aes);
 9500    }
 9501}
 9502
 9503/* Update the GHASH with AAD and/or cipher text.
 9504 *
 9505 * @param [in,out] aes   AES GCM object.
 9506 * @param [in]     a     Additional authentication data buffer.
 9507 * @param [in]     aSz   Size of data in AAD buffer.
 9508 * @param [in]     c     Cipher text buffer.
 9509 * @param [in]     cSz   Size of data in cipher text buffer.
 9510 */
 9511static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
 9512    word32 cSz)
 9513{
 9514    word32 blocks;
 9515    word32 partial;
 9516
 9517    /* Hash in A, the Additional Authentication Data */
 9518    if (aSz != 0 && a != NULL) {
 9519        /* Update count of AAD we have hashed. */
 9520        aes->aSz += aSz;
 9521        /* Check if we have unprocessed data. */
 9522        if (aes->aOver > 0) {
 9523            /* Calculate amount we can use - fill up the block. */
 9524            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
 9525            if (sz > aSz) {
 9526                sz = (byte)aSz;
 9527            }
 9528            /* Copy extra into last GHASH block array and update count. */
 9529            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
 9530            aes->aOver = (byte)(aes->aOver + sz);
 9531            if (aes->aOver == WC_AES_BLOCK_SIZE) {
 9532                /* We have filled up the block and can process. */
 9533                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
 9534                /* Reset count. */
 9535                aes->aOver = 0;
 9536            }
 9537            /* Used up some data. */
 9538            aSz -= sz;
 9539            a += sz;
 9540        }
 9541
 9542        /* Calculate number of blocks of AAD and the leftover. */
 9543        blocks = aSz / WC_AES_BLOCK_SIZE;
 9544        partial = aSz % WC_AES_BLOCK_SIZE;
 9545        /* GHASH full blocks now. */
 9546        while (blocks--) {
 9547            GHASH_ONE_BLOCK(aes, a);
 9548            a += WC_AES_BLOCK_SIZE;
 9549        }
 9550        if (partial != 0) {
 9551            /* Cache the partial block. */
 9552            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
 9553            aes->aOver = (byte)partial;
 9554        }
 9555    }
 9556    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
 9557        /* No more AAD coming and we have a partial block. */
 9558        /* Fill the rest of the block with zeros. */
 9559        byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
 9560        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
 9561        /* GHASH last AAD block. */
 9562        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
 9563        /* Clear partial count for next time through. */
 9564        aes->aOver = 0;
 9565    }
 9566
 9567    /* Hash in C, the Ciphertext */
 9568    if (cSz != 0 && c != NULL) {
 9569        /* Update count of cipher text we have hashed. */
 9570        aes->cSz += cSz;
 9571        if (aes->cOver > 0) {
 9572            /* Calculate amount we can use - fill up the block. */
 9573            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
 9574            if (sz > cSz) {
 9575                sz = (byte)cSz;
 9576            }
 9577            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
 9578            /* Update count of unused encrypted counter. */
 9579            aes->cOver = (byte)(aes->cOver + sz);
 9580            if (aes->cOver == WC_AES_BLOCK_SIZE) {
 9581                /* We have filled up the block and can process. */
 9582                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
 9583                /* Reset count. */
 9584                aes->cOver = 0;
 9585            }
 9586            /* Used up some data. */
 9587            cSz -= sz;
 9588            c += sz;
 9589        }
 9590
 9591        /* Calculate number of blocks of cipher text and the leftover. */
 9592        blocks = cSz / WC_AES_BLOCK_SIZE;
 9593        partial = cSz % WC_AES_BLOCK_SIZE;
 9594        /* GHASH full blocks now. */
 9595        while (blocks--) {
 9596            GHASH_ONE_BLOCK(aes, c);
 9597            c += WC_AES_BLOCK_SIZE;
 9598        }
 9599        if (partial != 0) {
 9600            /* Cache the partial block. */
 9601            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
 9602            aes->cOver = (byte)partial;
 9603        }
 9604    }
 9605}
 9606
 9607/* Finalize the GHASH calculation.
 9608 *
 9609 * Complete hashing cipher text and hash the AAD and cipher text lengths.
 9610 *
 9611 * @param [in, out] aes  AES GCM object.
 9612 * @param [out]     s    Authentication tag.
 9613 * @param [in]      sSz  Size of authentication tag required.
 9614 */
 9615static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
 9616{
 9617    /* AAD block incomplete when > 0 */
 9618    byte over = aes->aOver;
 9619
 9620    if (aes->cOver > 0) {
 9621        /* Cipher text block incomplete. */
 9622        over = aes->cOver;
 9623    }
 9624    if (over > 0) {
 9625        /* Zeroize the unused part of the block. */
 9626        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
 9627            (size_t)WC_AES_BLOCK_SIZE - over);
 9628        /* Hash the last block of cipher text. */
 9629        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
 9630    }
 9631    /* Hash in the lengths of AAD and cipher text in bits */
 9632    GHASH_LEN_BLOCK(aes);
 9633    /* Copy the result into s. */
 9634    XMEMCPY(s, AES_TAG(aes), sSz);
 9635    /* reset aes->gcm.H in case of reuse */
 9636    GHASH_INIT_EXTRA(aes);
 9637}
 9638#endif /* WOLFSSL_AESGCM_STREAM */
 9639
 9640
 9641#ifdef FREESCALE_LTC_AES_GCM
 9642int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
 9643                   const byte* iv, word32 ivSz,
 9644                   byte* authTag, word32 authTagSz,
 9645                   const byte* authIn, word32 authInSz)
 9646{
 9647    status_t status;
 9648    word32 keySize;
 9649
 9650    /* argument checks */
 9651    if (aes == NULL || authTagSz > WC_AES_BLOCK_SIZE || ivSz == 0) {
 9652        return BAD_FUNC_ARG;
 9653    }
 9654
 9655    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
 9656        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
 9657        return BAD_FUNC_ARG;
 9658    }
 9659
 9660    status = wc_AesGetKeySize(aes, &keySize);
 9661    if (status)
 9662        return status;
 9663
 9664    status = wolfSSL_CryptHwMutexLock();
 9665    if (status != 0)
 9666        return status;
 9667
 9668    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
 9669        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
 9670    wolfSSL_CryptHwMutexUnLock();
 9671
 9672    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
 9673}
 9674
 9675#else
 9676
 9677#ifdef STM32_CRYPTO_AES_GCM
 9678
 9679/* this function supports inline encrypt */
 9680static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
 9681                                  Aes* aes, byte* out, const byte* in, word32 sz,
 9682                                  const byte* iv, word32 ivSz,
 9683                                  byte* authTag, word32 authTagSz,
 9684                                  const byte* authIn, word32 authInSz)
 9685{
 9686    int ret;
 9687#ifdef WOLFSSL_STM32_CUBEMX
 9688    CRYP_HandleTypeDef hcryp;
 9689#else
 9690    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
 9691#endif
 9692    word32 keySize;
 9693#ifdef WOLFSSL_STM32_CUBEMX
 9694    int status = HAL_OK;
 9695    word32 blocks = sz / WC_AES_BLOCK_SIZE;
 9696    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
 9697#else
 9698    int status = SUCCESS;
 9699#endif
 9700    word32 partial = sz % WC_AES_BLOCK_SIZE;
 9701    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
 9702    word32 ctrInit[WC_AES_BLOCK_SIZE/sizeof(word32)];
 9703    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
 9704    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
 9705    byte* authInPadded = NULL;
 9706    int authPadSz, wasAlloc = 0, useSwGhash = 0;
 9707
 9708    ret = wc_AesGetKeySize(aes, &keySize);
 9709    if (ret != 0)
 9710        return ret;
 9711
 9712#ifdef WOLFSSL_STM32_CUBEMX
 9713    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
 9714    if (ret != 0)
 9715        return ret;
 9716#endif
 9717
 9718    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
 9719    if (ivSz == GCM_NONCE_MID_SZ) {
 9720        byte* pCtr = (byte*)ctr;
 9721        XMEMCPY(ctr, iv, ivSz);
 9722        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
 9723    }
 9724    else {
 9725        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
 9726    }
 9727    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
 9728
 9729    /* Authentication buffer */
 9730#if STM_CRYPT_HEADER_WIDTH == 1
 9731    authPadSz = 0; /* CubeHAL supports byte mode */
 9732#else
 9733    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
 9734#endif
 9735#ifdef WOLFSSL_STM32MP13
 9736    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
 9737     * minimum of 16 bytes for the auth */
 9738    if ((authInSz > 0) && (authInSz < 16)) {
 9739        authPadSz = 16 - authInSz;
 9740    }
 9741#endif
 9742    if (authPadSz != 0) {
 9743        if (authPadSz < authInSz + STM_CRYPT_HEADER_WIDTH) {
 9744            authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
 9745        }
 9746        if (authPadSz <= sizeof(authhdr)) {
 9747            authInPadded = (byte*)authhdr;
 9748        }
 9749        else {
 9750            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
 9751                DYNAMIC_TYPE_TMP_BUFFER);
 9752            if (authInPadded == NULL) {
 9753                wolfSSL_CryptHwMutexUnLock();
 9754                return MEMORY_E;
 9755            }
 9756            wasAlloc = 1;
 9757        }
 9758        XMEMSET(authInPadded, 0, authPadSz);
 9759        XMEMCPY(authInPadded, authIn, authInSz);
 9760    } else {
 9761        authPadSz = authInSz;
 9762        authInPadded = (byte*)authIn;
 9763    }
 9764
 9765    /* for cases where hardware cannot be used for authTag calculate it */
 9766    /* if IV is not 12 calculate GHASH using software */
 9767    if (ivSz != GCM_NONCE_MID_SZ
 9768    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
 9769        /* or hardware that does not support partial block */
 9770        || sz == 0 || partial != 0
 9771    #endif
 9772    #if STM_CRYPT_HEADER_WIDTH == 4
 9773        /* or authIn is not a multiple of 4  */
 9774        || authPadSz != authInSz
 9775    #endif
 9776    ) {
 9777        useSwGhash = 1;
 9778    }
 9779
 9780    /* Hardware requires counter + 1 */
 9781    IncrementGcmCounter((byte*)ctr);
 9782
 9783    ret = wolfSSL_CryptHwMutexLock();
 9784    if (ret != 0) {
 9785        return ret;
 9786    }
 9787
 9788#ifdef WOLFSSL_STM32_CUBEMX
 9789    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
 9790    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
 9791
 9792#if defined(STM32_HAL_V2)
 9793    hcryp.Init.Algorithm = CRYP_AES_GCM;
 9794    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
 9795    #ifdef CRYP_KEYIVCONFIG_ONCE
 9796    /* allows repeated calls to HAL_CRYP_Encrypt */
 9797    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
 9798    #endif
 9799    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
 9800    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
 9801    HAL_CRYP_Init(&hcryp);
 9802
 9803    #ifndef CRYP_KEYIVCONFIG_ONCE
 9804    /* GCM payload phase - can handle partial blocks */
 9805    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
 9806        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
 9807    #else
 9808    /* GCM payload phase - blocks */
 9809    if (blocks) {
 9810        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
 9811            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
 9812    }
 9813    /* GCM payload phase - partial remainder */
 9814    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
 9815        XMEMSET(partialBlock, 0, sizeof(partialBlock));
 9816        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
 9817        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
 9818            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
 9819        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
 9820    }
 9821    #endif
 9822    if (status == HAL_OK && !useSwGhash) {
 9823        /* Compute the authTag */
 9824        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
 9825            STM32_HAL_TIMEOUT);
 9826    }
 9827#elif defined(STM32_CRYPTO_AES_ONLY)
 9828    /* Set the CRYP parameters */
 9829    hcryp.Init.HeaderSize = authPadSz;
 9830    if (authPadSz == 0)
 9831        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
 9832    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
 9833    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
 9834    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
 9835    HAL_CRYP_Init(&hcryp);
 9836
 9837    /* GCM init phase */
 9838    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
 9839    if (status == HAL_OK) {
 9840        /* GCM header phase */
 9841        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
 9842        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
 9843    }
 9844    if (status == HAL_OK) {
 9845        /* GCM payload phase - blocks */
 9846        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
 9847        if (blocks) {
 9848            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
 9849                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
 9850        }
 9851    }
 9852    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
 9853        /* GCM payload phase - partial remainder */
 9854        XMEMSET(partialBlock, 0, sizeof(partialBlock));
 9855        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
 9856        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
 9857                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
 9858        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
 9859    }
 9860    if (status == HAL_OK && !useSwGhash) {
 9861        /* GCM final phase */
 9862        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
 9863        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
 9864    }
 9865#else
 9866    hcryp.Init.HeaderSize = authPadSz;
 9867    HAL_CRYP_Init(&hcryp);
 9868    if (blocks) {
 9869        /* GCM payload phase - blocks */
 9870        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
 9871            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
 9872    }
 9873    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
 9874        /* GCM payload phase - partial remainder */
 9875        XMEMSET(partialBlock, 0, sizeof(partialBlock));
 9876        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
 9877        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
 9878            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
 9879        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
 9880    }
 9881    if (status == HAL_OK && !useSwGhash) {
 9882        /* Compute the authTag */
 9883        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
 9884    }
 9885#endif
 9886
 9887    if (status != HAL_OK)
 9888        ret = AES_GCM_AUTH_E;
 9889    HAL_CRYP_DeInit(&hcryp);
 9890
 9891#else /* Standard Peripheral Library */
 9892    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
 9893    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
 9894                         (uint8_t*)keyCopy,      keySize * 8,
 9895                         (uint8_t*)in,           sz,
 9896                         (uint8_t*)authInPadded, authInSz,
 9897                         (uint8_t*)out,          (uint8_t*)tag);
 9898    if (status != SUCCESS)
 9899        ret = AES_GCM_AUTH_E;
 9900#endif /* WOLFSSL_STM32_CUBEMX */
 9901    wolfSSL_CryptHwMutexUnLock();
 9902    wc_Stm32_Aes_Cleanup();
 9903
 9904    if (ret == 0) {
 9905        /* return authTag */
 9906        if (authTag) {
 9907            if (useSwGhash) {
 9908                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
 9909                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
 9910                if (ret == 0) {
 9911                    xorbuf(authTag, tag, authTagSz);
 9912                }
 9913            }
 9914            else {
 9915                /* use hardware calculated tag */
 9916                XMEMCPY(authTag, tag, authTagSz);
 9917            }
 9918        }
 9919    }
 9920
 9921    /* Free memory */
 9922    if (wasAlloc) {
 9923        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
 9924    }
 9925
 9926    return ret;
 9927}
 9928
 9929#endif /* STM32_CRYPTO_AES_GCM */
 9930
 9931#if !defined(WOLFSSL_ARMASM)
 9932#ifdef WOLFSSL_AESNI
 9933/* For performance reasons, this code needs to be not inlined. */
 9934WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
 9935                      Aes* aes, byte* out, const byte* in, word32 sz,
 9936                      const byte* iv, word32 ivSz,
 9937                      byte* authTag, word32 authTagSz,
 9938                      const byte* authIn, word32 authInSz);
 9939#else
 9940static
 9941#endif
 9942WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
 9943                      Aes* aes, byte* out, const byte* in, word32 sz,
 9944                      const byte* iv, word32 ivSz,
 9945                      byte* authTag, word32 authTagSz,
 9946                      const byte* authIn, word32 authInSz)
 9947{
 9948    int ret = 0;
 9949    word32 blocks = sz / WC_AES_BLOCK_SIZE;
 9950    word32 partial = sz % WC_AES_BLOCK_SIZE;
 9951    const byte* p = in;
 9952    byte* c = out;
 9953    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
 9954    ALIGN16 byte initialCounter[WC_AES_BLOCK_SIZE];
 9955    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
 9956#ifdef WC_AES_HAVE_PREFETCH_ARG
 9957    int did_prefetches = 0;
 9958#endif
 9959
 9960    if (ivSz == GCM_NONCE_MID_SZ) {
 9961        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
 9962        XMEMCPY(counter, iv, ivSz);
 9963        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
 9964                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
 9965        counter[WC_AES_BLOCK_SIZE - 1] = 1;
 9966    }
 9967    else {
 9968        /* Counter is GHASH of IV. */
 9969#ifdef OPENSSL_EXTRA
 9970        word32 aadTemp = aes->gcm.aadLen;
 9971        aes->gcm.aadLen = 0;
 9972#endif
 9973        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
 9974#ifdef OPENSSL_EXTRA
 9975        aes->gcm.aadLen = aadTemp;
 9976#endif
 9977    }
 9978    XMEMCPY(initialCounter, counter, WC_AES_BLOCK_SIZE);
 9979
 9980#ifdef WOLFSSL_PIC32MZ_CRYPT
 9981    if (blocks) {
 9982        /* use initial IV for HW, but don't use it below */
 9983        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
 9984
 9985        ret = wc_Pic32AesCrypt(
 9986            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
 9987            out, in, (blocks * WC_AES_BLOCK_SIZE),
 9988            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
 9989        if (ret != 0)
 9990            return ret;
 9991    }
 9992    /* process remainder using partial handling */
 9993#endif
 9994
 9995#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
 9996    /* some hardware acceleration can gain performance from doing AES encryption
 9997     * of the whole buffer at once */
 9998    if (c != p && blocks > 0) { /* can not handle inline encryption */
 9999        while (blocks--) {
10000            IncrementGcmCounter(counter);
10001            XMEMCPY(c, counter, WC_AES_BLOCK_SIZE);
10002            c += WC_AES_BLOCK_SIZE;
10003        }
10004
10005        /* reset number of blocks and then do encryption */
10006        blocks = sz / WC_AES_BLOCK_SIZE;
10007        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
10008        xorbuf(out, p, WC_AES_BLOCK_SIZE * blocks);
10009        p += WC_AES_BLOCK_SIZE * blocks;
10010    }
10011    else
10012#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
10013    {
10014        while (blocks--) {
10015            IncrementGcmCounter(counter);
10016        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
10017            ret = AesEncrypt_preFetchOpt(aes, counter, scratch,
10018                                            &did_prefetches);
10019            if (ret != 0)
10020                return ret;
10021            xorbufout(c, scratch, p, WC_AES_BLOCK_SIZE);
10022        #endif
10023            p += WC_AES_BLOCK_SIZE;
10024            c += WC_AES_BLOCK_SIZE;
10025        }
10026    }
10027
10028    if (partial != 0) {
10029        IncrementGcmCounter(counter);
10030        ret = AesEncrypt_preFetchOpt(aes, counter, scratch, &did_prefetches);
10031        if (ret != 0)
10032            return ret;
10033        xorbufout(c, scratch, p, partial);
10034    }
10035    if (authTag) {
10036        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
10037        ret = AesEncrypt_preFetchOpt(aes, initialCounter, scratch,
10038                                        &did_prefetches);
10039        if (ret != 0)
10040            return ret;
10041        xorbuf(authTag, scratch, authTagSz);
10042#ifdef OPENSSL_EXTRA
10043        if (!in && !sz)
10044            /* store AAD size for next call */
10045            aes->gcm.aadLen = authInSz;
10046#endif
10047    }
10048
10049    return ret;
10050}
10051#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10052static int AES_GCM_encrypt_ARM(Aes* aes, byte* out, const byte* in,
10053    word32 sz, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
10054    const byte* authIn, word32 authInSz)
10055{
10056    word32 blocks;
10057    word32 partial;
10058    byte counter[WC_AES_BLOCK_SIZE];
10059    byte initialCounter[WC_AES_BLOCK_SIZE];
10060    byte x[WC_AES_BLOCK_SIZE];
10061    byte scratch[WC_AES_BLOCK_SIZE];
10062
10063    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
10064    if (ivSz == GCM_NONCE_MID_SZ) {
10065        XMEMCPY(initialCounter, iv, ivSz);
10066        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
10067    }
10068    else {
10069        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
10070    }
10071    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
10072
10073    /* Hash in the Additional Authentication Data */
10074    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
10075    if (authInSz != 0 && authIn != NULL) {
10076        blocks = authInSz / WC_AES_BLOCK_SIZE;
10077        partial = authInSz % WC_AES_BLOCK_SIZE;
10078        if (blocks > 0) {
10079            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
10080            authIn += blocks * WC_AES_BLOCK_SIZE;
10081        }
10082        if (partial != 0) {
10083            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10084            XMEMCPY(scratch, authIn, partial);
10085            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10086        }
10087    }
10088
10089    /* do as many blocks as possible */
10090    blocks = sz / WC_AES_BLOCK_SIZE;
10091    partial = sz % WC_AES_BLOCK_SIZE;
10092    if (blocks > 0) {
10093    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
10094    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10095        if (sz >= 32)
10096    #endif
10097        {
10098            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
10099                (const unsigned char*)aes->key, aes->rounds, counter);
10100        }
10101    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10102        else
10103    #endif
10104    #endif
10105    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10106        {
10107            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
10108                (const unsigned char*)aes->key, aes->rounds, counter);
10109        }
10110    #endif
10111        GCM_GMULT_LEN(&aes->gcm, x, out, blocks * WC_AES_BLOCK_SIZE);
10112        in += blocks * WC_AES_BLOCK_SIZE;
10113        out += blocks * WC_AES_BLOCK_SIZE;
10114    }
10115    /* take care of partial block sizes leftover */
10116    if (partial != 0) {
10117    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10118        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10119        {
10120            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
10121                (const unsigned char*)aes->key, aes->rounds, counter);
10122        }
10123    #else
10124        {
10125            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
10126                (const unsigned char*)aes->key, aes->rounds, counter);
10127        }
10128    #endif
10129        XMEMCPY(out, scratch, partial);
10130
10131        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10132        XMEMCPY(scratch, out, partial);
10133        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10134    }
10135
10136    /* Hash in the lengths of A and C in bits */
10137    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10138    FlattenSzInBits(&scratch[0], authInSz);
10139    FlattenSzInBits(&scratch[8], sz);
10140    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10141    if (authTagSz > WC_AES_BLOCK_SIZE) {
10142        XMEMCPY(authTag, x, WC_AES_BLOCK_SIZE);
10143    }
10144    else {
10145        /* authTagSz can be smaller than WC_AES_BLOCK_SIZE */
10146        XMEMCPY(authTag, x, authTagSz);
10147    }
10148
10149    /* Auth tag calculation. */
10150#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10151    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10152    {
10153        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10154            (const unsigned char*)aes->key, aes->rounds);
10155    }
10156#else
10157    {
10158        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10159            (const unsigned char*)aes->key, aes->rounds);
10160    }
10161#endif
10162    xorbuf(authTag, scratch, authTagSz);
10163
10164    return 0;
10165}
10166#endif
10167
10168/* Software AES - GCM Encrypt */
10169int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10170                   const byte* iv, word32 ivSz,
10171                   byte* authTag, word32 authTagSz,
10172                   const byte* authIn, word32 authInSz)
10173{
10174    int ret;
10175
10176    /* argument checks */
10177    /* If sz is non-zero, both in and out must be set; if sz is 0, in and
10178     * out are don't cares (GMAC case), matching wc_AesGcmDecrypt. */
10179    if (aes == NULL || iv == NULL || ivSz == 0 ||
10180        (sz != 0 && (in == NULL || out == NULL)) ||
10181        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE ||
10182        ((authInSz > 0) && (authIn == NULL)))
10183    {
10184        return BAD_FUNC_ARG;
10185    }
10186
10187    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
10188        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
10189        return BAD_FUNC_ARG;
10190    }
10191
10192#ifdef WOLF_CRYPTO_CB
10193    #ifndef WOLF_CRYPTO_CB_FIND
10194    if (aes->devId != INVALID_DEVID)
10195    #endif
10196    {
10197        int crypto_cb_ret =
10198            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
10199                                      authTagSz, authIn, authInSz);
10200        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
10201            return crypto_cb_ret;
10202        /* fall-through when unavailable */
10203    }
10204#endif
10205
10206#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
10207    /* if async and byte count above threshold */
10208    /* only 12-byte IV is supported in HW */
10209    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
10210                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
10211    #if defined(HAVE_CAVIUM)
10212        #ifdef HAVE_CAVIUM_V
10213        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
10214            return NitroxAesGcmEncrypt(aes, out, in, sz,
10215                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10216                authTag, authTagSz, authIn, authInSz);
10217        }
10218        #endif
10219    #elif defined(HAVE_INTEL_QA)
10220        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
10221            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10222            authTag, authTagSz, authIn, authInSz);
10223    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
10224        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
10225            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
10226            sw->aes.aes = aes;
10227            sw->aes.out = out;
10228            sw->aes.in = in;
10229            sw->aes.sz = sz;
10230            sw->aes.iv = iv;
10231            sw->aes.ivSz = ivSz;
10232            sw->aes.authTag = authTag;
10233            sw->aes.authTagSz = authTagSz;
10234            sw->aes.authIn = authIn;
10235            sw->aes.authInSz = authInSz;
10236            return WC_PENDING_E;
10237        }
10238    #endif
10239    }
10240#endif /* WOLFSSL_ASYNC_CRYPT */
10241
10242#ifdef WOLFSSL_SILABS_SE_ACCEL
10243    return wc_AesGcmEncrypt_silabs(
10244        aes, out, in, sz,
10245        iv, ivSz,
10246        authTag, authTagSz,
10247        authIn, authInSz);
10248#endif
10249#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
10250#ifndef TA_AES_GCM_MAX_DATA_SIZE
10251    #define TA_AES_GCM_MAX_DATA_SIZE 996u
10252#endif
10253    if (aes != NULL &&
10254        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
10255        ivSz == TA_AES_GCM_IV_LENGTH &&
10256        authTagSz == TA_AES_GCM_TAG_LENGTH &&
10257        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
10258        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
10259        return wc_Microchip_AesGcmEncrypt(
10260            aes, out, in, sz,
10261            iv, ivSz,
10262            authTag, authTagSz,
10263            authIn, authInSz);
10264    }
10265#endif
10266#ifdef STM32_CRYPTO_AES_GCM
10267    return wc_AesGcmEncrypt_STM32(
10268        aes, out, in, sz, iv, ivSz,
10269        authTag, authTagSz, authIn, authInSz);
10270#endif /* STM32_CRYPTO_AES_GCM */
10271
10272#if defined(WOLFSSL_PSOC6_CRYPTO)
10273    return wc_Psoc6_Aes_GcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
10274                                   authTagSz, authIn, authInSz);
10275#endif /* WOLFSSL_PSOC6_CRYPTO */
10276
10277    VECTOR_REGISTERS_PUSH;
10278
10279#if defined(WOLFSSL_ARMASM)
10280#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
10281#if !defined(__aarch64__)
10282    AES_GCM_encrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz, authIn,
10283        authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp, (byte*)aes->reg,
10284        aes->rounds);
10285    ret = 0;
10286#else
10287    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
10288    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
10289        if (aes->use_sha3_hw_crypto) {
10290            AES_GCM_encrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
10291                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
10292                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
10293        }
10294        else
10295    #endif
10296        {
10297            AES_GCM_encrypt_AARCH64(in, out, sz, iv, ivSz, authTag, authTagSz,
10298                authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
10299                (byte*)aes->reg, aes->rounds);
10300        }
10301        ret = 0;
10302    }
10303    else
10304#endif /* !__aarch64__ */
10305#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
10306#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10307    {
10308        ret = AES_GCM_encrypt_ARM(aes, out, in, sz, iv, ivSz, authTag,
10309            authTagSz, authIn, authInSz);
10310    }
10311#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
10312#else
10313#ifdef WOLFSSL_AESNI
10314    if (aes->use_aesni) {
10315#ifdef HAVE_INTEL_AVX2
10316        if (IS_INTEL_AVX2(intel_flags)) {
10317            AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10318                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
10319            ret = 0;
10320        }
10321        else
10322#endif
10323#if defined(HAVE_INTEL_AVX1)
10324        if (IS_INTEL_AVX1(intel_flags)) {
10325            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10326                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
10327            ret = 0;
10328        } else
10329#endif
10330        {
10331            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
10332                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
10333            ret = 0;
10334        }
10335    }
10336    else
10337#endif /* WOLFSSL_AESNI */
10338    {
10339        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
10340                                authIn, authInSz);
10341    }
10342#endif
10343
10344    VECTOR_REGISTERS_POP;
10345
10346    return ret;
10347}
10348#endif
10349
10350
10351/* AES GCM Decrypt */
10352#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
10353#ifdef FREESCALE_LTC_AES_GCM
10354int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10355                   const byte* iv, word32 ivSz,
10356                   const byte* authTag, word32 authTagSz,
10357                   const byte* authIn, word32 authInSz)
10358{
10359    int ret;
10360    word32 keySize;
10361    status_t status;
10362
10363    /* argument checks */
10364    /* If the sz is non-zero, both in and out must be set. If sz is 0,
10365     * in and out are don't cares, as this is is the GMAC case. */
10366    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
10367        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE ||
10368        authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ || ivSz == 0 ||
10369        ((authInSz > 0) && (authIn == NULL)))
10370    {
10371        return BAD_FUNC_ARG;
10372    }
10373
10374    ret = wc_AesGetKeySize(aes, &keySize);
10375    if (ret != 0) {
10376        return ret;
10377    }
10378
10379    status = wolfSSL_CryptHwMutexLock();
10380    if (status != 0)
10381        return status;
10382
10383    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
10384        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
10385    wolfSSL_CryptHwMutexUnLock();
10386
10387    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
10388}
10389
10390#else
10391
10392#ifdef STM32_CRYPTO_AES_GCM
10393/* this function supports inline decrypt */
10394static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
10395                                  Aes* aes, byte* out,
10396                                  const byte* in, word32 sz,
10397                                  const byte* iv, word32 ivSz,
10398                                  const byte* authTag, word32 authTagSz,
10399                                  const byte* authIn, word32 authInSz)
10400{
10401    int ret;
10402#ifdef WOLFSSL_STM32_CUBEMX
10403    int status = HAL_OK;
10404    CRYP_HandleTypeDef hcryp;
10405    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10406#else
10407    int status = SUCCESS;
10408    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
10409#endif
10410    word32 keySize;
10411    word32 partial = sz % WC_AES_BLOCK_SIZE;
10412    word32 tag[WC_AES_BLOCK_SIZE/sizeof(word32)];
10413    word32 tagExpected[WC_AES_BLOCK_SIZE/sizeof(word32)];
10414    word32 partialBlock[WC_AES_BLOCK_SIZE/sizeof(word32)];
10415    word32 ctr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10416    word32 authhdr[WC_AES_BLOCK_SIZE/sizeof(word32)];
10417    byte* authInPadded = NULL;
10418    int authPadSz, wasAlloc = 0, tagComputed = 0;
10419
10420    ret = wc_AesGetKeySize(aes, &keySize);
10421    if (ret != 0)
10422        return ret;
10423
10424#ifdef WOLFSSL_STM32_CUBEMX
10425    ret = wc_Stm32_Aes_Init(aes, &hcryp, 0);
10426    if (ret != 0)
10427        return ret;
10428#endif
10429
10430    XMEMSET(ctr, 0, WC_AES_BLOCK_SIZE);
10431    if (ivSz == GCM_NONCE_MID_SZ) {
10432        byte* pCtr = (byte*)ctr;
10433        XMEMCPY(ctr, iv, ivSz);
10434        pCtr[WC_AES_BLOCK_SIZE - 1] = 1;
10435    }
10436    else {
10437        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, WC_AES_BLOCK_SIZE);
10438    }
10439
10440    /* Make copy of expected authTag, which could get corrupted in some
10441     * Cube HAL versions without proper partial block support.
10442     * For TLS blocks the authTag is after the output buffer, so save it */
10443    XMEMCPY(tagExpected, authTag, authTagSz);
10444
10445    /* Authentication buffer */
10446#if STM_CRYPT_HEADER_WIDTH == 1
10447    authPadSz = 0; /* CubeHAL supports byte mode */
10448#else
10449    authPadSz = authInSz % STM_CRYPT_HEADER_WIDTH;
10450#endif
10451#ifdef WOLFSSL_STM32MP13
10452    /* STM32MP13 HAL at least v1.2 and lower has a bug with which it needs a
10453     * minimum of 16 bytes for the auth */
10454    if ((authInSz > 0) && (authInSz < 16)) {
10455        authPadSz = 16 - authInSz;
10456    }
10457#else
10458    if (authPadSz != 0) {
10459        authPadSz = authInSz + STM_CRYPT_HEADER_WIDTH - authPadSz;
10460    }
10461    else {
10462        authPadSz = authInSz;
10463    }
10464#endif
10465
10466    /* for cases where hardware cannot be used for authTag calculate it */
10467    /* if IV is not 12 calculate GHASH using software */
10468    if (ivSz != GCM_NONCE_MID_SZ
10469    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE)
10470        /* or hardware that does not support partial block */
10471        || sz == 0 || partial != 0
10472    #endif
10473    #if STM_CRYPT_HEADER_WIDTH == 4
10474        /* or authIn is not a multiple of 4  */
10475        || authPadSz != authInSz
10476    #endif
10477    ) {
10478        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
10479        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
10480        if (ret != 0)
10481            return ret;
10482        xorbuf(tag, partialBlock, sizeof(tag));
10483        tagComputed = 1;
10484    }
10485
10486    /* if using hardware for authentication tag make sure its aligned and zero padded */
10487    if (authPadSz != authInSz && !tagComputed) {
10488        if (authPadSz <= sizeof(authhdr)) {
10489            authInPadded = (byte*)authhdr;
10490        }
10491        else {
10492            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
10493                DYNAMIC_TYPE_TMP_BUFFER);
10494            if (authInPadded == NULL) {
10495                wolfSSL_CryptHwMutexUnLock();
10496                return MEMORY_E;
10497            }
10498            wasAlloc = 1;
10499        }
10500        XMEMSET(authInPadded, 0, authPadSz);
10501        XMEMCPY(authInPadded, authIn, authInSz);
10502    } else {
10503        authInPadded = (byte*)authIn;
10504    }
10505
10506    /* Hardware requires counter + 1 */
10507    IncrementGcmCounter((byte*)ctr);
10508
10509    ret = wolfSSL_CryptHwMutexLock();
10510    if (ret != 0) {
10511        if (wasAlloc) {
10512            XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
10513        }
10514        return ret;
10515    }
10516
10517#ifdef WOLFSSL_STM32_CUBEMX
10518    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10519    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
10520
10521#if defined(STM32_HAL_V2)
10522    hcryp.Init.Algorithm = CRYP_AES_GCM;
10523    hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH;
10524    #ifdef CRYP_KEYIVCONFIG_ONCE
10525    /* allows repeated calls to HAL_CRYP_Decrypt */
10526    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
10527    #endif
10528    ByteReverseWords(ctr, ctr, WC_AES_BLOCK_SIZE);
10529    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
10530    HAL_CRYP_Init(&hcryp);
10531
10532    #ifndef CRYP_KEYIVCONFIG_ONCE
10533    /* GCM payload phase - can handle partial blocks */
10534    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
10535        (blocks * WC_AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
10536    #else
10537    /* GCM payload phase - blocks */
10538    if (blocks) {
10539        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
10540            (blocks * WC_AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
10541    }
10542    /* GCM payload phase - partial remainder */
10543    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10544        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10545        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10546        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
10547            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
10548        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10549    }
10550    #endif
10551    if (status == HAL_OK && !tagComputed) {
10552        /* Compute the authTag */
10553        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
10554            STM32_HAL_TIMEOUT);
10555    }
10556#elif defined(STM32_CRYPTO_AES_ONLY)
10557    /* Set the CRYP parameters */
10558    hcryp.Init.HeaderSize = authPadSz;
10559    if (authPadSz == 0)
10560        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
10561    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
10562    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
10563    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
10564    HAL_CRYP_Init(&hcryp);
10565
10566    /* GCM init phase */
10567    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10568    if (status == HAL_OK) {
10569        /* GCM header phase */
10570        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
10571        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
10572    }
10573    if (status == HAL_OK) {
10574        /* GCM payload phase - blocks */
10575        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
10576        if (blocks) {
10577            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
10578                (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10579        }
10580    }
10581    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
10582        /* GCM payload phase - partial remainder */
10583        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10584        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10585        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
10586            (byte*)partialBlock, STM32_HAL_TIMEOUT);
10587        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10588    }
10589    if (status == HAL_OK && tagComputed == 0) {
10590        /* GCM final phase */
10591        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
10592        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
10593    }
10594#else
10595    hcryp.Init.HeaderSize = authPadSz;
10596    HAL_CRYP_Init(&hcryp);
10597    if (blocks) {
10598        /* GCM payload phase - blocks */
10599        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
10600            (blocks * WC_AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
10601    }
10602    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
10603        /* GCM payload phase - partial remainder */
10604        XMEMSET(partialBlock, 0, sizeof(partialBlock));
10605        XMEMCPY(partialBlock, in + (blocks * WC_AES_BLOCK_SIZE), partial);
10606        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
10607            (byte*)partialBlock, STM32_HAL_TIMEOUT);
10608        XMEMCPY(out + (blocks * WC_AES_BLOCK_SIZE), partialBlock, partial);
10609    }
10610    if (status == HAL_OK && tagComputed == 0) {
10611        /* Compute the authTag */
10612        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
10613    }
10614#endif
10615
10616    if (status != HAL_OK)
10617        ret = AES_GCM_AUTH_E;
10618
10619    HAL_CRYP_DeInit(&hcryp);
10620
10621#else /* Standard Peripheral Library */
10622    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
10623
10624    /* Input size and auth size need to be the actual sizes, even though
10625     * they are not block aligned, because this length (in bits) is used
10626     * in the final GHASH. */
10627    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
10628    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
10629                         (uint8_t*)keyCopy,      keySize * 8,
10630                         (uint8_t*)in,           sz,
10631                         (uint8_t*)authInPadded, authInSz,
10632                         (uint8_t*)out,          (uint8_t*)partialBlock);
10633    if (status != SUCCESS)
10634        ret = AES_GCM_AUTH_E;
10635    if (tagComputed == 0)
10636        XMEMCPY(tag, partialBlock, authTagSz);
10637#endif /* WOLFSSL_STM32_CUBEMX */
10638    wolfSSL_CryptHwMutexUnLock();
10639    wc_Stm32_Aes_Cleanup();
10640
10641    /* Check authentication tag */
10642    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
10643        ret = AES_GCM_AUTH_E;
10644    }
10645
10646    /* Free memory */
10647    if (wasAlloc) {
10648        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
10649    }
10650
10651    return ret;
10652}
10653
10654#endif /* STM32_CRYPTO_AES_GCM */
10655
10656#if !defined(WOLFSSL_ARMASM)
10657#ifdef WOLFSSL_AESNI
10658/* For performance reasons, this code needs to be not inlined. */
10659int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
10660                      Aes* aes, byte* out, const byte* in, word32 sz,
10661                      const byte* iv, word32 ivSz,
10662                      const byte* authTag, word32 authTagSz,
10663                      const byte* authIn, word32 authInSz);
10664#else
10665static
10666#endif
10667int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
10668                      Aes* aes, byte* out, const byte* in, word32 sz,
10669                      const byte* iv, word32 ivSz,
10670                      const byte* authTag, word32 authTagSz,
10671                      const byte* authIn, word32 authInSz)
10672{
10673    int ret;
10674    word32 blocks = sz / WC_AES_BLOCK_SIZE;
10675    word32 partial = sz % WC_AES_BLOCK_SIZE;
10676    const byte* c = in;
10677    byte* p = out;
10678    ALIGN16 byte counter[WC_AES_BLOCK_SIZE];
10679    ALIGN16 byte scratch[WC_AES_BLOCK_SIZE];
10680    ALIGN16 byte Tprime[WC_AES_BLOCK_SIZE];
10681    ALIGN16 byte EKY0[WC_AES_BLOCK_SIZE];
10682    volatile sword32 res;
10683
10684    if (ivSz == GCM_NONCE_MID_SZ) {
10685        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
10686        XMEMCPY(counter, iv, ivSz);
10687        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
10688                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
10689        counter[WC_AES_BLOCK_SIZE - 1] = 1;
10690    }
10691    else {
10692        /* Counter is GHASH of IV. */
10693#ifdef OPENSSL_EXTRA
10694        word32 aadTemp = aes->gcm.aadLen;
10695        aes->gcm.aadLen = 0;
10696#endif
10697        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
10698#ifdef OPENSSL_EXTRA
10699        aes->gcm.aadLen = aadTemp;
10700#endif
10701    }
10702
10703    /* Calc the authTag again using received auth data and the cipher text */
10704    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
10705    ret = wc_AesEncrypt(aes, counter, EKY0);
10706    if (ret != 0)
10707        return ret;
10708    xorbuf(Tprime, EKY0, sizeof(Tprime));
10709#ifdef WC_AES_GCM_DEC_AUTH_EARLY
10710    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
10711     * the pairwise bytes in the strings.
10712     */
10713    res = ConstantCompare(authTag, Tprime, authTagSz);
10714    /* convert positive retval from ConstantCompare() to all-1s word, in
10715     * constant time.
10716     */
10717    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
10718    ret = res & AES_GCM_AUTH_E;
10719    if (ret != 0)
10720        return ret;
10721#endif
10722
10723#ifdef OPENSSL_EXTRA
10724    if (!out) {
10725        /* authenticated, non-confidential data */
10726        /* store AAD size for next call */
10727        aes->gcm.aadLen = authInSz;
10728    }
10729#endif
10730
10731#if defined(WOLFSSL_PIC32MZ_CRYPT)
10732    if (blocks) {
10733        /* use initial IV for HW, but don't use it below */
10734        XMEMCPY(aes->reg, counter, WC_AES_BLOCK_SIZE);
10735
10736        ret = wc_Pic32AesCrypt(
10737            aes->key, aes->keylen, aes->reg, WC_AES_BLOCK_SIZE,
10738            out, in, (blocks * WC_AES_BLOCK_SIZE),
10739            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
10740        if (ret != 0)
10741            return ret;
10742    }
10743    /* process remainder using partial handling */
10744#endif
10745
10746#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
10747    /* some hardware acceleration can gain performance from doing AES encryption
10748     * of the whole buffer at once */
10749    if (c != p && blocks > 0) { /* can not handle inline decryption */
10750        while (blocks--) {
10751            IncrementGcmCounter(counter);
10752            XMEMCPY(p, counter, WC_AES_BLOCK_SIZE);
10753            p += WC_AES_BLOCK_SIZE;
10754        }
10755
10756        /* reset number of blocks and then do encryption */
10757        blocks = sz / WC_AES_BLOCK_SIZE;
10758
10759        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
10760        xorbuf(out, c, WC_AES_BLOCK_SIZE * blocks);
10761        c += WC_AES_BLOCK_SIZE * blocks;
10762    }
10763    else
10764#endif /* HAVE_AES_ECB && !PIC32MZ */
10765    {
10766        while (blocks--) {
10767            IncrementGcmCounter(counter);
10768        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
10769            ret = wc_AesEncrypt(aes, counter, scratch);
10770            if (ret != 0)
10771                return ret;
10772            xorbufout(p, scratch, c, WC_AES_BLOCK_SIZE);
10773        #endif
10774            p += WC_AES_BLOCK_SIZE;
10775            c += WC_AES_BLOCK_SIZE;
10776        }
10777    }
10778
10779    if (partial != 0) {
10780        IncrementGcmCounter(counter);
10781        ret = wc_AesEncrypt(aes, counter, scratch);
10782        if (ret != 0)
10783            return ret;
10784        xorbuf(scratch, c, partial);
10785        XMEMCPY(p, scratch, partial);
10786    }
10787
10788#ifndef WC_AES_GCM_DEC_AUTH_EARLY
10789    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
10790     * the pairwise bytes in the strings.
10791     */
10792    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
10793    /* convert positive retval from ConstantCompare() to all-1s word, in
10794     * constant time.
10795     */
10796    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
10797    /* now use res as a mask for constant time return of ret, unless tag
10798     * mismatch, whereupon AES_GCM_AUTH_E is returned.
10799     */
10800    ret = (ret & ~res);
10801    ret |= (res & WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
10802#endif
10803    return ret;
10804}
10805#elif defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
10806static int AES_GCM_decrypt_ARM(Aes* aes, byte* out, const byte* in,
10807    word32 sz, const byte* iv, word32 ivSz, const byte* authTag,
10808    word32 authTagSz, const byte* authIn, word32 authInSz)
10809{
10810    word32 blocks;
10811    word32 partial;
10812    byte counter[WC_AES_BLOCK_SIZE];
10813    byte initialCounter[WC_AES_BLOCK_SIZE];
10814    byte scratch[WC_AES_BLOCK_SIZE];
10815    byte x[WC_AES_BLOCK_SIZE];
10816
10817    XMEMSET(initialCounter, 0, WC_AES_BLOCK_SIZE);
10818    if (ivSz == GCM_NONCE_MID_SZ) {
10819        XMEMCPY(initialCounter, iv, ivSz);
10820        initialCounter[WC_AES_BLOCK_SIZE - 1] = 1;
10821    }
10822    else {
10823        GHASH(&aes->gcm, NULL, 0, iv, ivSz, initialCounter, WC_AES_BLOCK_SIZE);
10824    }
10825    XMEMCPY(counter, initialCounter, WC_AES_BLOCK_SIZE);
10826
10827    XMEMSET(x, 0, WC_AES_BLOCK_SIZE);
10828    /* Hash in the Additional Authentication Data */
10829    if (authInSz != 0 && authIn != NULL) {
10830        blocks = authInSz / WC_AES_BLOCK_SIZE;
10831        partial = authInSz % WC_AES_BLOCK_SIZE;
10832        if (blocks > 0) {
10833            GCM_GMULT_LEN(&aes->gcm, x, authIn, blocks * WC_AES_BLOCK_SIZE);
10834            authIn += blocks * WC_AES_BLOCK_SIZE;
10835        }
10836        if (partial != 0) {
10837            XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10838            XMEMCPY(scratch, authIn, partial);
10839            GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10840        }
10841    }
10842
10843    blocks = sz / WC_AES_BLOCK_SIZE;
10844    partial = sz % WC_AES_BLOCK_SIZE;
10845    /* do as many blocks as possible */
10846    if (blocks > 0) {
10847        GCM_GMULT_LEN(&aes->gcm, x, in, blocks * WC_AES_BLOCK_SIZE);
10848
10849    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
10850    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10851        if (sz >= 32)
10852    #endif
10853        {
10854            AES_GCM_encrypt_NEON(in, out, blocks * WC_AES_BLOCK_SIZE,
10855                (const unsigned char*)aes->key, aes->rounds, counter);
10856        }
10857    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10858        else
10859    #endif
10860    #endif
10861    #ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
10862        {
10863            AES_GCM_encrypt(in, out, blocks * WC_AES_BLOCK_SIZE,
10864                (const unsigned char*)aes->key, aes->rounds, counter);
10865        }
10866    #endif
10867        in += blocks * WC_AES_BLOCK_SIZE;
10868        out += blocks * WC_AES_BLOCK_SIZE;
10869    }
10870    if (partial != 0) {
10871        XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10872        XMEMCPY(scratch, in, partial);
10873        GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10874
10875    #if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10876        defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10877        {
10878            AES_GCM_encrypt_NEON(in, scratch, WC_AES_BLOCK_SIZE,
10879                (const unsigned char*)aes->key, aes->rounds, counter);
10880        }
10881    #else
10882        {
10883            AES_GCM_encrypt(in, scratch, WC_AES_BLOCK_SIZE,
10884                (const unsigned char*)aes->key, aes->rounds, counter);
10885        }
10886    #endif
10887        XMEMCPY(out, scratch, partial);
10888    }
10889
10890    XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE);
10891    FlattenSzInBits(&scratch[0], authInSz);
10892    FlattenSzInBits(&scratch[8], sz);
10893    GCM_GMULT_LEN(&aes->gcm, x, scratch, WC_AES_BLOCK_SIZE);
10894#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
10895    defined(WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP)
10896    {
10897        AES_ECB_encrypt_NEON(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10898            (const unsigned char*)aes->key, aes->rounds);
10899    }
10900#else
10901    {
10902        AES_ECB_encrypt(initialCounter, scratch, WC_AES_BLOCK_SIZE,
10903            (const unsigned char*)aes->key, aes->rounds);
10904    }
10905#endif
10906    xorbuf(x, scratch, authTagSz);
10907    if (authTag != NULL) {
10908        if (ConstantCompare(authTag, x, authTagSz) != 0) {
10909            return AES_GCM_AUTH_E;
10910        }
10911    }
10912
10913    return 0;
10914}
10915#endif
10916
10917/* Software AES - GCM Decrypt */
10918int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
10919                     const byte* iv, word32 ivSz,
10920                     const byte* authTag, word32 authTagSz,
10921                     const byte* authIn, word32 authInSz)
10922{
10923    int ret;
10924#ifdef WOLFSSL_AESNI
10925    int res = WC_NO_ERR_TRACE(AES_GCM_AUTH_E);
10926#endif
10927
10928    /* argument checks */
10929    /* If the sz is non-zero, both in and out must be set. If sz is 0,
10930     * in and out are don't cares, as this is is the GMAC case. */
10931    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
10932        authTag == NULL || authTagSz > WC_AES_BLOCK_SIZE ||
10933        authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ || ivSz == 0) {
10934
10935        return BAD_FUNC_ARG;
10936    }
10937
10938#ifdef WOLF_CRYPTO_CB
10939    #ifndef WOLF_CRYPTO_CB_FIND
10940    if (aes->devId != INVALID_DEVID)
10941    #endif
10942    {
10943        int crypto_cb_ret =
10944            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
10945                                      authTag, authTagSz, authIn, authInSz);
10946        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
10947            return crypto_cb_ret;
10948        /* fall-through when unavailable */
10949    }
10950#endif
10951
10952#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
10953    /* if async and byte count above threshold */
10954    /* only 12-byte IV is supported in HW */
10955    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
10956                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
10957    #if defined(HAVE_CAVIUM)
10958        #ifdef HAVE_CAVIUM_V
10959        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
10960            return NitroxAesGcmDecrypt(aes, out, in, sz,
10961                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10962                authTag, authTagSz, authIn, authInSz);
10963        }
10964        #endif
10965    #elif defined(HAVE_INTEL_QA)
10966        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
10967            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
10968            authTag, authTagSz, authIn, authInSz);
10969    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
10970        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
10971            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
10972            sw->aes.aes = aes;
10973            sw->aes.out = out;
10974            sw->aes.in = in;
10975            sw->aes.sz = sz;
10976            sw->aes.iv = iv;
10977            sw->aes.ivSz = ivSz;
10978            sw->aes.authTag = (byte*)authTag;
10979            sw->aes.authTagSz = authTagSz;
10980            sw->aes.authIn = authIn;
10981            sw->aes.authInSz = authInSz;
10982            return WC_PENDING_E;
10983        }
10984    #endif
10985    }
10986#endif /* WOLFSSL_ASYNC_CRYPT */
10987
10988#ifdef WOLFSSL_SILABS_SE_ACCEL
10989    return wc_AesGcmDecrypt_silabs(
10990        aes, out, in, sz, iv, ivSz,
10991        authTag, authTagSz, authIn, authInSz);
10992
10993#endif
10994#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
10995#ifndef TA_AES_GCM_MAX_DATA_SIZE
10996    #define TA_AES_GCM_MAX_DATA_SIZE 996u
10997#endif
10998    if (aes != NULL &&
10999        aes->keylen == TA_KEY_TYPE_AES128_SIZE &&
11000        ivSz == TA_AES_GCM_IV_LENGTH &&
11001        authTagSz == TA_AES_GCM_TAG_LENGTH &&
11002        sz <= TA_AES_GCM_MAX_DATA_SIZE &&
11003        authInSz <= (word32)(TA_AES_GCM_MAX_DATA_SIZE - sz)) {
11004        return wc_Microchip_AesGcmDecrypt(
11005            aes, out, in, sz, iv, ivSz,
11006            authTag, authTagSz, authIn, authInSz);
11007    }
11008#endif
11009
11010#ifdef STM32_CRYPTO_AES_GCM
11011    /* The STM standard peripheral library API's doesn't support partial blocks */
11012    return wc_AesGcmDecrypt_STM32(
11013        aes, out, in, sz, iv, ivSz,
11014        authTag, authTagSz, authIn, authInSz);
11015#endif /* STM32_CRYPTO_AES_GCM */
11016
11017#if defined(WOLFSSL_PSOC6_CRYPTO)
11018    return wc_Psoc6_Aes_GcmDecrypt(aes, out, in, sz, iv, ivSz, authTag,
11019                                   authTagSz, authIn, authInSz);
11020#endif /* WOLFSSL_PSOC6_CRYPTO */
11021
11022    VECTOR_REGISTERS_PUSH;
11023
11024#if defined(WOLFSSL_ARMASM)
11025#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
11026#ifndef __aarch64__
11027    {
11028    #ifdef OPENSSL_EXTRA
11029        word32 reg[WC_AES_BLOCK_SIZE / sizeof(word32)];
11030        XMEMCPY(reg, aes->reg, sizeof(reg));
11031    #endif
11032        ret = AES_GCM_decrypt_AARCH32(in, out, sz, iv, ivSz, authTag, authTagSz,
11033            authIn, authInSz, (byte*)aes->key, aes->gcm.H, (byte*)aes->tmp,
11034            (byte*)aes->reg, aes->rounds);
11035    #ifdef OPENSSL_EXTRA
11036        XMEMCPY(aes->reg, reg, sizeof(reg));
11037    #endif
11038    }
11039#else
11040    if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
11041    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11042        if (aes->use_sha3_hw_crypto) {
11043            ret = AES_GCM_decrypt_AARCH64_EOR3(in, out, sz, iv, ivSz, authTag,
11044                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11045                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
11046        }
11047        else
11048    #endif
11049        {
11050            ret = AES_GCM_decrypt_AARCH64(in, out, sz, iv, ivSz, authTag,
11051                authTagSz, authIn, authInSz, (byte*)aes->key, aes->gcm.H,
11052                (byte*)aes->tmp, (byte*)aes->reg, aes->rounds);
11053        }
11054    }
11055    else
11056#endif /* !__aarch64__ */
11057#endif /* !WOLFSSL_ARMASM_NO_HW_CRYPTO */
11058#if defined(__aarch64__) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11059    {
11060        ret = AES_GCM_decrypt_ARM(aes, out, in, sz, iv, ivSz, authTag,
11061            authTagSz, authIn, authInSz);
11062    }
11063#endif /* __aarch64__ || WOLFSSL_ARMASM_NO_HW_CRYPTO */
11064#else
11065#ifdef WOLFSSL_AESNI
11066    if (aes->use_aesni) {
11067#ifdef HAVE_INTEL_AVX2
11068        if (IS_INTEL_AVX2(intel_flags)) {
11069            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11070                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11071            if (res == 0)
11072                ret = AES_GCM_AUTH_E;
11073            else
11074                ret = 0;
11075        }
11076        else
11077#endif
11078#if defined(HAVE_INTEL_AVX1)
11079        if (IS_INTEL_AVX1(intel_flags)) {
11080            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11081                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11082            if (res == 0)
11083                ret = AES_GCM_AUTH_E;
11084            else
11085                ret = 0;
11086        }
11087        else
11088#endif
11089        {
11090            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
11091                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
11092            if (res == 0)
11093                ret = AES_GCM_AUTH_E;
11094            else
11095                ret = 0;
11096        }
11097    }
11098    else
11099#endif /* WOLFSSL_AESNI */
11100    {
11101        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
11102                                                             authIn, authInSz);
11103    }
11104#endif
11105
11106    VECTOR_REGISTERS_POP;
11107
11108    return ret;
11109}
11110#endif
11111#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
11112
11113#ifdef WOLFSSL_AESGCM_STREAM
11114
11115/* Initialize the AES GCM cipher with an IV. C implementation.
11116 *
11117 * @param [in, out] aes   AES object.
11118 * @param [in]      iv    IV/nonce buffer.
11119 * @param [in]      ivSz  Length of IV/nonce data.
11120 */
11121static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
11122{
11123    ALIGN32 byte counter[WC_AES_BLOCK_SIZE];
11124    int ret;
11125
11126    if (ivSz == GCM_NONCE_MID_SZ) {
11127        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
11128        XMEMCPY(counter, iv, ivSz);
11129        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
11130                                         WC_AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
11131        counter[WC_AES_BLOCK_SIZE - 1] = 1;
11132    }
11133    else {
11134        /* Counter is GHASH of IV. */
11135    #ifdef OPENSSL_EXTRA
11136        word32 aadTemp = aes->gcm.aadLen;
11137        aes->gcm.aadLen = 0;
11138    #endif
11139        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, WC_AES_BLOCK_SIZE);
11140    #ifdef OPENSSL_EXTRA
11141        aes->gcm.aadLen = aadTemp;
11142    #endif
11143    }
11144
11145    /* Copy in the counter for use with cipher. */
11146    XMEMCPY(AES_COUNTER(aes), counter, WC_AES_BLOCK_SIZE);
11147    /* Encrypt initial counter into a buffer for GCM. */
11148    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
11149    if (ret != 0)
11150        return ret;
11151    /* Reset state fields. */
11152    aes->over = 0;
11153    aes->aSz = 0;
11154    aes->cSz = 0;
11155    /* Initialization for GHASH. */
11156    GHASH_INIT(aes);
11157
11158    return 0;
11159}
11160
11161/* Update the AES GCM cipher with data. C implementation.
11162 *
11163 * Only enciphers data.
11164 *
11165 * @param [in, out] aes  AES object.
11166 * @param [in]      out  Cipher text or plaintext buffer.
11167 * @param [in]      in   Plaintext or cipher text buffer.
11168 * @param [in]      sz   Length of data.
11169 */
11170static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
11171    Aes* aes, byte* out, const byte* in, word32 sz)
11172{
11173    word32 blocks;
11174    word32 partial;
11175    int ret;
11176
11177    /* Check if previous encrypted block was not used up. */
11178    if (aes->over > 0) {
11179        byte pSz = (byte)(WC_AES_BLOCK_SIZE - aes->over);
11180        if (pSz > sz) pSz = (byte)sz;
11181
11182        /* Use some/all of last encrypted block. */
11183        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
11184        aes->over = (aes->over + pSz) & (WC_AES_BLOCK_SIZE - 1);
11185
11186        /* Some data used. */
11187        sz  -= pSz;
11188        in  += pSz;
11189        out += pSz;
11190    }
11191
11192    /* Calculate the number of blocks needing to be encrypted and any leftover.
11193     */
11194    blocks  = sz / WC_AES_BLOCK_SIZE;
11195    partial = sz & (WC_AES_BLOCK_SIZE - 1);
11196
11197#if defined(HAVE_AES_ECB)
11198    /* Some hardware acceleration can gain performance from doing AES encryption
11199     * of the whole buffer at once.
11200     * Overwrites the cipher text before using plaintext - no inline encryption.
11201     */
11202    if ((out != in) && blocks > 0) {
11203        word32 b;
11204        /* Place incrementing counter blocks into cipher text. */
11205        for (b = 0; b < blocks; b++) {
11206            IncrementGcmCounter(AES_COUNTER(aes));
11207            XMEMCPY(out + b * WC_AES_BLOCK_SIZE, AES_COUNTER(aes), WC_AES_BLOCK_SIZE);
11208        }
11209
11210        /* Encrypt counter blocks. */
11211        wc_AesEcbEncrypt(aes, out, out, WC_AES_BLOCK_SIZE * blocks);
11212        /* XOR in plaintext. */
11213        xorbuf(out, in, WC_AES_BLOCK_SIZE * blocks);
11214        /* Skip over processed data. */
11215        in += WC_AES_BLOCK_SIZE * blocks;
11216        out += WC_AES_BLOCK_SIZE * blocks;
11217    }
11218    else
11219#endif /* HAVE_AES_ECB */
11220    {
11221        /* Encrypt block by block. */
11222        while (blocks--) {
11223            ALIGN32 byte scratch[WC_AES_BLOCK_SIZE];
11224            IncrementGcmCounter(AES_COUNTER(aes));
11225            /* Encrypt counter into a buffer. */
11226            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
11227            if (ret != 0)
11228                return ret;
11229            /* XOR plain text into encrypted counter into cipher text buffer. */
11230            xorbufout(out, scratch, in, WC_AES_BLOCK_SIZE);
11231            /* Data complete. */
11232            in  += WC_AES_BLOCK_SIZE;
11233            out += WC_AES_BLOCK_SIZE;
11234        }
11235    }
11236
11237    if (partial != 0) {
11238        /* Generate an extra block and use up as much as needed. */
11239        IncrementGcmCounter(AES_COUNTER(aes));
11240        /* Encrypt counter into cache. */
11241        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
11242        if (ret != 0)
11243            return ret;
11244        /* XOR plain text into encrypted counter into cipher text buffer. */
11245        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
11246        /* Keep amount of encrypted block used. */
11247        aes->over = (byte)partial;
11248    }
11249
11250    return 0;
11251}
11252
11253/* Calculates authentication tag for AES GCM. C implementation.
11254 *
11255 * @param [in, out] aes        AES object.
11256 * @param [out]     authTag    Buffer to store authentication tag in.
11257 * @param [in]      authTagSz  Length of tag to create.
11258 */
11259static WARN_UNUSED_RESULT int AesGcmFinal_C(
11260    Aes* aes, byte* authTag, word32 authTagSz)
11261{
11262    /* Calculate authentication tag. */
11263    GHASH_FINAL(aes, authTag, authTagSz);
11264    /* XOR in as much of encrypted counter as is required. */
11265    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
11266#ifdef OPENSSL_EXTRA
11267    /* store AAD size for next call */
11268    aes->gcm.aadLen = aes->aSz;
11269#endif
11270    /* Zeroize last block to protect sensitive data. */
11271    ForceZero(AES_LASTBLOCK(aes), WC_AES_BLOCK_SIZE);
11272
11273    return 0;
11274}
11275
11276#ifdef WOLFSSL_AESNI
11277
11278#ifdef __cplusplus
11279    extern "C" {
11280#endif
11281
11282/* Assembly code implementations in: aes_gcm_asm.S */
11283#ifdef HAVE_INTEL_AVX2
11284extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
11285    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
11286    unsigned char* counter, unsigned char* initCtr);
11287extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
11288    unsigned int abytes, unsigned char* tag, unsigned char* h);
11289extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
11290    unsigned char* out, const unsigned char* in, unsigned char* counter);
11291extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
11292    unsigned char* tag, unsigned char* h);
11293
11294extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
11295    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11296    unsigned char* tag, unsigned char* h, unsigned char* counter);
11297extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
11298    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11299    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
11300#endif
11301#ifdef HAVE_INTEL_AVX1
11302extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
11303    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
11304    unsigned char* counter, unsigned char* initCtr);
11305extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
11306    unsigned int abytes, unsigned char* tag, unsigned char* h);
11307extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
11308    unsigned char* out, const unsigned char* in, unsigned char* counter);
11309extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
11310    unsigned char* tag, unsigned char* h);
11311
11312extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
11313    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11314    unsigned char* tag, unsigned char* h, unsigned char* counter);
11315extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
11316    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11317    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
11318#endif
11319extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
11320    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
11321    unsigned char* counter, unsigned char* initCtr);
11322extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
11323    unsigned int abytes, unsigned char* tag, unsigned char* h);
11324extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
11325    unsigned char* out, const unsigned char* in, unsigned char* counter);
11326extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
11327    unsigned char* tag, unsigned char* h);
11328
11329extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
11330    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11331    unsigned char* tag, unsigned char* h, unsigned char* counter);
11332extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
11333    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11334    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
11335
11336#ifdef __cplusplus
11337    } /* extern "C" */
11338#endif
11339
11340/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
11341 *
11342 * @param [in, out] aes   AES object.
11343 * @param [in]      iv    IV/nonce buffer.
11344 * @param [in]      ivSz  Length of IV/nonce data.
11345 */
11346static WARN_UNUSED_RESULT int AesGcmInit_aesni(
11347    Aes* aes, const byte* iv, word32 ivSz)
11348{
11349    ASSERT_SAVED_VECTOR_REGISTERS();
11350
11351    /* Reset state fields. */
11352    aes->over = 0;
11353    aes->aSz = 0;
11354    aes->cSz = 0;
11355    /* Set tag to all zeros as initial value. */
11356    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
11357    /* Reset counts of AAD and cipher text. */
11358    aes->aOver = 0;
11359    aes->cOver = 0;
11360
11361#ifdef HAVE_INTEL_AVX2
11362    if (IS_INTEL_AVX2(intel_flags)) {
11363        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11364            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11365    }
11366    else
11367#endif
11368#ifdef HAVE_INTEL_AVX1
11369    if (IS_INTEL_AVX1(intel_flags)) {
11370        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11371            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11372    }
11373    else
11374#endif
11375    {
11376        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11377            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11378    }
11379
11380    return 0;
11381}
11382
11383/* Update the AES GCM for encryption with authentication data.
11384 *
11385 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
11386 *
11387 * @param [in, out] aes   AES object.
11388 * @param [in]      a     Buffer holding authentication data.
11389 * @param [in]      aSz   Length of authentication data in bytes.
11390 * @param [in]      endA  Whether no more authentication data is expected.
11391 */
11392static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
11393    Aes* aes, const byte* a, word32 aSz, int endA)
11394{
11395    word32 blocks;
11396    int partial;
11397
11398    ASSERT_SAVED_VECTOR_REGISTERS();
11399
11400    if (aSz != 0 && a != NULL) {
11401        /* Total count of AAD updated. */
11402        aes->aSz += aSz;
11403        /* Check if we have unprocessed data. */
11404        if (aes->aOver > 0) {
11405            /* Calculate amount we can use - fill up the block. */
11406            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
11407            if (sz > aSz) {
11408                sz = (byte)aSz;
11409            }
11410            /* Copy extra into last GHASH block array and update count. */
11411            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
11412            aes->aOver = (byte)(aes->aOver + sz);
11413            if (aes->aOver == WC_AES_BLOCK_SIZE) {
11414                /* We have filled up the block and can process. */
11415            #ifdef HAVE_INTEL_AVX2
11416                if (IS_INTEL_AVX2(intel_flags)) {
11417                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11418                                             aes->gcm.H);
11419                }
11420                else
11421            #endif
11422            #ifdef HAVE_INTEL_AVX1
11423                if (IS_INTEL_AVX1(intel_flags)) {
11424                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11425                                             aes->gcm.H);
11426                }
11427                else
11428            #endif
11429                {
11430                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11431                                              aes->gcm.H);
11432                }
11433                /* Reset count. */
11434                aes->aOver = 0;
11435            }
11436            /* Used up some data. */
11437            aSz -= sz;
11438            a += sz;
11439        }
11440
11441        /* Calculate number of blocks of AAD and the leftover. */
11442        blocks = aSz / WC_AES_BLOCK_SIZE;
11443        partial = aSz % WC_AES_BLOCK_SIZE;
11444        if (blocks > 0) {
11445            /* GHASH full blocks now. */
11446        #ifdef HAVE_INTEL_AVX2
11447            if (IS_INTEL_AVX2(intel_flags)) {
11448                AES_GCM_aad_update_avx2(a, blocks * WC_AES_BLOCK_SIZE,
11449                                        AES_TAG(aes), aes->gcm.H);
11450            }
11451            else
11452        #endif
11453        #ifdef HAVE_INTEL_AVX1
11454            if (IS_INTEL_AVX1(intel_flags)) {
11455                AES_GCM_aad_update_avx1(a, blocks * WC_AES_BLOCK_SIZE,
11456                                        AES_TAG(aes), aes->gcm.H);
11457            }
11458            else
11459        #endif
11460            {
11461                AES_GCM_aad_update_aesni(a, blocks * WC_AES_BLOCK_SIZE,
11462                                         AES_TAG(aes), aes->gcm.H);
11463            }
11464            /* Skip over to end of AAD blocks. */
11465            a += blocks * WC_AES_BLOCK_SIZE;
11466        }
11467        if (partial != 0) {
11468            /* Cache the partial block. */
11469            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
11470            aes->aOver = (byte)partial;
11471        }
11472    }
11473    if (endA && (aes->aOver > 0)) {
11474        /* No more AAD coming and we have a partial block. */
11475        /* Fill the rest of the block with zeros. */
11476        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
11477                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
11478        /* GHASH last AAD block. */
11479    #ifdef HAVE_INTEL_AVX2
11480        if (IS_INTEL_AVX2(intel_flags)) {
11481            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11482                                     aes->gcm.H);
11483        }
11484        else
11485    #endif
11486    #ifdef HAVE_INTEL_AVX1
11487        if (IS_INTEL_AVX1(intel_flags)) {
11488            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11489                                     aes->gcm.H);
11490        }
11491        else
11492    #endif
11493        {
11494            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11495                                      aes->gcm.H);
11496        }
11497        /* Clear partial count for next time through. */
11498        aes->aOver = 0;
11499    }
11500
11501    return 0;
11502}
11503
11504/* Update the AES GCM for encryption with data and/or authentication data.
11505 *
11506 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
11507 *
11508 * @param [in, out] aes  AES object.
11509 * @param [out]     c    Buffer to hold cipher text.
11510 * @param [in]      p    Buffer holding plaintext.
11511 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11512 * @param [in]      a    Buffer holding authentication data.
11513 * @param [in]      aSz  Length of authentication data in bytes.
11514 */
11515static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
11516    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
11517{
11518    word32 blocks;
11519    int partial;
11520    int ret;
11521
11522    ASSERT_SAVED_VECTOR_REGISTERS();
11523
11524    /* Hash in A, the Authentication Data */
11525    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
11526    if (ret != 0)
11527        return ret;
11528
11529    /* Encrypt plaintext and Hash in C, the Cipher text */
11530    if (cSz != 0 && c != NULL) {
11531        /* Update count of cipher text we have hashed. */
11532        aes->cSz += cSz;
11533        if (aes->cOver > 0) {
11534            /* Calculate amount we can use - fill up the block. */
11535            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11536            if (sz > cSz) {
11537                sz = (byte)cSz;
11538            }
11539            /* Encrypt some of the plaintext. */
11540            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
11541            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11542            /* Update count of unused encrypted counter. */
11543            aes->cOver = (byte)(aes->cOver + sz);
11544            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11545                /* We have filled up the block and can process. */
11546            #ifdef HAVE_INTEL_AVX2
11547                if (IS_INTEL_AVX2(intel_flags)) {
11548                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11549                                             aes->gcm.H);
11550                }
11551                else
11552            #endif
11553            #ifdef HAVE_INTEL_AVX1
11554                if (IS_INTEL_AVX1(intel_flags)) {
11555                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11556                                             aes->gcm.H);
11557                }
11558                else
11559            #endif
11560                {
11561                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11562                                              aes->gcm.H);
11563                }
11564                /* Reset count. */
11565                aes->cOver = 0;
11566            }
11567            /* Used up some data. */
11568            cSz -= sz;
11569            p += sz;
11570            c += sz;
11571        }
11572
11573        /* Calculate number of blocks of plaintext and the leftover. */
11574        blocks = cSz / WC_AES_BLOCK_SIZE;
11575        partial = cSz % WC_AES_BLOCK_SIZE;
11576        if (blocks > 0) {
11577            /* Encrypt and GHASH full blocks now. */
11578        #ifdef HAVE_INTEL_AVX2
11579            if (IS_INTEL_AVX2(intel_flags)) {
11580                AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
11581                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11582                    AES_COUNTER(aes));
11583            }
11584            else
11585        #endif
11586        #ifdef HAVE_INTEL_AVX1
11587            if (IS_INTEL_AVX1(intel_flags)) {
11588                AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
11589                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11590                    AES_COUNTER(aes));
11591            }
11592            else
11593        #endif
11594            {
11595                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
11596                    c, p, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11597                    AES_COUNTER(aes));
11598            }
11599            /* Skip over to end of blocks. */
11600            p += blocks * WC_AES_BLOCK_SIZE;
11601            c += blocks * WC_AES_BLOCK_SIZE;
11602        }
11603        if (partial != 0) {
11604            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
11605            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11606        #ifdef HAVE_INTEL_AVX2
11607            if (IS_INTEL_AVX2(intel_flags)) {
11608                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
11609                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11610            }
11611            else
11612        #endif
11613        #ifdef HAVE_INTEL_AVX1
11614            if (IS_INTEL_AVX1(intel_flags)) {
11615                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
11616                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11617            }
11618            else
11619        #endif
11620            {
11621                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
11622                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11623            }
11624            /* XOR the remaining plaintext to calculate cipher text.
11625             * Keep cipher text for GHASH of last partial block.
11626             */
11627            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
11628            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
11629            /* Update count of the block used. */
11630            aes->cOver = (byte)partial;
11631        }
11632    }
11633    return 0;
11634}
11635
11636/* Finalize the AES GCM for encryption and calculate the authentication tag.
11637 *
11638 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
11639 *
11640 * @param [in, out] aes        AES object.
11641 * @param [in]      authTag    Buffer to hold authentication tag.
11642 * @param [in]      authTagSz  Length of authentication tag in bytes.
11643 * @return  0 on success.
11644 */
11645static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
11646    Aes* aes, byte* authTag, word32 authTagSz)
11647{
11648    /* AAD block incomplete when > 0 */
11649    byte over = aes->aOver;
11650
11651    ASSERT_SAVED_VECTOR_REGISTERS();
11652
11653    if (aes->cOver > 0) {
11654        /* Cipher text block incomplete. */
11655        over = aes->cOver;
11656    }
11657    if (over > 0) {
11658        /* Fill the rest of the block with zeros. */
11659        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
11660        /* GHASH last cipher block. */
11661    #ifdef HAVE_INTEL_AVX2
11662        if (IS_INTEL_AVX2(intel_flags)) {
11663            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
11664                                     aes->gcm.H);
11665        }
11666        else
11667    #endif
11668    #ifdef HAVE_INTEL_AVX1
11669        if (IS_INTEL_AVX1(intel_flags)) {
11670            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
11671                                     aes->gcm.H);
11672        }
11673        else
11674    #endif
11675        {
11676            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
11677                                      aes->gcm.H);
11678        }
11679    }
11680    /* Calculate the authentication tag. */
11681#ifdef HAVE_INTEL_AVX2
11682    if (IS_INTEL_AVX2(intel_flags)) {
11683        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11684            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11685    }
11686    else
11687#endif
11688#ifdef HAVE_INTEL_AVX1
11689    if (IS_INTEL_AVX1(intel_flags)) {
11690        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11691            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11692    }
11693    else
11694#endif
11695    {
11696        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11697            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
11698    }
11699
11700    return 0;
11701}
11702
11703#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
11704
11705#ifdef __cplusplus
11706    extern "C" {
11707#endif
11708
11709/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
11710#ifdef HAVE_INTEL_AVX2
11711extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
11712    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11713    unsigned char* tag, unsigned char* h, unsigned char* counter);
11714extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
11715    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11716    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
11717#endif
11718#ifdef HAVE_INTEL_AVX1
11719extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
11720    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11721    unsigned char* tag, unsigned char* h, unsigned char* counter);
11722extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
11723    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11724    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
11725#endif
11726extern void AES_GCM_decrypt_update_aesni(const unsigned char* key, int nr,
11727    unsigned char* out, const unsigned char* in, unsigned int nbytes,
11728    unsigned char* tag, unsigned char* h, unsigned char* counter);
11729extern void AES_GCM_decrypt_final_aesni(unsigned char* tag,
11730    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
11731    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
11732
11733#ifdef __cplusplus
11734    } /* extern "C" */
11735#endif
11736
11737/* Update the AES GCM for decryption with data and/or authentication data.
11738 *
11739 * @param [in, out] aes  AES object.
11740 * @param [out]     p    Buffer to hold plaintext.
11741 * @param [in]      c    Buffer holding cipher text.
11742 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
11743 * @param [in]      a    Buffer holding authentication data.
11744 * @param [in]      aSz  Length of authentication data in bytes.
11745 */
11746static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
11747    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
11748{
11749    word32 blocks;
11750    int partial;
11751    int ret;
11752
11753    ASSERT_SAVED_VECTOR_REGISTERS();
11754
11755    /* Hash in A, the Authentication Data */
11756    ret = AesGcmAadUpdate_aesni(aes, a, aSz, cSz > 0);
11757    if (ret != 0)
11758        return ret;
11759
11760    /* Hash in C, the Cipher text, and decrypt. */
11761    if (cSz != 0 && p != NULL) {
11762        /* Update count of cipher text we have hashed. */
11763        aes->cSz += cSz;
11764        if (aes->cOver > 0) {
11765            /* Calculate amount we can use - fill up the block. */
11766            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
11767            if (sz > cSz) {
11768                sz = (byte)cSz;
11769            }
11770            /* Keep a copy of the cipher text for GHASH. */
11771            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
11772            /* Decrypt some of the cipher text. */
11773            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
11774            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
11775            /* Update count of unused encrypted counter. */
11776            aes->cOver = (byte)(aes->cOver + sz);
11777            if (aes->cOver == WC_AES_BLOCK_SIZE) {
11778                /* We have filled up the block and can process. */
11779            #ifdef HAVE_INTEL_AVX2
11780                if (IS_INTEL_AVX2(intel_flags)) {
11781                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
11782                                             aes->gcm.H);
11783                }
11784                else
11785            #endif
11786            #ifdef HAVE_INTEL_AVX1
11787                if (IS_INTEL_AVX1(intel_flags)) {
11788                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
11789                                             aes->gcm.H);
11790                }
11791                else
11792            #endif
11793                {
11794                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
11795                                              aes->gcm.H);
11796                }
11797                /* Reset count. */
11798                aes->cOver = 0;
11799            }
11800            /* Used up some data. */
11801            cSz -= sz;
11802            c += sz;
11803            p += sz;
11804        }
11805
11806        /* Calculate number of blocks of plaintext and the leftover. */
11807        blocks = cSz / WC_AES_BLOCK_SIZE;
11808        partial = cSz % WC_AES_BLOCK_SIZE;
11809        if (blocks > 0) {
11810            /* Decrypt and GHASH full blocks now. */
11811        #ifdef HAVE_INTEL_AVX2
11812            if (IS_INTEL_AVX2(intel_flags)) {
11813                AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
11814                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11815                    AES_COUNTER(aes));
11816            }
11817            else
11818        #endif
11819        #ifdef HAVE_INTEL_AVX1
11820            if (IS_INTEL_AVX1(intel_flags)) {
11821                AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
11822                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11823                    AES_COUNTER(aes));
11824            }
11825            else
11826        #endif
11827            {
11828                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
11829                    p, c, blocks * WC_AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
11830                    AES_COUNTER(aes));
11831            }
11832            /* Skip over to end of blocks. */
11833            c += blocks * WC_AES_BLOCK_SIZE;
11834            p += blocks * WC_AES_BLOCK_SIZE;
11835        }
11836        if (partial != 0) {
11837            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
11838            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
11839        #ifdef HAVE_INTEL_AVX2
11840            if (IS_INTEL_AVX2(intel_flags)) {
11841                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
11842                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11843            }
11844            else
11845        #endif
11846        #ifdef HAVE_INTEL_AVX1
11847            if (IS_INTEL_AVX1(intel_flags)) {
11848                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
11849                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11850            }
11851            else
11852        #endif
11853            {
11854                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
11855                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
11856            }
11857            /* Keep cipher text for GHASH of last partial block. */
11858            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
11859            /* XOR the remaining cipher text to calculate plaintext. */
11860            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
11861            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
11862            /* Update count of the block used. */
11863            aes->cOver = (byte)partial;
11864        }
11865    }
11866
11867    return 0;
11868}
11869
11870/* Finalize the AES GCM for decryption and check the authentication tag.
11871 *
11872 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
11873 *
11874 * @param [in, out] aes        AES object.
11875 * @param [in]      authTag    Buffer holding authentication tag.
11876 * @param [in]      authTagSz  Length of authentication tag in bytes.
11877 * @return  0 on success.
11878 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
11879 *          value.
11880 */
11881static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
11882    Aes* aes, const byte* authTag, word32 authTagSz)
11883{
11884    int ret = 0;
11885    int res;
11886    /* AAD block incomplete when > 0 */
11887    byte over = aes->aOver;
11888    byte *lastBlock = AES_LASTGBLOCK(aes);
11889
11890    ASSERT_SAVED_VECTOR_REGISTERS();
11891
11892    if (aes->cOver > 0) {
11893        /* Cipher text block incomplete. */
11894        over = aes->cOver;
11895        lastBlock = AES_LASTBLOCK(aes);
11896    }
11897    if (over > 0) {
11898        /* Zeroize the unused part of the block. */
11899        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
11900        /* Hash the last block of cipher text. */
11901    #ifdef HAVE_INTEL_AVX2
11902        if (IS_INTEL_AVX2(intel_flags)) {
11903            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
11904        }
11905        else
11906    #endif
11907    #ifdef HAVE_INTEL_AVX1
11908        if (IS_INTEL_AVX1(intel_flags)) {
11909            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
11910        }
11911        else
11912    #endif
11913        {
11914            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
11915        }
11916    }
11917    /* Calculate and compare the authentication tag. */
11918#ifdef HAVE_INTEL_AVX2
11919    if (IS_INTEL_AVX2(intel_flags)) {
11920        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11921            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11922    }
11923    else
11924#endif
11925#ifdef HAVE_INTEL_AVX1
11926    if (IS_INTEL_AVX1(intel_flags)) {
11927        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11928            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11929    }
11930    else
11931#endif
11932    {
11933        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
11934            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
11935    }
11936
11937    /* Return error code when calculated doesn't match input. */
11938    if (res == 0) {
11939        ret = AES_GCM_AUTH_E;
11940    }
11941    return ret;
11942}
11943#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
11944#endif /* WOLFSSL_AESNI */
11945
11946#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
11947    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
11948/* Initialize the AES GCM cipher with an IV. Aarch64 HW Crypto implementations.
11949 *
11950 * @param [in, out] aes   AES object.
11951 * @param [in]      iv    IV/nonce buffer.
11952 * @param [in]      ivSz  Length of IV/nonce data.
11953 */
11954static WARN_UNUSED_RESULT int AesGcmInit_AARCH64(Aes* aes, const byte* iv,
11955    word32 ivSz)
11956{
11957    /* Reset state fields. */
11958    aes->over = 0;
11959    aes->aSz = 0;
11960    aes->cSz = 0;
11961    /* Set tag to all zeros as initial value. */
11962    XMEMSET(AES_TAG(aes), 0, WC_AES_BLOCK_SIZE);
11963    /* Reset counts of AAD and cipher text. */
11964    aes->aOver = 0;
11965    aes->cOver = 0;
11966
11967#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
11968    if (aes->use_sha3_hw_crypto) {
11969        AES_GCM_init_AARCH64_EOR3((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11970            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11971    }
11972    else
11973#endif
11974    {
11975        AES_GCM_init_AARCH64((byte*)aes->key, (int)aes->rounds, iv, ivSz,
11976            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
11977    }
11978
11979    return 0;
11980}
11981
11982/* Update the AES GCM for encryption with authentication data.
11983 *
11984 * Implementation uses AARCH64 optimized assembly code.
11985 *
11986 * @param [in, out] aes   AES object.
11987 * @param [in]      a     Buffer holding authentication data.
11988 * @param [in]      aSz   Length of authentication data in bytes.
11989 * @param [in]      endA  Whether no more authentication data is expected.
11990 */
11991static WARN_UNUSED_RESULT int AesGcmAadUpdate_AARCH64(
11992    Aes* aes, const byte* a, word32 aSz, int endA)
11993{
11994    word32 blocks;
11995    int partial;
11996
11997    if (aSz != 0 && a != NULL) {
11998        /* Total count of AAD updated. */
11999        aes->aSz += aSz;
12000        /* Check if we have unprocessed data. */
12001        if (aes->aOver > 0) {
12002            /* Calculate amount we can use - fill up the block. */
12003            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->aOver);
12004            if (sz > aSz) {
12005                sz = (byte)aSz;
12006            }
12007            /* Copy extra into last GHASH block array and update count. */
12008            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
12009            aes->aOver = (byte)(aes->aOver + sz);
12010            if (aes->aOver == WC_AES_BLOCK_SIZE) {
12011                /* We have filled up the block and can process. */
12012            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12013                if (aes->use_sha3_hw_crypto) {
12014                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
12015                        AES_TAG(aes), aes->gcm.H);
12016                }
12017                else
12018            #endif
12019                {
12020                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
12021                        AES_TAG(aes), aes->gcm.H);
12022                }
12023                /* Reset count. */
12024                aes->aOver = 0;
12025            }
12026            /* Used up some data. */
12027            aSz -= sz;
12028            a += sz;
12029        }
12030
12031        /* Calculate number of blocks of AAD and the leftover. */
12032        blocks = aSz / WC_AES_BLOCK_SIZE;
12033        partial = aSz % WC_AES_BLOCK_SIZE;
12034        if (blocks > 0) {
12035            /* GHASH full blocks now. */
12036        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12037            if (aes->use_sha3_hw_crypto) {
12038                AES_GCM_aad_update_AARCH64_EOR3(a, blocks * WC_AES_BLOCK_SIZE,
12039                    AES_TAG(aes), aes->gcm.H);
12040            }
12041            else
12042        #endif
12043            {
12044                AES_GCM_aad_update_AARCH64(a, blocks * WC_AES_BLOCK_SIZE,
12045                    AES_TAG(aes), aes->gcm.H);
12046            }
12047            /* Skip over to end of AAD blocks. */
12048            a += blocks * WC_AES_BLOCK_SIZE;
12049        }
12050        if (partial != 0) {
12051            /* Cache the partial block. */
12052            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
12053            aes->aOver = (byte)partial;
12054        }
12055    }
12056    if (endA && (aes->aOver > 0)) {
12057        /* No more AAD coming and we have a partial block. */
12058        /* Fill the rest of the block with zeros. */
12059        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
12060                (size_t)WC_AES_BLOCK_SIZE - aes->aOver);
12061        /* GHASH last AAD block. */
12062    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12063        if (aes->use_sha3_hw_crypto) {
12064            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
12065                AES_TAG(aes), aes->gcm.H);
12066        }
12067        else
12068    #endif
12069        {
12070            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
12071                AES_TAG(aes), aes->gcm.H);
12072        }
12073        /* Clear partial count for next time through. */
12074        aes->aOver = 0;
12075    }
12076
12077    return 0;
12078}
12079
12080/* Update the AES GCM for encryption with data and/or authentication data.
12081 *
12082 * Implementation uses AARCH64 optimized assembly code.
12083 *
12084 * @param [in, out] aes  AES object.
12085 * @param [out]     c    Buffer to hold cipher text.
12086 * @param [in]      p    Buffer holding plaintext.
12087 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
12088 * @param [in]      a    Buffer holding authentication data.
12089 * @param [in]      aSz  Length of authentication data in bytes.
12090 */
12091static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_AARCH64(
12092    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
12093{
12094    word32 blocks;
12095    int partial;
12096    int ret;
12097
12098    /* Hash in A, the Authentication Data */
12099    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, (cSz > 0) && (c != NULL));
12100    if (ret != 0)
12101        return ret;
12102
12103    /* Encrypt plaintext and Hash in C, the Cipher text */
12104    if (cSz != 0 && c != NULL) {
12105        /* Update count of cipher text we have hashed. */
12106        aes->cSz += cSz;
12107        if (aes->cOver > 0) {
12108            /* Calculate amount we can use - fill up the block. */
12109            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
12110            if (sz > cSz) {
12111                sz = (byte)cSz;
12112            }
12113            /* Encrypt some of the plaintext. */
12114            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
12115            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
12116            /* Update count of unused encrypted counter. */
12117            aes->cOver = (byte)(aes->cOver + sz);
12118            if (aes->cOver == WC_AES_BLOCK_SIZE) {
12119                /* We have filled up the block and can process. */
12120            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12121                if (aes->use_sha3_hw_crypto) {
12122                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes),
12123                        AES_TAG(aes), aes->gcm.H);
12124                }
12125                else
12126            #endif
12127                {
12128                    AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes),
12129                        AES_TAG(aes), aes->gcm.H);
12130                }
12131                /* Reset count. */
12132                aes->cOver = 0;
12133            }
12134            /* Used up some data. */
12135            cSz -= sz;
12136            p += sz;
12137            c += sz;
12138        }
12139
12140        /* Calculate number of blocks of plaintext and the leftover. */
12141        blocks = cSz / WC_AES_BLOCK_SIZE;
12142        partial = cSz % WC_AES_BLOCK_SIZE;
12143        if (blocks > 0) {
12144            /* Encrypt and GHASH full blocks now. */
12145        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12146            if (aes->use_sha3_hw_crypto) {
12147                AES_GCM_encrypt_update_AARCH64_EOR3((byte*)aes->key,
12148                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
12149                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
12150            }
12151            else
12152        #endif
12153            {
12154                AES_GCM_encrypt_update_AARCH64((byte*)aes->key,
12155                    (int)aes->rounds, c, p, blocks * WC_AES_BLOCK_SIZE,
12156                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
12157            }
12158            /* Skip over to end of blocks. */
12159            p += blocks * WC_AES_BLOCK_SIZE;
12160            c += blocks * WC_AES_BLOCK_SIZE;
12161        }
12162        if (partial != 0) {
12163            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
12164            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
12165        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12166            if (aes->use_sha3_hw_crypto) {
12167                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
12168                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
12169                    AES_COUNTER(aes));
12170            }
12171            else
12172        #endif
12173            {
12174                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
12175                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12176            }
12177            /* XOR the remaining plaintext to calculate cipher text.
12178             * Keep cipher text for GHASH of last partial block.
12179             */
12180            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
12181            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
12182            /* Update count of the block used. */
12183            aes->cOver = (byte)partial;
12184        }
12185    }
12186    return 0;
12187}
12188
12189/* Finalize the AES GCM for encryption and calculate the authentication tag.
12190 *
12191 * Calls ARCH64 optimized assembly code.
12192 *
12193 * @param [in, out] aes        AES object.
12194 * @param [in]      authTag    Buffer to hold authentication tag.
12195 * @param [in]      authTagSz  Length of authentication tag in bytes.
12196 * @return  0 on success.
12197 */
12198static WARN_UNUSED_RESULT int AesGcmEncryptFinal_AARCH64(Aes* aes,
12199    byte* authTag, word32 authTagSz)
12200{
12201    /* AAD block incomplete when > 0 */
12202    byte over = aes->aOver;
12203
12204    ASSERT_SAVED_VECTOR_REGISTERS();
12205
12206    if (aes->cOver > 0) {
12207        /* Cipher text block incomplete. */
12208        over = aes->cOver;
12209    }
12210    if (over > 0) {
12211        /* Fill the rest of the block with zeros. */
12212        XMEMSET(AES_LASTGBLOCK(aes) + over, 0,
12213            (size_t)WC_AES_BLOCK_SIZE - over);
12214        /* GHASH last cipher block. */
12215    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12216        if (aes->use_sha3_hw_crypto) {
12217            AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTGBLOCK(aes), AES_TAG(aes),
12218                aes->gcm.H);
12219        }
12220        else
12221    #endif
12222        {
12223            AES_GCM_ghash_block_AARCH64(AES_LASTGBLOCK(aes), AES_TAG(aes),
12224                aes->gcm.H);
12225        }
12226    }
12227    /* Calculate the authentication tag. */
12228#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12229    if (aes->use_sha3_hw_crypto) {
12230        AES_GCM_encrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
12231            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12232    }
12233    else
12234#endif
12235    {
12236        AES_GCM_encrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
12237            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes));
12238    }
12239
12240    return 0;
12241}
12242
12243#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
12244/* Update the AES GCM for decryption with data and/or authentication data.
12245 *
12246 * @param [in, out] aes  AES object.
12247 * @param [out]     p    Buffer to hold plaintext.
12248 * @param [in]      c    Buffer holding cipher text.
12249 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
12250 * @param [in]      a    Buffer holding authentication data.
12251 * @param [in]      aSz  Length of authentication data in bytes.
12252 */
12253static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_AARCH64(Aes* aes, byte* p,
12254    const byte* c, word32 cSz, const byte* a, word32 aSz)
12255{
12256    word32 blocks;
12257    int partial;
12258    int ret;
12259
12260    /* Hash in A, the Authentication Data */
12261    ret = AesGcmAadUpdate_AARCH64(aes, a, aSz, cSz > 0);
12262    if (ret != 0)
12263        return ret;
12264
12265    /* Hash in C, the Cipher text, and decrypt. */
12266    if (cSz != 0 && p != NULL) {
12267        /* Update count of cipher text we have hashed. */
12268        aes->cSz += cSz;
12269        if (aes->cOver > 0) {
12270            /* Calculate amount we can use - fill up the block. */
12271            byte sz = (byte)(WC_AES_BLOCK_SIZE - aes->cOver);
12272            if (sz > cSz) {
12273                sz = (byte)cSz;
12274            }
12275            /* Keep a copy of the cipher text for GHASH. */
12276            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
12277            /* Decrypt some of the cipher text. */
12278            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
12279            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
12280            /* Update count of unused encrypted counter. */
12281            aes->cOver = (byte)(aes->cOver + sz);
12282            if (aes->cOver == WC_AES_BLOCK_SIZE) {
12283                /* We have filled up the block and can process. */
12284            #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12285                if (aes->use_sha3_hw_crypto) {
12286                    AES_GCM_ghash_block_AARCH64_EOR3(AES_LASTBLOCK(aes),
12287                        AES_TAG(aes), aes->gcm.H);
12288                }
12289                else
12290            #endif
12291                {
12292                    AES_GCM_ghash_block_AARCH64(AES_LASTBLOCK(aes),
12293                        AES_TAG(aes), aes->gcm.H);
12294                }
12295                /* Reset count. */
12296                aes->cOver = 0;
12297            }
12298            /* Used up some data. */
12299            cSz -= sz;
12300            c += sz;
12301            p += sz;
12302        }
12303
12304        /* Calculate number of blocks of plaintext and the leftover. */
12305        blocks = cSz / WC_AES_BLOCK_SIZE;
12306        partial = cSz % WC_AES_BLOCK_SIZE;
12307        if (blocks > 0) {
12308            /* Decrypt and GHASH full blocks now. */
12309        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12310            if (aes->use_sha3_hw_crypto) {
12311                AES_GCM_decrypt_update_AARCH64_EOR3((byte*)aes->key,
12312                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
12313                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
12314            }
12315            else
12316        #endif
12317            {
12318                AES_GCM_decrypt_update_AARCH64((byte*)aes->key,
12319                    (int)aes->rounds, p, c, blocks * WC_AES_BLOCK_SIZE,
12320                    AES_TAG(aes), aes->gcm.H, AES_COUNTER(aes));
12321            }
12322            /* Skip over to end of blocks. */
12323            c += blocks * WC_AES_BLOCK_SIZE;
12324            p += blocks * WC_AES_BLOCK_SIZE;
12325        }
12326        if (partial != 0) {
12327            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
12328            XMEMSET(AES_LASTGBLOCK(aes), 0, WC_AES_BLOCK_SIZE);
12329        #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12330            if (aes->use_sha3_hw_crypto) {
12331                AES_GCM_encrypt_block_AARCH64_EOR3((byte*)aes->key,
12332                    (int)aes->rounds, AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes),
12333                    AES_COUNTER(aes));
12334            }
12335            else
12336        #endif
12337            {
12338                AES_GCM_encrypt_block_AARCH64((byte*)aes->key, (int)aes->rounds,
12339                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
12340            }
12341            /* Keep cipher text for GHASH of last partial block. */
12342            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
12343            /* XOR the remaining cipher text to calculate plaintext. */
12344            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
12345            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
12346            /* Update count of the block used. */
12347            aes->cOver = (byte)partial;
12348        }
12349    }
12350
12351    return 0;
12352}
12353
12354/* Finalize the AES GCM for decryption and check the authentication tag.
12355 *
12356 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
12357 *
12358 * @param [in, out] aes        AES object.
12359 * @param [in]      authTag    Buffer holding authentication tag.
12360 * @param [in]      authTagSz  Length of authentication tag in bytes.
12361 * @return  0 on success.
12362 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
12363 *          value.
12364 */
12365static WARN_UNUSED_RESULT int AesGcmDecryptFinal_AARCH64(
12366    Aes* aes, const byte* authTag, word32 authTagSz)
12367{
12368    int ret = 0;
12369    int res;
12370    /* AAD block incomplete when > 0 */
12371    byte over = aes->aOver;
12372    byte *lastBlock = AES_LASTGBLOCK(aes);
12373
12374    ASSERT_SAVED_VECTOR_REGISTERS();
12375
12376    if (aes->cOver > 0) {
12377        /* Cipher text block incomplete. */
12378        over = aes->cOver;
12379        lastBlock = AES_LASTBLOCK(aes);
12380    }
12381    if (over > 0) {
12382        /* Zeroize the unused part of the block. */
12383        XMEMSET(lastBlock + over, 0, (size_t)WC_AES_BLOCK_SIZE - over);
12384        /* Hash the last block of cipher text. */
12385    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12386        if (aes->use_sha3_hw_crypto) {
12387            AES_GCM_ghash_block_AARCH64_EOR3(lastBlock, AES_TAG(aes),
12388                aes->gcm.H);
12389        }
12390        else
12391    #endif
12392        {
12393            AES_GCM_ghash_block_AARCH64(lastBlock, AES_TAG(aes), aes->gcm.H);
12394        }
12395    }
12396    /* Calculate and compare the authentication tag. */
12397#ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
12398    if (aes->use_sha3_hw_crypto) {
12399        AES_GCM_decrypt_final_AARCH64_EOR3(AES_TAG(aes), authTag, authTagSz,
12400            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
12401    }
12402    else
12403#endif
12404    {
12405        AES_GCM_decrypt_final_AARCH64(AES_TAG(aes), authTag, authTagSz,
12406            aes->cSz, aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
12407    }
12408
12409    /* Return error code when calculated doesn't match input. */
12410    if (res == 0) {
12411        ret = AES_GCM_AUTH_E;
12412    }
12413    return ret;
12414}
12415#endif
12416#endif
12417
12418/* Initialize an AES GCM cipher for encryption or decryption.
12419 *
12420 * Must call wc_AesInit() before calling this function.
12421 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
12422 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
12423 *
12424 * @param [in, out] aes   AES object.
12425 * @param [in]      key   Buffer holding key.
12426 * @param [in]      len   Length of key in bytes.
12427 * @param [in]      iv    Buffer holding IV/nonce.
12428 * @param [in]      ivSz  Length of IV/nonce in bytes.
12429 * @return  0 on success.
12430 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
12431 *          is NULL, or the IV is NULL and no previous IV has been set.
12432 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
12433 */
12434int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
12435    word32 ivSz)
12436{
12437    int ret = 0;
12438
12439    /* Check validity of parameters. */
12440    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
12441            ((ivSz == 0) && (iv != NULL)) ||
12442            ((ivSz > 0) && (iv == NULL))) {
12443        ret = BAD_FUNC_ARG;
12444    }
12445
12446#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
12447    if ((ret == 0) && (aes->streamData == NULL)) {
12448        /* Allocate buffers for streaming. */
12449        aes->streamData_sz = 5 * WC_AES_BLOCK_SIZE;
12450        aes->streamData = (byte*)XMALLOC(aes->streamData_sz, aes->heap,
12451                                                              DYNAMIC_TYPE_AES);
12452        if (aes->streamData == NULL) {
12453            ret = MEMORY_E;
12454        }
12455    }
12456#endif
12457
12458    /* Set the key if passed in. */
12459    if ((ret == 0) && (key != NULL)) {
12460        ret = wc_AesGcmSetKey(aes, key, len);
12461    }
12462
12463    if (ret == 0) {
12464        /* Set the IV passed in if it is smaller than a block. */
12465        if ((iv != NULL) && (ivSz <= WC_AES_BLOCK_SIZE)) {
12466            XMEMMOVE((byte*)aes->reg, iv, ivSz);
12467            aes->nonceSz = ivSz;
12468        }
12469        /* No IV passed in, check for cached IV. */
12470        if ((iv == NULL) && (aes->nonceSz != 0)) {
12471            /* Use the cached copy. */
12472            iv = (byte*)aes->reg;
12473            ivSz = aes->nonceSz;
12474        }
12475
12476        if (iv != NULL) {
12477            /* Initialize with the IV. */
12478
12479        #ifdef WOLFSSL_AESNI
12480            if (aes->use_aesni) {
12481                SAVE_VECTOR_REGISTERS(return _svr_ret;);
12482                ret = AesGcmInit_aesni(aes, iv, ivSz);
12483                RESTORE_VECTOR_REGISTERS();
12484            }
12485            else
12486        #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12487              !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12488            if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12489                ret = AesGcmInit_AARCH64(aes, iv, ivSz);
12490            }
12491            else
12492        #endif /* WOLFSSL_AESNI */
12493            {
12494                ret = AesGcmInit_C(aes, iv, ivSz);
12495            }
12496
12497            if (ret == 0)
12498                aes->nonceSet = 1;
12499        }
12500    }
12501
12502    return ret;
12503}
12504
12505/* Initialize an AES GCM cipher for encryption.
12506 *
12507 * Must call wc_AesInit() before calling this function.
12508 *
12509 * @param [in, out] aes   AES object.
12510 * @param [in]      key   Buffer holding key.
12511 * @param [in]      len   Length of key in bytes.
12512 * @param [in]      iv    Buffer holding IV/nonce.
12513 * @param [in]      ivSz  Length of IV/nonce in bytes.
12514 * @return  0 on success.
12515 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
12516 *          is NULL, or the IV is NULL and no previous IV has been set.
12517 */
12518int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
12519    word32 ivSz)
12520{
12521    return wc_AesGcmInit(aes, key, len, iv, ivSz);
12522}
12523
12524/* Initialize an AES GCM cipher for encryption. Get IV.
12525 *
12526 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
12527 * function.
12528 * Must call wc_AesInit() before calling this function.
12529 *
12530 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
12531 *
12532 * @param [in, out] aes   AES object.
12533 * @param [in]      key   Buffer holding key.
12534 * @param [in]      len   Length of key in bytes.
12535 * @param [in]      iv    Buffer holding IV/nonce.
12536 * @param [in]      ivSz  Length of IV/nonce in bytes.
12537 * @return  0 on success.
12538 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
12539 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
12540 *          nonce size.
12541 */
12542int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
12543    word32 ivOutSz)
12544{
12545    int ret;
12546
12547    /* Check validity of parameters. */
12548    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
12549        ret = BAD_FUNC_ARG;
12550    }
12551    else {
12552        /* Copy out the IV including generated part for decryption. */
12553        XMEMCPY(ivOut, aes->reg, ivOutSz);
12554        /* Initialize AES GCM cipher with key and cached Iv. */
12555        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
12556    }
12557
12558    return ret;
12559}
12560
12561/* Update the AES GCM for encryption with data and/or authentication data. */
12562int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
12563    const byte* authIn, word32 authInSz)
12564{
12565    int ret = 0;
12566
12567    /* Check validity of parameters. */
12568    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
12569            ((out == NULL) || (in == NULL)))) {
12570        ret = BAD_FUNC_ARG;
12571    }
12572
12573    /* Check key has been set. */
12574    if ((ret == 0) && (!aes->gcmKeySet)) {
12575        ret = MISSING_KEY;
12576    }
12577    /* Check IV has been set. */
12578    if ((ret == 0) && (!aes->nonceSet)) {
12579        ret = MISSING_IV;
12580    }
12581
12582    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
12583        aes->invokeCtr[0]++;
12584        if (aes->invokeCtr[0] == 0) {
12585            aes->invokeCtr[1]++;
12586            if (aes->invokeCtr[1] == 0)
12587                ret = AES_GCM_OVERFLOW_E;
12588        }
12589    }
12590
12591    if (ret == 0) {
12592        /* Encrypt with AAD and/or plaintext. */
12593
12594    #ifdef WOLFSSL_AESNI
12595        if (aes->use_aesni) {
12596            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12597            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
12598            RESTORE_VECTOR_REGISTERS();
12599        }
12600        else
12601    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12602          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12603        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12604            ret = AesGcmEncryptUpdate_AARCH64(aes, out, in, sz, authIn,
12605                authInSz);
12606        }
12607        else
12608    #endif
12609        {
12610            /* Encrypt the plaintext. */
12611            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
12612            if (ret == 0) {
12613                /* Update the authentication tag with any authentication data and the
12614                 * new cipher text. */
12615                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
12616            }
12617        }
12618    }
12619
12620    return ret;
12621}
12622
12623/* Finalize the AES GCM for encryption and return the authentication tag.
12624 *
12625 * Must set key and IV before calling this function.
12626 * Must call wc_AesGcmInit() before calling this function.
12627 *
12628 * @param [in, out] aes        AES object.
12629 * @param [out]     authTag    Buffer to hold authentication tag.
12630 * @param [in]      authTagSz  Length of authentication tag in bytes.
12631 * @return  0 on success.
12632 */
12633int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
12634{
12635    int ret = 0;
12636
12637    /* Check validity of parameters. */
12638    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
12639            (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ)) {
12640        ret = BAD_FUNC_ARG;
12641    }
12642
12643    /* Check key has been set. */
12644    if ((ret == 0) && (!aes->gcmKeySet)) {
12645        ret = MISSING_KEY;
12646    }
12647    /* Check IV has been set. */
12648    if ((ret == 0) && (!aes->nonceSet)) {
12649        ret = MISSING_IV;
12650    }
12651
12652    if (ret == 0) {
12653        /* Calculate authentication tag. */
12654    #ifdef WOLFSSL_AESNI
12655        if (aes->use_aesni) {
12656            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12657            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
12658            RESTORE_VECTOR_REGISTERS();
12659        }
12660        else
12661    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12662          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12663        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12664            ret = AesGcmEncryptFinal_AARCH64(aes, authTag, authTagSz);
12665        }
12666        else
12667    #endif
12668        {
12669            ret = AesGcmFinal_C(aes, authTag, authTagSz);
12670        }
12671    }
12672
12673    if ((ret == 0) && aes->ctrSet) {
12674        IncCtr((byte*)aes->reg, aes->nonceSz);
12675    }
12676
12677    return ret;
12678}
12679
12680#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
12681/* Initialize an AES GCM cipher for decryption.
12682 *
12683 * Must call wc_AesInit() before calling this function.
12684 *
12685 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
12686 * instead.
12687 *
12688 * @param [in, out] aes   AES object.
12689 * @param [in]      key   Buffer holding key.
12690 * @param [in]      len   Length of key in bytes.
12691 * @param [in]      iv    Buffer holding IV/nonce.
12692 * @param [in]      ivSz  Length of IV/nonce in bytes.
12693 * @return  0 on success.
12694 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
12695 *          is NULL, or the IV is NULL and no previous IV has been set.
12696 */
12697int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
12698    word32 ivSz)
12699{
12700    return wc_AesGcmInit(aes, key, len, iv, ivSz);
12701}
12702
12703/* Update the AES GCM for decryption with data and/or authentication data. */
12704int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
12705    const byte* authIn, word32 authInSz)
12706{
12707    int ret = 0;
12708
12709    /* Check validity of parameters. */
12710    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
12711            ((out == NULL) || (in == NULL)))) {
12712        ret = BAD_FUNC_ARG;
12713    }
12714
12715    /* Check key has been set. */
12716    if ((ret == 0) && (!aes->gcmKeySet)) {
12717        ret = MISSING_KEY;
12718    }
12719    /* Check IV has been set. */
12720    if ((ret == 0) && (!aes->nonceSet)) {
12721        ret = MISSING_IV;
12722    }
12723
12724    if (ret == 0) {
12725        /* Decrypt with AAD and/or cipher text. */
12726    #ifdef WOLFSSL_AESNI
12727        if (aes->use_aesni) {
12728            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12729            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
12730            RESTORE_VECTOR_REGISTERS();
12731        }
12732        else
12733    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12734          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12735        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12736            ret = AesGcmDecryptUpdate_AARCH64(aes, out, in, sz, authIn,
12737                authInSz);
12738        }
12739        else
12740    #endif
12741        {
12742            /* Update the authentication tag with any authentication data and
12743             * cipher text. */
12744            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
12745            /* Decrypt the cipher text. */
12746            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
12747        }
12748    }
12749
12750    return ret;
12751}
12752
12753/* Finalize the AES GCM for decryption and check the authentication tag.
12754 *
12755 * Must set key and IV before calling this function.
12756 * Must call wc_AesGcmInit() before calling this function.
12757 *
12758 * @param [in, out] aes        AES object.
12759 * @param [in]      authTag    Buffer holding authentication tag.
12760 * @param [in]      authTagSz  Length of authentication tag in bytes.
12761 * @return  0 on success.
12762 */
12763int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
12764{
12765    int ret = 0;
12766
12767    /* Check validity of parameters. */
12768    if ((aes == NULL) || (authTag == NULL) || (authTagSz > WC_AES_BLOCK_SIZE) ||
12769            (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ)) {
12770        ret = BAD_FUNC_ARG;
12771    }
12772
12773    /* Check key has been set. */
12774    if ((ret == 0) && (!aes->gcmKeySet)) {
12775        ret = MISSING_KEY;
12776    }
12777    /* Check IV has been set. */
12778    if ((ret == 0) && (!aes->nonceSet)) {
12779        ret = MISSING_IV;
12780    }
12781
12782    if (ret == 0) {
12783        /* Calculate authentication tag and compare with one passed in.. */
12784    #ifdef WOLFSSL_AESNI
12785        if (aes->use_aesni) {
12786            SAVE_VECTOR_REGISTERS(return _svr_ret;);
12787            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
12788            RESTORE_VECTOR_REGISTERS();
12789        }
12790        else
12791    #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
12792          !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12793        if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) {
12794            ret = AesGcmDecryptFinal_AARCH64(aes, authTag, authTagSz);
12795        }
12796        else
12797    #endif
12798        {
12799            ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE];
12800            /* Calculate authentication tag. */
12801            ret = AesGcmFinal_C(aes, calcTag, WC_AES_BLOCK_SIZE);
12802            if (ret == 0) {
12803                /* Check calculated tag matches the one passed in. */
12804                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
12805                    ret = AES_GCM_AUTH_E;
12806                }
12807            }
12808        }
12809    }
12810
12811    return ret;
12812}
12813#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
12814#endif /* WOLFSSL_AESGCM_STREAM */
12815#endif /* WOLFSSL_XILINX_CRYPT */
12816#endif /* end of block for AESGCM implementation selection */
12817
12818
12819/* Common to all, abstract functions that build off of lower level AESGCM
12820 * functions */
12821#ifndef WC_NO_RNG
12822
12823static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
12824    return (ivSz == GCM_NONCE_MIN_SZ ||
12825            ivSz == GCM_NONCE_MID_SZ ||
12826            ivSz == GCM_NONCE_MAX_SZ);
12827}
12828
12829
12830int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
12831{
12832    int ret = 0;
12833
12834    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
12835        ret = BAD_FUNC_ARG;
12836    }
12837
12838    if (ret == 0) {
12839        XMEMCPY((byte*)aes->reg, iv, ivSz);
12840
12841        /* If the IV is 96, allow for a 2^64 invocation counter.
12842         * For any other size for the nonce, limit the invocation
12843         * counter to 32-bits. (SP 800-38D 8.3) */
12844        aes->invokeCtr[0] = 0;
12845        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
12846    #ifdef WOLFSSL_AESGCM_STREAM
12847        aes->ctrSet = 1;
12848    #endif
12849        aes->nonceSz = ivSz;
12850    }
12851
12852    return ret;
12853}
12854
12855
12856int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
12857                   const byte* ivFixed, word32 ivFixedSz,
12858                   WC_RNG* rng)
12859{
12860    int ret = 0;
12861
12862    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
12863        (ivFixed == NULL && ivFixedSz != 0) ||
12864        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
12865
12866        ret = BAD_FUNC_ARG;
12867    }
12868
12869    if (ret == 0) {
12870        byte* iv = (byte*)aes->reg;
12871
12872        if (ivFixedSz)
12873            XMEMCPY(iv, ivFixed, ivFixedSz);
12874
12875        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
12876    }
12877
12878    if (ret == 0) {
12879        /* If the IV is 96, allow for a 2^64 invocation counter.
12880         * For any other size for the nonce, limit the invocation
12881         * counter to 32-bits. (SP 800-38D 8.3) */
12882        aes->invokeCtr[0] = 0;
12883        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
12884    #ifdef WOLFSSL_AESGCM_STREAM
12885        aes->ctrSet = 1;
12886    #endif
12887        aes->nonceSz = ivSz;
12888    }
12889
12890    return ret;
12891}
12892
12893
12894int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
12895                        byte* ivOut, word32 ivOutSz,
12896                        byte* authTag, word32 authTagSz,
12897                        const byte* authIn, word32 authInSz)
12898{
12899    int ret = 0;
12900
12901    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
12902        ivOut == NULL || ivOutSz != aes->nonceSz ||
12903        (authIn == NULL && authInSz != 0)) {
12904
12905        ret = BAD_FUNC_ARG;
12906    }
12907
12908    if (ret == 0) {
12909        aes->invokeCtr[0]++;
12910        if (aes->invokeCtr[0] == 0) {
12911            aes->invokeCtr[1]++;
12912            if (aes->invokeCtr[1] == 0)
12913                ret = AES_GCM_OVERFLOW_E;
12914        }
12915    }
12916
12917    if (ret == 0) {
12918        XMEMCPY(ivOut, aes->reg, ivOutSz);
12919        ret = wc_AesGcmEncrypt(aes, out, in, sz,
12920                               (byte*)aes->reg, ivOutSz,
12921                               authTag, authTagSz,
12922                               authIn, authInSz);
12923        if (ret == 0)
12924            IncCtr((byte*)aes->reg, ivOutSz);
12925    }
12926
12927    return ret;
12928}
12929
12930int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
12931            const byte* authIn, word32 authInSz,
12932            byte* authTag, word32 authTagSz, WC_RNG* rng)
12933{
12934    WC_DECLARE_VAR(aes, Aes, 1, 0);
12935    int ret;
12936
12937    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
12938        authTag == NULL || authTagSz == 0 || rng == NULL) {
12939
12940        return BAD_FUNC_ARG;
12941    }
12942
12943#ifdef WOLFSSL_SMALL_STACK
12944    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
12945#else
12946    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12947#endif
12948    if (ret != 0)
12949        return ret;
12950
12951    ret = wc_AesGcmSetKey(aes, key, keySz);
12952    if (ret == 0)
12953        ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
12954    if (ret == 0)
12955        ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
12956                                  authTag, authTagSz, authIn, authInSz);
12957
12958#ifdef WOLFSSL_SMALL_STACK
12959    wc_AesDelete(aes, NULL);
12960#else
12961    wc_AesFree(aes);
12962#endif
12963
12964    return ret;
12965}
12966
12967int wc_GmacVerify(const byte* key, word32 keySz,
12968                  const byte* iv, word32 ivSz,
12969                  const byte* authIn, word32 authInSz,
12970                  const byte* authTag, word32 authTagSz)
12971{
12972    int ret;
12973#ifdef HAVE_AES_DECRYPT
12974    WC_DECLARE_VAR(aes, Aes, 1, 0);
12975
12976    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
12977        authTag == NULL || authTagSz == 0 || authTagSz > WC_AES_BLOCK_SIZE) {
12978
12979        return BAD_FUNC_ARG;
12980    }
12981
12982#ifdef WOLFSSL_SMALL_STACK
12983    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
12984#else
12985    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12986#endif
12987    if (ret == 0) {
12988        ret = wc_AesGcmSetKey(aes, key, keySz);
12989        if (ret == 0)
12990            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
12991                                  authTag, authTagSz, authIn, authInSz);
12992
12993    }
12994#ifdef WOLFSSL_SMALL_STACK
12995    wc_AesDelete(aes, NULL);
12996#else
12997    wc_AesFree(aes);
12998#endif
12999#else
13000    (void)key;
13001    (void)keySz;
13002    (void)iv;
13003    (void)ivSz;
13004    (void)authIn;
13005    (void)authInSz;
13006    (void)authTag;
13007    (void)authTagSz;
13008    ret = NOT_COMPILED_IN;
13009#endif
13010    return ret;
13011}
13012
13013#endif /* WC_NO_RNG */
13014
13015
13016int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
13017{
13018    if (gmac == NULL || key == NULL) {
13019        return BAD_FUNC_ARG;
13020    }
13021    return wc_AesGcmSetKey(&gmac->aes, key, len);
13022}
13023
13024
13025int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
13026                              const byte* authIn, word32 authInSz,
13027                              byte* authTag, word32 authTagSz)
13028{
13029    if (gmac == NULL) {
13030        return BAD_FUNC_ARG;
13031    }
13032
13033    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
13034                                         authTag, authTagSz, authIn, authInSz);
13035}
13036
13037#endif /* HAVE_AESGCM */
13038
13039#ifdef HAVE_AESCCM
13040
13041int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
13042{
13043    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
13044        return BAD_FUNC_ARG;
13045
13046    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
13047}
13048
13049
13050/* Checks if the tag size is an accepted value based on RFC 3610 section 2
13051 * returns 0 if tag size is ok
13052 */
13053int wc_AesCcmCheckTagSize(int sz)
13054{
13055    /* values here are from RFC 3610 section 2 */
13056    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
13057            && sz != 16) {
13058        WOLFSSL_MSG("Bad auth tag size AES-CCM");
13059        return BAD_FUNC_ARG;
13060    }
13061    return 0;
13062}
13063
13064#if defined(WOLFSSL_RISCV_ASM)
13065    /* implementation located in wolfcrypt/src/port/riscv/riscv-64-aes.c */
13066
13067#elif defined(HAVE_COLDFIRE_SEC)
13068    #error "Coldfire SEC doesn't currently support AES-CCM mode"
13069
13070#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
13071        !defined(WOLFSSL_QNX_CAAM)
13072    /* implemented in wolfcrypt/src/port/caam_aes.c */
13073
13074#elif defined(WOLFSSL_SILABS_SE_ACCEL)
13075    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
13076int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
13077                   const byte* nonce, word32 nonceSz,
13078                   byte* authTag, word32 authTagSz,
13079                   const byte* authIn, word32 authInSz)
13080{
13081    return wc_AesCcmEncrypt_silabs(
13082        aes, out, in, inSz,
13083        nonce, nonceSz,
13084        authTag, authTagSz,
13085        authIn, authInSz);
13086}
13087
13088#ifdef HAVE_AES_DECRYPT
13089int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
13090                   const byte* nonce, word32 nonceSz,
13091                   const byte* authTag, word32 authTagSz,
13092                   const byte* authIn, word32 authInSz)
13093{
13094    return wc_AesCcmDecrypt_silabs(
13095        aes, out, in, inSz,
13096        nonce, nonceSz,
13097        authTag, authTagSz,
13098        authIn, authInSz);
13099}
13100#endif
13101#elif defined(FREESCALE_LTC)
13102
13103/* return 0 on success */
13104int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
13105                   const byte* nonce, word32 nonceSz,
13106                   byte* authTag, word32 authTagSz,
13107                   const byte* authIn, word32 authInSz)
13108{
13109    byte *key;
13110    word32 keySize;
13111    status_t status;
13112
13113    /* sanity check on arguments */
13114    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
13115     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
13116     * don't allow it here either.
13117     */
13118    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
13119            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
13120        return BAD_FUNC_ARG;
13121    }
13122
13123    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
13124        return BAD_FUNC_ARG;
13125    }
13126
13127    key = (byte*)aes->key;
13128
13129    status = wc_AesGetKeySize(aes, &keySize);
13130    if (status != 0) {
13131        return status;
13132    }
13133
13134    status = wolfSSL_CryptHwMutexLock();
13135    if (status != 0)
13136        return status;
13137
13138    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
13139        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
13140    wolfSSL_CryptHwMutexUnLock();
13141
13142    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
13143}
13144
13145#ifdef HAVE_AES_DECRYPT
13146int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
13147                   const byte* nonce, word32 nonceSz,
13148                   const byte* authTag, word32 authTagSz,
13149                   const byte* authIn, word32 authInSz)
13150{
13151    byte *key;
13152    word32 keySize;
13153    status_t status;
13154
13155    /* sanity check on arguments */
13156    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
13157            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
13158        return BAD_FUNC_ARG;
13159    }
13160
13161    key = (byte*)aes->key;
13162
13163    status = wc_AesGetKeySize(aes, &keySize);
13164    if (status != 0) {
13165        return status;
13166    }
13167
13168    status = wolfSSL_CryptHwMutexLock();
13169    if (status != 0)
13170        return status;
13171    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
13172        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
13173    wolfSSL_CryptHwMutexUnLock();
13174
13175    if (status != kStatus_Success) {
13176        XMEMSET(out, 0, inSz);
13177        return AES_CCM_AUTH_E;
13178    }
13179    return 0;
13180}
13181#endif /* HAVE_AES_DECRYPT */
13182
13183#else
13184
13185/* Software CCM */
13186static WARN_UNUSED_RESULT int roll_x(
13187    Aes* aes, const byte* in, word32 inSz, byte* out)
13188{
13189    int ret;
13190
13191    /* process the bulk of the data */
13192    while (inSz >= WC_AES_BLOCK_SIZE) {
13193        xorbuf(out, in, WC_AES_BLOCK_SIZE);
13194        in += WC_AES_BLOCK_SIZE;
13195        inSz -= WC_AES_BLOCK_SIZE;
13196
13197        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
13198         * roll_x() after the AES cache lines are already hot -- no need to
13199         * absorb additional prefetch overhead here.
13200         */
13201        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
13202        if (ret != 0)
13203            return ret;
13204    }
13205
13206    /* process remainder of the data */
13207    if (inSz > 0) {
13208        xorbuf(out, in, inSz);
13209        /* wc_AesCcmEncrypt(), wc_AesCcmDecrypt(), and roll_auth() only call
13210         * roll_x() after the AES cache lines are already hot -- no need to
13211         * absorb additional prefetch overhead here.
13212         */
13213        ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
13214        if (ret != 0)
13215            return ret;
13216    }
13217
13218    return 0;
13219}
13220
13221static WARN_UNUSED_RESULT int roll_auth(
13222    Aes* aes, const byte* in, word32 inSz, byte* out)
13223{
13224    word32 authLenSz;
13225    word32 remainder;
13226    int ret;
13227
13228    /* encode the length in */
13229    if (inSz <= 0xFEFF) {
13230        authLenSz = 2;
13231        out[0] ^= (byte)(inSz >> 8);
13232        out[1] ^= (byte)inSz;
13233    }
13234    else {
13235        authLenSz = 6;
13236        out[0] ^= 0xFF;
13237        out[1] ^= 0xFE;
13238        out[2] ^= (byte)(inSz >> 24);
13239        out[3] ^= (byte)(inSz >> 16);
13240        out[4] ^= (byte)(inSz >>  8);
13241        out[5] ^= (byte)inSz;
13242    }
13243    /* Note, the protocol handles auth data up to 2^64, but we are
13244     * using 32-bit sizes right now, so the bigger data isn't handled
13245     * else {}
13246     */
13247
13248    /* start fill out the rest of the first block */
13249    remainder = WC_AES_BLOCK_SIZE - authLenSz;
13250    if (inSz >= remainder) {
13251        /* plenty of bulk data to fill the remainder of this block */
13252        xorbuf(out + authLenSz, in, remainder);
13253        inSz -= remainder;
13254        in += remainder;
13255    }
13256    else {
13257        /* not enough bulk data, copy what is available, and pad zero */
13258        xorbuf(out + authLenSz, in, inSz);
13259        inSz = 0;
13260    }
13261    /* wc_AesCcmEncrypt() and wc_AesCcmDecrypt() only call roll_auth() after the
13262     * AES cache lines are already hot -- no need to absorb additional prefetch
13263     * overhead here.
13264     */
13265    ret = AesEncrypt_preFetchOpt(aes, out, out, &never_prefetch);
13266
13267    if ((ret == 0) && (inSz > 0)) {
13268        ret = roll_x(aes, in, inSz, out);
13269    }
13270
13271    return ret;
13272}
13273
13274
13275static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
13276{
13277    word32 i;
13278
13279    for (i = 0; i < lenSz; i++) {
13280        if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) return;
13281    }
13282}
13283
13284#ifdef WOLFSSL_AESNI
13285static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
13286{
13287    word32 i;
13288
13289    /* B+1 = B */
13290    XMEMCPY(B + WC_AES_BLOCK_SIZE * 1, B, WC_AES_BLOCK_SIZE);
13291    /* B+2,B+3 = B,B+1 */
13292    XMEMCPY(B + WC_AES_BLOCK_SIZE * 2, B, WC_AES_BLOCK_SIZE * 2);
13293
13294    for (i = 0; i < lenSz; i++) {
13295        if (++B[WC_AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
13296    }
13297    B[WC_AES_BLOCK_SIZE * 3 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 3 - 1] + 2U);
13298    if (B[WC_AES_BLOCK_SIZE * 3 - 1] < 2U) {
13299        for (i = 1; i < lenSz; i++) {
13300            if (++B[WC_AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
13301        }
13302    }
13303    B[WC_AES_BLOCK_SIZE * 4 - 1] = (byte)(B[WC_AES_BLOCK_SIZE * 4 - 1] + 3U);
13304    if (B[WC_AES_BLOCK_SIZE * 4 - 1] < 3U) {
13305        for (i = 1; i < lenSz; i++) {
13306            if (++B[WC_AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
13307        }
13308    }
13309}
13310
13311static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
13312{
13313    word32 i;
13314
13315    B[WC_AES_BLOCK_SIZE - 1] = (byte)(B[WC_AES_BLOCK_SIZE - 1] + 4U);
13316    if (B[WC_AES_BLOCK_SIZE - 1] < 4U) {
13317        for (i = 1; i < lenSz; i++) {
13318            if (++B[WC_AES_BLOCK_SIZE - 1 - i] != 0) break;
13319        }
13320    }
13321}
13322#endif
13323
13324/* Software AES - CCM Encrypt */
13325/* return 0 on success */
13326int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
13327                   const byte* nonce, word32 nonceSz,
13328                   byte* authTag, word32 authTagSz,
13329                   const byte* authIn, word32 authInSz)
13330{
13331#ifdef WOLFSSL_AESNI
13332    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
13333    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
13334#else
13335    byte A[WC_AES_BLOCK_SIZE];
13336    byte B[WC_AES_BLOCK_SIZE];
13337#endif
13338    byte lenSz;
13339    word32 i;
13340    byte mask = 0xFF;
13341    const word32 wordSz = (word32)sizeof(word32);
13342    int ret;
13343
13344    /* sanity check on arguments */
13345    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
13346        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
13347            authTagSz > WC_AES_BLOCK_SIZE)
13348        return BAD_FUNC_ARG;
13349
13350    /* Sanity check on authIn to prevent segfault in xorbuf() where
13351     * variable 'in' is dereferenced as the mask 'm' in misc.c */
13352    if (authIn == NULL && authInSz > 0)
13353        return BAD_FUNC_ARG;
13354
13355    /* sanity check on tag size */
13356    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
13357        return BAD_FUNC_ARG;
13358    }
13359
13360#ifdef WOLF_CRYPTO_CB
13361    #ifndef WOLF_CRYPTO_CB_FIND
13362    if (aes->devId != INVALID_DEVID)
13363    #endif
13364    {
13365        int crypto_cb_ret =
13366            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
13367                                      authTag, authTagSz, authIn, authInSz);
13368        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13369            return crypto_cb_ret;
13370        /* fall-through when unavailable */
13371    }
13372#endif
13373
13374    XMEMSET(A, 0, sizeof(A));
13375    XMEMCPY(B+1, nonce, nonceSz);
13376    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
13377    B[0] = (byte)((authInSz > 0 ? 64 : 0)
13378                  + (8 * (((byte)authTagSz - 2) / 2))
13379                  + (lenSz - 1));
13380    for (i = 0; i < lenSz; i++) {
13381        if (mask && i >= wordSz)
13382            mask = 0x00;
13383        B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
13384    }
13385
13386#ifdef WOLFSSL_CHECK_MEM_ZERO
13387    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
13388#endif
13389
13390    VECTOR_REGISTERS_PUSH;
13391    /* note this wc_AesEncrypt() will perform cache prefetches if needed, so
13392     * that the later encrypt ops don't need to.
13393     */
13394    ret = wc_AesEncrypt(aes, B, A);
13395#ifdef WOLFSSL_CHECK_MEM_ZERO
13396    if (ret == 0)
13397        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
13398#endif
13399
13400    if ((ret == 0) && (authInSz > 0))
13401        ret = roll_auth(aes, authIn, authInSz, A);
13402
13403    if ((ret == 0) && (inSz > 0))
13404        ret = roll_x(aes, in, inSz, A);
13405
13406    if (ret == 0) {
13407        XMEMCPY(authTag, A, authTagSz);
13408
13409        B[0] = (byte)(lenSz - 1U);
13410        for (i = 0; i < lenSz; i++)
13411            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13412        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
13413    }
13414
13415    if (ret == 0) {
13416        xorbuf(authTag, A, authTagSz);
13417        B[15] = 1;
13418    }
13419#ifdef WOLFSSL_AESNI
13420    if ((ret == 0) && aes->use_aesni) {
13421        while (inSz >= WC_AES_BLOCK_SIZE * 4) {
13422            AesCcmCtrIncSet4(B, lenSz);
13423
13424            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
13425                            (int)aes->rounds);
13426
13427            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
13428            XMEMCPY(out, A, WC_AES_BLOCK_SIZE * 4);
13429
13430            inSz -= WC_AES_BLOCK_SIZE * 4;
13431            in += WC_AES_BLOCK_SIZE * 4;
13432            out += WC_AES_BLOCK_SIZE * 4;
13433
13434            AesCcmCtrInc4(B, lenSz);
13435        }
13436    }
13437#endif
13438    if (ret == 0) {
13439        while (inSz >= WC_AES_BLOCK_SIZE) {
13440            ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
13441            if (ret != 0)
13442                break;
13443            xorbuf(A, in, WC_AES_BLOCK_SIZE);
13444            XMEMCPY(out, A, WC_AES_BLOCK_SIZE);
13445
13446            AesCcmCtrInc(B, lenSz);
13447            inSz -= WC_AES_BLOCK_SIZE;
13448            in += WC_AES_BLOCK_SIZE;
13449            out += WC_AES_BLOCK_SIZE;
13450        }
13451    }
13452    if ((ret == 0) && (inSz > 0)) {
13453        ret = AesEncrypt_preFetchOpt(aes, B, A, &never_prefetch);
13454    }
13455    if ((ret == 0) && (inSz > 0)) {
13456        xorbuf(A, in, inSz);
13457        XMEMCPY(out, A, inSz);
13458    }
13459
13460    ForceZero(A, sizeof(A));
13461    ForceZero(B, sizeof(B));
13462
13463#ifdef WOLFSSL_CHECK_MEM_ZERO
13464    wc_MemZero_Check(A, sizeof(A));
13465    wc_MemZero_Check(B, sizeof(B));
13466#endif
13467
13468    VECTOR_REGISTERS_POP;
13469
13470    return ret;
13471}
13472
13473#ifdef HAVE_AES_DECRYPT
13474/* Software AES - CCM Decrypt */
13475int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
13476                   const byte* nonce, word32 nonceSz,
13477                   const byte* authTag, word32 authTagSz,
13478                   const byte* authIn, word32 authInSz)
13479{
13480#ifdef WOLFSSL_AESNI
13481    ALIGN128 byte B[WC_AES_BLOCK_SIZE * 4];
13482    ALIGN128 byte A[WC_AES_BLOCK_SIZE * 4];
13483#else
13484    byte A[WC_AES_BLOCK_SIZE];
13485    byte B[WC_AES_BLOCK_SIZE];
13486#endif
13487    byte* o;
13488    byte lenSz;
13489    word32 i, oSz;
13490    byte mask = 0xFF;
13491    const word32 wordSz = (word32)sizeof(word32);
13492    int ret = 0;
13493#ifdef WC_AES_HAVE_PREFETCH_ARG
13494    int did_prefetches = 0;
13495#endif
13496
13497    /* sanity check on arguments */
13498    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
13499        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
13500        authTagSz > WC_AES_BLOCK_SIZE)
13501        return BAD_FUNC_ARG;
13502
13503    /* Sanity check on authIn to prevent segfault in xorbuf() where
13504     * variable 'in' is dereferenced as the mask 'm' in misc.c */
13505    if (authIn == NULL && authInSz > 0)
13506        return BAD_FUNC_ARG;
13507
13508    /* sanity check on tag size */
13509    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
13510        return BAD_FUNC_ARG;
13511    }
13512
13513#ifdef WOLF_CRYPTO_CB
13514    #ifndef WOLF_CRYPTO_CB_FIND
13515    if (aes->devId != INVALID_DEVID)
13516    #endif
13517    {
13518        int crypto_cb_ret =
13519            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
13520            authTag, authTagSz, authIn, authInSz);
13521        if (crypto_cb_ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13522            return crypto_cb_ret;
13523        /* fall-through when unavailable */
13524    }
13525#endif
13526
13527    o = out;
13528    oSz = inSz;
13529    XMEMSET(A, 0, sizeof A);
13530    XMEMCPY(B+1, nonce, nonceSz);
13531    lenSz = (byte)(WC_AES_BLOCK_SIZE - 1U - nonceSz);
13532
13533    B[0] = (byte)(lenSz - 1U);
13534    for (i = 0; i < lenSz; i++)
13535        B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13536    B[15] = 1;
13537
13538#ifdef WOLFSSL_CHECK_MEM_ZERO
13539    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
13540    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
13541#endif
13542
13543    VECTOR_REGISTERS_PUSH;
13544
13545#ifdef WOLFSSL_AESNI
13546    if (aes->use_aesni) {
13547        while (oSz >= WC_AES_BLOCK_SIZE * 4) {
13548            AesCcmCtrIncSet4(B, lenSz);
13549
13550            AES_ECB_encrypt_AESNI(B, A, WC_AES_BLOCK_SIZE * 4, (byte*)aes->key,
13551                            (int)aes->rounds);
13552
13553            xorbuf(A, in, WC_AES_BLOCK_SIZE * 4);
13554            XMEMCPY(o, A, WC_AES_BLOCK_SIZE * 4);
13555
13556            oSz -= WC_AES_BLOCK_SIZE * 4;
13557            in += WC_AES_BLOCK_SIZE * 4;
13558            o += WC_AES_BLOCK_SIZE * 4;
13559
13560            AesCcmCtrInc4(B, lenSz);
13561        }
13562    }
13563#endif
13564
13565    while (oSz >= WC_AES_BLOCK_SIZE) {
13566        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
13567        if (ret != 0)
13568            break;
13569        xorbuf(A, in, WC_AES_BLOCK_SIZE);
13570        XMEMCPY(o, A, WC_AES_BLOCK_SIZE);
13571        AesCcmCtrInc(B, lenSz);
13572        oSz -= WC_AES_BLOCK_SIZE;
13573        in += WC_AES_BLOCK_SIZE;
13574        o += WC_AES_BLOCK_SIZE;
13575    }
13576
13577    if ((ret == 0) && (inSz > 0))
13578        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
13579
13580    if ((ret == 0) && (inSz > 0)) {
13581        xorbuf(A, in, oSz);
13582        XMEMCPY(o, A, oSz);
13583        for (i = 0; i < lenSz; i++)
13584            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13585        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
13586    }
13587
13588    if (ret == 0) {
13589        o = out;
13590        oSz = inSz;
13591
13592        B[0] = (byte)((authInSz > 0 ? 64 : 0)
13593                      + (8 * (((byte)authTagSz - 2) / 2))
13594                      + (lenSz - 1));
13595        for (i = 0; i < lenSz; i++) {
13596            if (mask && i >= wordSz)
13597                mask = 0x00;
13598            B[WC_AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
13599        }
13600
13601        ret = AesEncrypt_preFetchOpt(aes, B, A, &did_prefetches);
13602    }
13603
13604    if (ret == 0) {
13605        if (authInSz > 0)
13606            ret = roll_auth(aes, authIn, authInSz, A);
13607    }
13608    if ((ret == 0) && (inSz > 0))
13609        ret = roll_x(aes, o, oSz, A);
13610
13611    if (ret == 0) {
13612        B[0] = (byte)(lenSz - 1U);
13613        for (i = 0; i < lenSz; i++)
13614            B[WC_AES_BLOCK_SIZE - 1 - i] = 0;
13615        ret = AesEncrypt_preFetchOpt(aes, B, B, &did_prefetches);
13616    }
13617
13618    if (ret == 0)
13619        xorbuf(A, B, authTagSz);
13620
13621    if (ret == 0) {
13622        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
13623            /* If the authTag check fails, don't keep the decrypted data.
13624             * Unfortunately, you need the decrypted data to calculate the
13625             * check value. */
13626            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
13627                        defined(ACVP_VECTOR_TESTING)
13628            WOLFSSL_MSG("Preserve output for vector responses");
13629            #else
13630            if (inSz > 0)
13631                XMEMSET(out, 0, inSz);
13632            #endif
13633            ret = AES_CCM_AUTH_E;
13634        }
13635    }
13636
13637    ForceZero(A, sizeof(A));
13638    ForceZero(B, sizeof(B));
13639    o = NULL;
13640
13641#ifdef WOLFSSL_CHECK_MEM_ZERO
13642    wc_MemZero_Check(A, sizeof(A));
13643    wc_MemZero_Check(B, sizeof(B));
13644#endif
13645
13646    VECTOR_REGISTERS_POP;
13647
13648    return ret;
13649}
13650
13651#endif /* HAVE_AES_DECRYPT */
13652#endif /* software CCM */
13653
13654/* abstract functions that call lower level AESCCM functions */
13655#ifndef WC_NO_RNG
13656
13657int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
13658{
13659    int ret = 0;
13660
13661    if (aes == NULL || nonce == NULL ||
13662        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
13663
13664        ret = BAD_FUNC_ARG;
13665    }
13666
13667    if (ret == 0) {
13668        XMEMCPY(aes->reg, nonce, nonceSz);
13669        aes->nonceSz = nonceSz;
13670
13671        /* Invocation counter should be 2^61 */
13672        aes->invokeCtr[0] = 0;
13673        aes->invokeCtr[1] = 0xE0000000;
13674    }
13675
13676    return ret;
13677}
13678
13679
13680int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
13681                        byte* ivOut, word32 ivOutSz,
13682                        byte* authTag, word32 authTagSz,
13683                        const byte* authIn, word32 authInSz)
13684{
13685    int ret = 0;
13686
13687    if (aes == NULL || out == NULL ||
13688        (in == NULL && sz != 0) ||
13689        ivOut == NULL ||
13690        (authIn == NULL && authInSz != 0) ||
13691        (ivOutSz != aes->nonceSz)) {
13692
13693        ret = BAD_FUNC_ARG;
13694    }
13695
13696    if (ret == 0) {
13697        aes->invokeCtr[0]++;
13698        if (aes->invokeCtr[0] == 0) {
13699            aes->invokeCtr[1]++;
13700            if (aes->invokeCtr[1] == 0)
13701                ret = AES_CCM_OVERFLOW_E;
13702        }
13703    }
13704
13705    if (ret == 0) {
13706        ret = wc_AesCcmEncrypt(aes, out, in, sz,
13707                               (byte*)aes->reg, aes->nonceSz,
13708                               authTag, authTagSz,
13709                               authIn, authInSz);
13710        if (ret == 0) {
13711            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
13712            IncCtr((byte*)aes->reg, aes->nonceSz);
13713        }
13714    }
13715
13716    return ret;
13717}
13718
13719#endif /* WC_NO_RNG */
13720
13721#endif /* HAVE_AESCCM */
13722
13723#ifndef WC_NO_CONSTRUCTORS
13724
13725#define AES_NEW_INIT_PLAIN  0
13726#ifdef WOLF_PRIVATE_KEY_ID
13727#define AES_NEW_INIT_ID     1
13728#define AES_NEW_INIT_LABEL  2
13729#endif
13730
13731static Aes* _AesNew_common(void* heap, int devId, int *result_code,
13732                            int aesInitType, unsigned char* id,
13733                            int idLen, const char* label)
13734{
13735    int ret;
13736    Aes* aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_AES);
13737    if (aes == NULL) {
13738        ret = MEMORY_E;
13739    }
13740    else {
13741        switch (aesInitType) {
13742#ifdef WOLF_PRIVATE_KEY_ID
13743        case AES_NEW_INIT_ID:
13744            if (id == NULL || idLen == 0 || label != NULL) {
13745                ret = BAD_FUNC_ARG;
13746            }
13747            else {
13748                ret = wc_AesInit_Id(aes, id, idLen, heap, devId);
13749            }
13750            break;
13751        case AES_NEW_INIT_LABEL:
13752            if (label == NULL || id != NULL || idLen != 0) {
13753                ret = BAD_FUNC_ARG;
13754            }
13755            else {
13756                ret = wc_AesInit_Label(aes, label, heap, devId);
13757            }
13758            break;
13759#endif
13760        default:
13761            if (id != NULL || idLen != 0 || label != NULL) {
13762                ret = BAD_FUNC_ARG;
13763            }
13764            else {
13765                ret = wc_AesInit(aes, heap, devId);
13766            }
13767            break;
13768        }
13769        if (ret != 0) {
13770            XFREE(aes, heap, DYNAMIC_TYPE_AES);
13771            aes = NULL;
13772        }
13773    }
13774    (void)aesInitType;
13775    (void)id;
13776    (void)idLen;
13777    (void)label;
13778
13779    if (result_code != NULL) {
13780        *result_code = ret;
13781    }
13782
13783    return aes;
13784}
13785
13786Aes* wc_AesNew(void* heap, int devId, int *result_code)
13787{
13788    return _AesNew_common(heap, devId, result_code,
13789                          AES_NEW_INIT_PLAIN, NULL, 0, NULL);
13790}
13791
13792#ifdef WOLF_PRIVATE_KEY_ID
13793Aes* wc_AesNew_Id(unsigned char* id, int len, void* heap, int devId,
13794                   int *result_code)
13795{
13796    return _AesNew_common(heap, devId, result_code,
13797                          AES_NEW_INIT_ID, id, len, NULL);
13798}
13799
13800Aes* wc_AesNew_Label(const char* label, void* heap, int devId,
13801                      int *result_code)
13802{
13803    return _AesNew_common(heap, devId, result_code,
13804                          AES_NEW_INIT_LABEL, NULL, 0, label);
13805}
13806#endif /* WOLF_PRIVATE_KEY_ID */
13807
13808int wc_AesDelete(Aes *aes, Aes** aes_p)
13809{
13810    void* heap;
13811    if (aes == NULL)
13812        return BAD_FUNC_ARG;
13813    heap = aes->heap;
13814    wc_AesFree(aes);
13815    XFREE(aes, heap, DYNAMIC_TYPE_AES);
13816    if (aes_p != NULL)
13817        *aes_p = NULL;
13818    return 0;
13819}
13820#endif /* !WC_NO_CONSTRUCTORS */
13821
13822/* Initialize Aes */
13823int wc_AesInit(Aes* aes, void* heap, int devId)
13824{
13825    int ret = 0;
13826
13827    if (aes == NULL)
13828        return BAD_FUNC_ARG;
13829
13830    XMEMSET(aes, 0, sizeof(*aes));
13831
13832    aes->heap = heap;
13833
13834#if defined(WOLF_CRYPTO_CB) || defined(WOLFSSL_STM32U5_DHUK)
13835    aes->devId = devId;
13836    aes->devCtx = NULL;
13837#else
13838    (void)devId;
13839#endif
13840#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
13841    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
13842                                                        aes->heap, devId);
13843#endif /* WOLFSSL_ASYNC_CRYPT */
13844
13845#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
13846    aes->alFd = WC_SOCK_NOTSET;
13847    aes->rdFd = WC_SOCK_NOTSET;
13848#endif
13849#if defined(WOLFSSL_DEVCRYPTO) && \
13850   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
13851    aes->ctx.cfd = -1;
13852#endif
13853#if defined(WOLFSSL_IMXRT_DCP)
13854    DCPAesInit(aes);
13855#endif
13856
13857#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
13858    ret = wc_psa_aes_init(aes);
13859#endif
13860
13861#ifdef WC_DEBUG_CIPHER_LIFECYCLE
13862    if (ret == 0)
13863        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
13864#endif
13865
13866    return ret;
13867}
13868
13869#ifdef WOLF_PRIVATE_KEY_ID
13870int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
13871{
13872    int ret = 0;
13873
13874    if (aes == NULL)
13875        ret = BAD_FUNC_ARG;
13876    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
13877        ret = BUFFER_E;
13878
13879    if (ret == 0)
13880        ret = wc_AesInit(aes, heap, devId);
13881    if (ret == 0) {
13882        XMEMCPY(aes->id, id, (size_t)len);
13883        aes->idLen = len;
13884        aes->labelLen = 0;
13885    }
13886
13887    return ret;
13888}
13889
13890int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
13891{
13892    int ret = 0;
13893    size_t labelLen = 0;
13894
13895    if (aes == NULL || label == NULL)
13896        ret = BAD_FUNC_ARG;
13897    if (ret == 0) {
13898        labelLen = XSTRLEN(label);
13899        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
13900            ret = BUFFER_E;
13901    }
13902
13903    if (ret == 0)
13904        ret = wc_AesInit(aes, heap, devId);
13905    if (ret == 0) {
13906        XMEMCPY(aes->label, label, labelLen);
13907        aes->labelLen = (int)labelLen;
13908        aes->idLen = 0;
13909    }
13910
13911    return ret;
13912}
13913#endif
13914
13915/* Free Aes resources */
13916void wc_AesFree(Aes* aes)
13917{
13918    if (aes == NULL) {
13919        return;
13920    }
13921
13922#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
13923    #ifndef WOLF_CRYPTO_CB_FIND
13924    if (aes->devId != INVALID_DEVID)
13925    #endif
13926    {
13927        int ret = wc_CryptoCb_Free(aes->devId, WC_ALGO_TYPE_CIPHER,
13928                                   WC_CIPHER_AES, 0, aes);
13929    #ifdef WOLF_CRYPTO_CB_AES_SETKEY
13930        aes->devCtx = NULL;  /* Clear device context handle */
13931    #endif
13932        /* If callback wants standard free, it can set devId to INVALID_DEVID.
13933         * Otherwise assume the callback handled cleanup. */
13934        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
13935            return;
13936        /* fall-through when unavailable */
13937    }
13938#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
13939
13940#ifdef WC_DEBUG_CIPHER_LIFECYCLE
13941    (void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
13942#endif
13943
13944#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
13945    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
13946#endif /* WOLFSSL_ASYNC_CRYPT */
13947#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
13948    if (aes->rdFd > 0) { /* negative is error case */
13949        close(aes->rdFd);
13950        aes->rdFd = WC_SOCK_NOTSET;
13951    }
13952    if (aes->alFd > 0) {
13953        close(aes->alFd);
13954        aes->alFd = WC_SOCK_NOTSET;
13955    }
13956#endif /* WOLFSSL_AFALG */
13957#ifdef WOLFSSL_KCAPI_AES
13958    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
13959    if (aes->init == 1) {
13960        kcapi_cipher_destroy(aes->handle);
13961    }
13962    aes->init = 0;
13963    aes->handle = NULL;
13964#endif
13965#if defined(WOLFSSL_DEVCRYPTO) && \
13966    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
13967    wc_DevCryptoFree(&aes->ctx);
13968#endif
13969#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
13970    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
13971    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
13972    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
13973#endif
13974#if defined(WOLFSSL_IMXRT_DCP)
13975    DCPAesFree(aes);
13976#endif
13977#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
13978    !defined(WOLFSSL_AESNI)
13979    if (aes->streamData != NULL) {
13980        ForceZero(aes->streamData, aes->streamData_sz);
13981        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
13982        aes->streamData = NULL;
13983    }
13984#endif
13985
13986#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
13987    if (aes->useSWCrypt == 0) {
13988        se050_aes_free(aes);
13989    }
13990#endif
13991#if defined(WOLFSSL_MICROCHIP_TA100) && defined(WOLFSSL_MICROCHIP_AESGCM)
13992    wc_Microchip_aes_free(aes);
13993#endif
13994#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
13995    wc_psa_aes_free(aes);
13996#endif
13997
13998#ifdef WOLFSSL_MAXQ10XX_CRYPTO
13999    wc_MAXQ10XX_AesFree(aes);
14000#endif
14001
14002#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
14003    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
14004    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
14005    wc_fspsm_Aesfree(aes);
14006#endif
14007
14008    ForceZero(aes, sizeof(Aes));
14009
14010#ifdef WOLFSSL_CHECK_MEM_ZERO
14011    wc_MemZero_Check(aes, sizeof(Aes));
14012#endif
14013}
14014
14015int wc_AesGetKeySize(Aes* aes, word32* keySize)
14016{
14017    int ret = 0;
14018
14019    if (aes == NULL || keySize == NULL) {
14020        return BAD_FUNC_ARG;
14021    }
14022
14023#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
14024    return wc_psa_aes_get_key_size(aes, keySize);
14025#endif
14026#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
14027    *keySize = aes->ctx.key.keySize;
14028    return ret;
14029#endif
14030    switch (aes->rounds) {
14031#ifdef WOLFSSL_AES_128
14032    case 10:
14033        *keySize = 16;
14034        break;
14035#endif
14036#ifdef WOLFSSL_AES_192
14037    case 12:
14038        *keySize = 24;
14039        break;
14040#endif
14041#ifdef WOLFSSL_AES_256
14042    case 14:
14043        *keySize = 32;
14044        break;
14045#endif
14046    default:
14047        *keySize = 0;
14048        ret = BAD_FUNC_ARG;
14049    }
14050
14051    return ret;
14052}
14053
14054#endif /* !WOLFSSL_TI_CRYPT */
14055
14056/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
14057 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
14058 */
14059#ifndef VECTOR_REGISTERS_PUSH
14060    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
14061#endif
14062#ifndef VECTOR_REGISTERS_POP
14063    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
14064#endif
14065
14066#ifdef HAVE_AES_ECB
14067#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
14068        !defined(WOLFSSL_QNX_CAAM)
14069    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
14070
14071#elif defined(WOLFSSL_AFALG)
14072    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
14073
14074#elif defined(WOLFSSL_DEVCRYPTO_AES)
14075    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
14076
14077#elif defined(WOLFSSL_RISCV_ASM)
14078    /* implemented in wolfcrypt/src/port/riscv/riscv-64-aes.c */
14079
14080#elif defined(WOLFSSL_NXP_HASHCRYPT_AES)
14081    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
14082
14083#elif defined(WOLFSSL_SILABS_SE_ACCEL)
14084    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
14085
14086#elif defined(MAX3266X_AES)
14087
14088int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14089{
14090    int status;
14091    word32 keySize;
14092
14093    if ((in == NULL) || (out == NULL) || (aes == NULL))
14094        return BAD_FUNC_ARG;
14095
14096    status = wc_AesGetKeySize(aes, &keySize);
14097    if (status != 0) {
14098        return status;
14099    }
14100
14101    status = wc_MXC_TPU_AesEncrypt(in, (byte*)aes->reg, (byte*)aes->key,
14102                                        MXC_TPU_MODE_ECB, sz, out, keySize);
14103
14104    return status;
14105}
14106
14107#ifdef HAVE_AES_DECRYPT
14108int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14109{
14110    int status;
14111    word32 keySize;
14112
14113    if ((in == NULL) || (out == NULL) || (aes == NULL))
14114        return BAD_FUNC_ARG;
14115
14116    status = wc_AesGetKeySize(aes, &keySize);
14117    if (status != 0) {
14118        return status;
14119    }
14120
14121    status = wc_MXC_TPU_AesDecrypt(in, (byte*)aes->reg, (byte*)aes->key,
14122                                        MXC_TPU_MODE_ECB, sz, out, keySize);
14123
14124    return status;
14125}
14126#endif /* HAVE_AES_DECRYPT */
14127
14128#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
14129
14130/* Software AES - ECB */
14131int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14132{
14133    if ((in == NULL) || (out == NULL) || (aes == NULL))
14134        return BAD_FUNC_ARG;
14135
14136    return AES_ECB_encrypt(aes, in, out, sz);
14137}
14138
14139
14140int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14141{
14142    if ((in == NULL) || (out == NULL) || (aes == NULL))
14143        return BAD_FUNC_ARG;
14144
14145    return AES_ECB_decrypt(aes, in, out, sz);
14146}
14147
14148#elif defined(WOLFSSL_PSOC6_CRYPTO)
14149
14150int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14151{
14152    if ((in == NULL) || (out == NULL) || (aes == NULL))
14153        return BAD_FUNC_ARG;
14154
14155    return wc_Psoc6_Aes_EcbEncrypt(aes, out, in, sz);
14156}
14157
14158#define _AesEcbEncrypt(aes, out, in, sz) wc_AesEcbEncrypt(aes, out, in, sz)
14159
14160#ifdef HAVE_AES_DECRYPT
14161int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14162{
14163    if ((in == NULL) || (out == NULL) || (aes == NULL))
14164        return BAD_FUNC_ARG;
14165
14166    return wc_Psoc6_Aes_EcbDecrypt(aes, out, in, sz);
14167}
14168
14169#define _AesEcbDecrypt(aes, out, in, sz) wc_AesEcbDecrypt(aes, out, in, sz)
14170#endif /* HAVE_AES_DECRYPT */
14171
14172#else
14173
14174/* Software AES - ECB */
14175static WARN_UNUSED_RESULT int _AesEcbEncrypt(
14176    Aes* aes, byte* out, const byte* in, word32 sz)
14177{
14178    int ret = 0;
14179
14180#ifdef WOLF_CRYPTO_CB
14181    #ifndef WOLF_CRYPTO_CB_FIND
14182    if (aes->devId != INVALID_DEVID)
14183    #endif
14184    {
14185        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
14186        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
14187            return ret;
14188        ret = 0;
14189        /* fall-through when unavailable */
14190    }
14191#endif
14192#ifdef WOLF_CRYPTO_CB_ONLY_AES
14193    /* No software fallback: the per-block loop below would only re-invoke
14194     * cryptocb ECB and propagate UNAVAILABLE; short-circuit instead. */
14195    return NO_VALID_DEVID;
14196#endif
14197#ifdef WOLFSSL_IMXRT_DCP
14198    if (aes->keylen == 16)
14199        return DCPAesEcbEncrypt(aes, out, in, sz);
14200#endif
14201
14202    VECTOR_REGISTERS_PUSH;
14203
14204#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
14205#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
14206    AES_encrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
14207#else
14208    AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
14209#endif
14210#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
14211#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14212    if (aes->use_aes_hw_crypto) {
14213        AES_encrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
14214            (int)aes->rounds);
14215    }
14216    else
14217#endif
14218#if !defined(WOLFSSL_ARMASM_NO_NEON)
14219#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
14220    if (sz >= 32)
14221#endif
14222    {
14223        AES_ECB_encrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
14224            aes->rounds);
14225    }
14226#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
14227    else
14228#endif
14229#endif
14230#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
14231    {
14232        AES_ECB_encrypt(in, out, sz, (const unsigned char*)aes->key,
14233            aes->rounds);
14234    }
14235#endif
14236#else
14237#ifdef WOLFSSL_AESNI
14238    if (aes->use_aesni) {
14239        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
14240    }
14241    else
14242#endif
14243    {
14244#if defined(NEED_AES_TABLES)
14245        AesEncryptBlocks_C(aes, in, out, sz);
14246#else
14247        word32 i;
14248#ifdef WC_AES_HAVE_PREFETCH_ARG
14249        int did_prefetches = 0;
14250#endif
14251
14252        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
14253            ret = AesEncrypt_preFetchOpt(aes, in, out, &did_prefetches);
14254            if (ret != 0)
14255                break;
14256            in += WC_AES_BLOCK_SIZE;
14257            out += WC_AES_BLOCK_SIZE;
14258        }
14259#endif
14260    }
14261#endif
14262
14263    VECTOR_REGISTERS_POP;
14264
14265    return ret;
14266}
14267
14268#ifdef HAVE_AES_DECRYPT
14269static WARN_UNUSED_RESULT int _AesEcbDecrypt(
14270    Aes* aes, byte* out, const byte* in, word32 sz)
14271{
14272    int ret = 0;
14273
14274#ifdef WOLF_CRYPTO_CB
14275    #ifndef WOLF_CRYPTO_CB_FIND
14276    if (aes->devId != INVALID_DEVID)
14277    #endif
14278    {
14279        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
14280        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
14281            return ret;
14282        ret = 0;
14283        /* fall-through when unavailable */
14284    }
14285#endif
14286#ifdef WOLF_CRYPTO_CB_ONLY_AES
14287    return NO_VALID_DEVID;
14288#endif
14289#ifdef WOLFSSL_IMXRT_DCP
14290    if (aes->keylen == 16)
14291        return DCPAesEcbDecrypt(aes, out, in, sz);
14292#endif
14293
14294    VECTOR_REGISTERS_PUSH;
14295
14296#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM)
14297#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
14298    AES_decrypt_blocks_AARCH32(in, out, sz, (byte*)aes->key, (int)aes->rounds);
14299#else
14300    AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key, aes->rounds);
14301#endif
14302#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
14303#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
14304    if (aes->use_aes_hw_crypto) {
14305        AES_decrypt_blocks_AARCH64(in, out, sz, (byte*)aes->key,
14306            (int)aes->rounds);
14307    }
14308    else
14309#endif
14310#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
14311#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
14312    if (sz >= 64)
14313#endif
14314    {
14315        AES_ECB_decrypt_NEON(in, out, sz, (const unsigned char*)aes->key,
14316            aes->rounds);
14317    }
14318#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
14319    else
14320#endif
14321#endif
14322#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
14323    {
14324        AES_ECB_decrypt(in, out, sz, (const unsigned char*)aes->key,
14325            aes->rounds);
14326    }
14327#endif
14328#else
14329#ifdef WOLFSSL_AESNI
14330    if (aes->use_aesni) {
14331        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
14332    }
14333    else
14334#endif
14335    {
14336#if defined(NEED_AES_TABLES)
14337        AesDecryptBlocks_C(aes, in, out, sz);
14338#else
14339        word32 i;
14340
14341        for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) {
14342            ret = wc_AesDecryptDirect(aes, out, in);
14343            if (ret != 0)
14344                break;
14345            in += WC_AES_BLOCK_SIZE;
14346            out += WC_AES_BLOCK_SIZE;
14347        }
14348#endif
14349    }
14350#endif
14351
14352    VECTOR_REGISTERS_POP;
14353
14354    return ret;
14355}
14356#endif
14357
14358int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14359{
14360    if ((in == NULL) || (out == NULL) || (aes == NULL))
14361      return BAD_FUNC_ARG;
14362    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
14363        return BAD_LENGTH_E;
14364    }
14365
14366    return _AesEcbEncrypt(aes, out, in, sz);
14367}
14368
14369#ifdef HAVE_AES_DECRYPT
14370int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14371{
14372    if ((in == NULL) || (out == NULL) || (aes == NULL))
14373      return BAD_FUNC_ARG;
14374    if ((sz % WC_AES_BLOCK_SIZE) != 0) {
14375        return BAD_LENGTH_E;
14376    }
14377
14378    return _AesEcbDecrypt(aes, out, in, sz);
14379}
14380#endif /* HAVE_AES_DECRYPT */
14381#endif
14382#endif /* HAVE_AES_ECB */
14383
14384#if defined(WOLFSSL_AES_CFB)
14385
14386#if defined(WOLFSSL_NXP_HASHCRYPT_AES)
14387    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
14388
14389#elif defined(WOLFSSL_PSOC6_CRYPTO)
14390
14391int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14392{
14393    return wc_Psoc6_Aes_CfbEncrypt(aes, out, in, sz);
14394}
14395
14396#ifdef HAVE_AES_DECRYPT
14397int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14398{
14399    return wc_Psoc6_Aes_CfbDecrypt(aes, out, in, sz);
14400}
14401#endif /* HAVE_AES_DECRYPT */
14402
14403#else
14404/* Feedback AES mode
14405 *
14406 * aes structure holding key to use for encryption
14407 * out buffer to hold result of encryption (must be at least as large as input
14408 *     buffer)
14409 * in  buffer to encrypt
14410 * sz  size of input buffer
14411 * mode flag to specify AES mode
14412 *
14413 * returns 0 on success and negative error values on failure
14414 */
14415/* Software AES - CFB Encrypt */
14416static WARN_UNUSED_RESULT int AesCfbEncrypt_C(Aes* aes, byte* out,
14417    const byte* in, word32 sz)
14418{
14419    int ret = 0;
14420    word32 processed;
14421#ifdef WC_AES_HAVE_PREFETCH_ARG
14422    int did_prefetches = 0;
14423#endif
14424
14425    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
14426        return BAD_FUNC_ARG;
14427    }
14428    if (sz == 0) {
14429        return 0;
14430    }
14431
14432    if (aes->left > 0) {
14433        /* consume any unused bytes left in aes->tmp */
14434        processed = min(aes->left, sz);
14435        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
14436            processed);
14437        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, out,
14438            processed);
14439        aes->left -= processed;
14440        out += processed;
14441        in += processed;
14442        sz -= processed;
14443    }
14444
14445    VECTOR_REGISTERS_PUSH;
14446
14447    while (sz >= WC_AES_BLOCK_SIZE) {
14448        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
14449                                        &did_prefetches);
14450        if (ret != 0) {
14451            break;
14452        }
14453        xorbuf((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
14454        XMEMCPY(out, aes->reg, WC_AES_BLOCK_SIZE);
14455        out += WC_AES_BLOCK_SIZE;
14456        in  += WC_AES_BLOCK_SIZE;
14457        sz  -= WC_AES_BLOCK_SIZE;
14458    }
14459
14460    /* encrypt left over data */
14461    if ((ret == 0) && sz) {
14462        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14463                                     &did_prefetches);
14464        if (ret == 0) {
14465            xorbufout(out, in, aes->tmp, sz);
14466            XMEMCPY(aes->reg, out, sz);
14467            aes->left = WC_AES_BLOCK_SIZE - sz;
14468        }
14469    }
14470
14471    VECTOR_REGISTERS_POP;
14472
14473    return ret;
14474}
14475
14476
14477#if defined(HAVE_AES_DECRYPT)
14478/* CFB 128
14479 *
14480 * aes structure holding key to use for decryption
14481 * out buffer to hold result of decryption (must be at least as large as input
14482 *     buffer)
14483 * in  buffer to decrypt
14484 * sz  size of input buffer
14485 *
14486 * returns 0 on success and negative error values on failure
14487 */
14488/* Software AES - CFB Decrypt */
14489static WARN_UNUSED_RESULT int AesCfbDecrypt_C(Aes* aes, byte* out,
14490    const byte* in, word32 sz, byte mode)
14491{
14492    int ret = 0;
14493    word32 processed;
14494#ifdef WC_AES_HAVE_PREFETCH_ARG
14495    int did_prefetches = 0;
14496#endif
14497
14498    (void)mode;
14499
14500    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
14501        return BAD_FUNC_ARG;
14502    }
14503    if (sz == 0) {
14504        return 0;
14505    }
14506
14507    if (aes->left > 0) {
14508        /* consume any unused bytes left in aes->tmp */
14509        processed = min(aes->left, sz);
14510        /* copy input over to aes->reg */
14511        XMEMCPY((byte*)aes->reg + WC_AES_BLOCK_SIZE - aes->left, in, processed);
14512        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
14513            processed);
14514        aes->left -= processed;
14515        out += processed;
14516        in += processed;
14517        sz -= processed;
14518    }
14519
14520    VECTOR_REGISTERS_PUSH;
14521
14522    #if !defined(WOLFSSL_SMALL_STACK) && defined(HAVE_AES_ECB) && \
14523        !defined(WOLFSSL_PIC32MZ_CRYPT) && \
14524        (defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM))
14525    {
14526        ALIGN16 byte tmp[4 * WC_AES_BLOCK_SIZE];
14527        while (sz >= 4 * WC_AES_BLOCK_SIZE) {
14528            XMEMCPY(tmp, aes->reg, WC_AES_BLOCK_SIZE);
14529            XMEMCPY(tmp + WC_AES_BLOCK_SIZE, in, 3 * WC_AES_BLOCK_SIZE);
14530            XMEMCPY(aes->reg, in + 3 * WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
14531            ret = wc_AesEcbEncrypt(aes, tmp, tmp, 4 * WC_AES_BLOCK_SIZE);
14532            if (ret != 0) {
14533                break;
14534            }
14535            xorbufout(out, in, tmp, 4 * WC_AES_BLOCK_SIZE);
14536            out += 4 * WC_AES_BLOCK_SIZE;
14537            in  += 4 * WC_AES_BLOCK_SIZE;
14538            sz  -= 4 * WC_AES_BLOCK_SIZE;
14539        }
14540    }
14541    #endif
14542    while (sz >= WC_AES_BLOCK_SIZE) {
14543        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14544                                        &did_prefetches);
14545        if (ret != 0) {
14546            break;
14547        }
14548        XMEMCPY((byte*)aes->reg, in, WC_AES_BLOCK_SIZE);
14549        xorbufout(out, in, (byte*)aes->tmp, WC_AES_BLOCK_SIZE);
14550        out += WC_AES_BLOCK_SIZE;
14551        in  += WC_AES_BLOCK_SIZE;
14552        sz  -= WC_AES_BLOCK_SIZE;
14553    }
14554
14555    /* decrypt left over data */
14556    if ((ret == 0) && sz) {
14557        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14558                                        &did_prefetches);
14559        if (ret == 0) {
14560            XMEMCPY(aes->reg, in, sz);
14561            xorbufout(out, in, aes->tmp, sz);
14562            aes->left = WC_AES_BLOCK_SIZE - sz;
14563        }
14564    }
14565
14566    VECTOR_REGISTERS_POP;
14567
14568    return ret;
14569}
14570#endif /* HAVE_AES_DECRYPT */
14571
14572/* CFB 128
14573 *
14574 * aes structure holding key to use for encryption
14575 * out buffer to hold result of encryption (must be at least as large as input
14576 *     buffer)
14577 * in  buffer to encrypt
14578 * sz  size of input buffer
14579 *
14580 * returns 0 on success and negative error values on failure
14581 */
14582/* Software AES - CFB Encrypt */
14583int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14584{
14585    return AesCfbEncrypt_C(aes, out, in, sz);
14586}
14587
14588
14589#ifdef HAVE_AES_DECRYPT
14590/* CFB 128
14591 *
14592 * aes structure holding key to use for decryption
14593 * out buffer to hold result of decryption (must be at least as large as input
14594 *     buffer)
14595 * in  buffer to decrypt
14596 * sz  size of input buffer
14597 *
14598 * returns 0 on success and negative error values on failure
14599 */
14600/* Software AES - CFB Decrypt */
14601int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14602{
14603    return AesCfbDecrypt_C(aes, out, in, sz, AES_CFB_MODE);
14604}
14605#endif /* HAVE_AES_DECRYPT */
14606#endif /* WOLFSSL_PSOC6_CRYPTO */
14607
14608#ifndef WOLFSSL_NO_AES_CFB_1_8
14609/* shift the whole WC_AES_BLOCK_SIZE array left by 8 or 1 bits */
14610static void shiftLeftArray(byte* ary, byte shift)
14611{
14612    int i;
14613
14614    if (shift == WOLFSSL_BIT_SIZE) {
14615        /* shifting over by 8 bits */
14616        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
14617            ary[i] = ary[i+1];
14618        }
14619        ary[i] = 0;
14620    }
14621    else {
14622        /* shifting over by 7 or less bits */
14623        for (i = 0; i < WC_AES_BLOCK_SIZE - 1; i++) {
14624            byte carry = (byte)(ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)));
14625            carry = (byte)(carry >> (WOLFSSL_BIT_SIZE - shift));
14626            ary[i] = (byte)((ary[i] << shift) + carry);
14627        }
14628        ary[i] = (byte)(ary[i] << shift);
14629    }
14630}
14631
14632
14633/* returns 0 on success and negative values on failure */
14634static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
14635    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
14636{
14637    byte *pt;
14638    int ret = 0;
14639#ifdef WC_AES_HAVE_PREFETCH_ARG
14640    int did_prefetches = 0;
14641#endif
14642
14643    if (aes == NULL || out == NULL || in == NULL) {
14644        return BAD_FUNC_ARG;
14645    }
14646
14647    if (sz == 0) {
14648        return 0;
14649    }
14650
14651    VECTOR_REGISTERS_PUSH;
14652
14653    while (sz > 0) {
14654        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14655                                        &did_prefetches);
14656        if (ret != 0)
14657            break;
14658        if (dir == AES_DECRYPTION) {
14659            pt = (byte*)aes->reg;
14660
14661            /* LSB + CAT */
14662            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
14663            pt[WC_AES_BLOCK_SIZE - 1] = in[0];
14664        }
14665
14666        /* MSB + XOR */
14667    #ifdef BIG_ENDIAN_ORDER
14668        ByteReverseWords(aes->tmp, aes->tmp, WC_AES_BLOCK_SIZE);
14669    #endif
14670        out[0] = (byte)(aes->tmp[0] ^ in[0]);
14671        if (dir == AES_ENCRYPTION) {
14672            pt = (byte*)aes->reg;
14673
14674            /* LSB + CAT */
14675            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
14676            pt[WC_AES_BLOCK_SIZE - 1] = out[0];
14677        }
14678
14679        out += 1;
14680        in  += 1;
14681        sz  -= 1;
14682    }
14683
14684    VECTOR_REGISTERS_POP;
14685
14686    return ret;
14687}
14688
14689
14690/* returns 0 on success and negative values on failure */
14691static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
14692    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
14693{
14694    byte tmp;
14695    byte cur = 0; /* hold current work in order to handle inline in=out */
14696    byte* pt;
14697    int bit = 7;
14698    int ret = 0;
14699#ifdef WC_AES_HAVE_PREFETCH_ARG
14700    int did_prefetches = 0;
14701#endif
14702
14703    if (aes == NULL || out == NULL || in == NULL) {
14704        return BAD_FUNC_ARG;
14705    }
14706
14707    if (sz == 0) {
14708        return 0;
14709    }
14710
14711    VECTOR_REGISTERS_PUSH;
14712
14713    while (sz > 0) {
14714        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14715                                        &did_prefetches);
14716        if (ret != 0)
14717            break;
14718        if (dir == AES_DECRYPTION) {
14719            pt = (byte*)aes->reg;
14720
14721            /* LSB + CAT */
14722            tmp = (byte)((0X01U << bit) & in[0]);
14723            tmp = (byte)(tmp >> bit);
14724            tmp &= 0x01;
14725            shiftLeftArray((byte*)aes->reg, 1);
14726            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
14727        }
14728
14729        /* MSB  + XOR */
14730        tmp = (byte)((0X01U << bit) & in[0]);
14731        pt = (byte*)aes->tmp;
14732        tmp = (byte)((pt[0] >> 7) ^ (tmp >> bit));
14733        tmp &= 0x01;
14734        cur = (byte)(cur | (tmp << bit));
14735
14736
14737        if (dir == AES_ENCRYPTION) {
14738            pt = (byte*)aes->reg;
14739
14740            /* LSB + CAT */
14741            shiftLeftArray((byte*)aes->reg, 1);
14742            pt[WC_AES_BLOCK_SIZE - 1] |= tmp;
14743        }
14744
14745        bit--;
14746        if (bit < 0) {
14747            out[0] = cur;
14748            out += 1;
14749            in  += 1;
14750            sz  -= 1;
14751            bit = 7U;
14752            cur = 0;
14753        }
14754        else {
14755            sz -= 1;
14756        }
14757    }
14758
14759    if (ret == 0) {
14760        if (bit >= 0 && bit < 7) {
14761            out[0] = cur;
14762        }
14763    }
14764
14765    VECTOR_REGISTERS_POP;
14766
14767    return ret;
14768}
14769
14770
14771/* CFB 1
14772 *
14773 * aes structure holding key to use for encryption
14774 * out buffer to hold result of encryption (must be at least as large as input
14775 *     buffer)
14776 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
14777 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
14778 *
14779 * returns 0 on success and negative values on failure
14780 */
14781int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14782{
14783    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
14784}
14785
14786
14787/* CFB 8
14788 *
14789 * aes structure holding key to use for encryption
14790 * out buffer to hold result of encryption (must be at least as large as input
14791 *     buffer)
14792 * in  buffer to encrypt
14793 * sz  size of input buffer
14794 *
14795 * returns 0 on success and negative values on failure
14796 */
14797int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14798{
14799    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
14800}
14801#ifdef HAVE_AES_DECRYPT
14802
14803/* CFB 1
14804 *
14805 * aes structure holding key to use for encryption
14806 * out buffer to hold result of encryption (must be at least as large as input
14807 *     buffer)
14808 * in  buffer to encrypt
14809 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
14810 *
14811 * returns 0 on success and negative values on failure
14812 */
14813int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14814{
14815    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
14816}
14817
14818
14819/* CFB 8
14820 *
14821 * aes structure holding key to use for encryption
14822 * out buffer to hold result of encryption (must be at least as large as input
14823 *     buffer)
14824 * in  buffer to encrypt
14825 * sz  size of input buffer
14826 *
14827 * returns 0 on success and negative values on failure
14828 */
14829int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14830{
14831    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
14832}
14833#endif /* HAVE_AES_DECRYPT */
14834#endif /* !WOLFSSL_NO_AES_CFB_1_8 */
14835#endif /* WOLFSSL_AES_CFB */
14836
14837#ifdef WOLFSSL_AES_OFB
14838#ifdef WOLFSSL_NXP_HASHCRYPT_AES
14839    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
14840
14841#else /* software */
14842/* OFB AES mode
14843 *
14844 * aes structure holding key to use for encryption
14845 * out buffer to hold result of encryption (must be at least as large as input
14846 *     buffer)
14847 * in  buffer to encrypt
14848 * sz  size of input buffer
14849 *
14850 * returns 0 on success and negative error values on failure
14851 */
14852/* Software AES - OFB Encrypt/Decrypt */
14853static WARN_UNUSED_RESULT int AesOfbCrypt_C(Aes* aes, byte* out, const byte* in,
14854    word32 sz)
14855{
14856    int ret = 0;
14857    word32 processed;
14858#ifdef WC_AES_HAVE_PREFETCH_ARG
14859    int did_prefetches = 0;
14860#endif
14861
14862    if ((aes == NULL) || (out == NULL) || (in == NULL)) {
14863        return BAD_FUNC_ARG;
14864    }
14865    if (sz == 0) {
14866        return 0;
14867    }
14868
14869    if (aes->left > 0) {
14870        /* consume any unused bytes left in aes->tmp */
14871        processed = min(aes->left, sz);
14872        xorbufout(out, in, (byte*)aes->tmp + WC_AES_BLOCK_SIZE - aes->left,
14873            processed);
14874        aes->left -= processed;
14875        out += processed;
14876        in += processed;
14877        sz -= processed;
14878    }
14879
14880    VECTOR_REGISTERS_PUSH;
14881
14882    while (sz >= WC_AES_BLOCK_SIZE) {
14883        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->reg,
14884                                        &did_prefetches);
14885        if (ret != 0) {
14886            break;
14887        }
14888        xorbufout(out, in, (byte*)aes->reg, WC_AES_BLOCK_SIZE);
14889        out += WC_AES_BLOCK_SIZE;
14890        in  += WC_AES_BLOCK_SIZE;
14891        sz  -= WC_AES_BLOCK_SIZE;
14892    }
14893
14894    /* encrypt left over data */
14895    if ((ret == 0) && sz) {
14896        ret = AesEncrypt_preFetchOpt(aes, (byte*)aes->reg, (byte*)aes->tmp,
14897                                        &did_prefetches);
14898        if (ret == 0) {
14899            XMEMCPY(aes->reg, aes->tmp, WC_AES_BLOCK_SIZE);
14900            xorbufout(out, in, aes->tmp, sz);
14901            aes->left = WC_AES_BLOCK_SIZE - sz;
14902        }
14903    }
14904
14905    VECTOR_REGISTERS_POP;
14906
14907    return ret;
14908}
14909
14910/* OFB
14911 *
14912 * aes structure holding key to use for encryption
14913 * out buffer to hold result of encryption (must be at least as large as input
14914 *     buffer)
14915 * in  buffer to encrypt
14916 * sz  size of input buffer
14917 *
14918 * returns 0 on success and negative error values on failure
14919 */
14920/* Software AES - OFB Encrypt */
14921int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14922{
14923    return AesOfbCrypt_C(aes, out, in, sz);
14924}
14925
14926
14927#ifdef HAVE_AES_DECRYPT
14928/* OFB
14929 *
14930 * aes structure holding key to use for decryption
14931 * out buffer to hold result of decryption (must be at least as large as input
14932 *     buffer)
14933 * in  buffer to decrypt
14934 * sz  size of input buffer
14935 *
14936 * returns 0 on success and negative error values on failure
14937 */
14938/* Software AES - OFB Decrypt */
14939int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
14940{
14941    return AesOfbCrypt_C(aes, out, in, sz);
14942}
14943#endif /* HAVE_AES_DECRYPT */
14944#endif /* software */
14945#endif /* WOLFSSL_AES_OFB */
14946
14947
14948#ifdef HAVE_AES_KEYWRAP
14949
14950/* Initialize key wrap counter with value */
14951static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
14952{
14953    word32 i;
14954    word32 bytes;
14955
14956    bytes = sizeof(word32);
14957    for (i = 0; i < sizeof(word32); i++) {
14958        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
14959        bytes--;
14960    }
14961}
14962
14963/* Increment key wrap counter */
14964static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
14965{
14966    int i;
14967
14968    /* in network byte order so start at end and work back */
14969    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
14970        if (++inOutCtr[i])  /* we're done unless we overflow */
14971            return;
14972    }
14973}
14974
14975/* Decrement key wrap counter */
14976static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
14977{
14978    int i;
14979
14980    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
14981        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
14982            return;
14983    }
14984}
14985
14986int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
14987        word32 outSz, const byte* iv)
14988{
14989    word32 i;
14990    byte* r;
14991    int j;
14992    int ret = 0;
14993
14994    byte t[KEYWRAP_BLOCK_SIZE];
14995    byte tmp[WC_AES_BLOCK_SIZE];
14996
14997    /* n must be at least 2 64-bit blocks, output size is (n + 1) 8 bytes (64-bit) */
14998    if (aes == NULL || in  == NULL || inSz < 2*KEYWRAP_BLOCK_SIZE ||
14999        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
15000        return BAD_FUNC_ARG;
15001
15002    /* input must be multiple of 64-bits */
15003    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
15004        return BAD_FUNC_ARG;
15005
15006    r = out + 8;
15007    XMEMCPY(r, in, inSz);
15008    XMEMSET(t, 0, sizeof(t));
15009
15010    /* user IV is optional */
15011    if (iv == NULL) {
15012        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
15013    } else {
15014        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
15015    }
15016
15017    VECTOR_REGISTERS_PUSH;
15018
15019    for (j = 0; j <= 5; j++) {
15020        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
15021            /* load R[i] */
15022            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
15023
15024            ret = wc_AesEncryptDirect(aes, tmp, tmp);
15025            if (ret != 0)
15026                break;
15027
15028            /* calculate new A */
15029            IncrementKeyWrapCounter(t);
15030            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
15031
15032            /* save R[i] */
15033            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
15034            r += KEYWRAP_BLOCK_SIZE;
15035        }
15036        if (ret != 0)
15037            break;
15038        r = out + KEYWRAP_BLOCK_SIZE;
15039    }
15040
15041    VECTOR_REGISTERS_POP;
15042
15043    if (ret != 0)
15044        return ret;
15045
15046    /* C[0] = A */
15047    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
15048
15049    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
15050}
15051
15052/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
15053int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
15054                  byte* out, word32 outSz, const byte* iv)
15055{
15056    WC_DECLARE_VAR(aes, Aes, 1, 0);
15057    int ret;
15058
15059    if (key == NULL)
15060        return BAD_FUNC_ARG;
15061
15062#ifdef WOLFSSL_SMALL_STACK
15063    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
15064                              DYNAMIC_TYPE_AES)) == NULL)
15065        return MEMORY_E;
15066#endif
15067
15068    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15069    if (ret != 0)
15070        goto out;
15071
15072    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
15073    if (ret != 0) {
15074        wc_AesFree(aes);
15075        goto out;
15076    }
15077
15078    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
15079
15080    wc_AesFree(aes);
15081
15082  out:
15083    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
15084
15085    return ret;
15086}
15087
15088int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
15089        word32 outSz, const byte* iv)
15090{
15091    byte* r;
15092    word32 i, n;
15093    int j;
15094    int ret = 0;
15095
15096    byte t[KEYWRAP_BLOCK_SIZE];
15097    byte tmp[WC_AES_BLOCK_SIZE];
15098
15099    const byte* expIv;
15100    const byte defaultIV[] = {
15101        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
15102    };
15103
15104    if (aes == NULL || in == NULL || inSz < 3 * KEYWRAP_BLOCK_SIZE ||
15105        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
15106        return BAD_FUNC_ARG;
15107
15108    /* input must be multiple of 64-bits */
15109    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
15110        return BAD_FUNC_ARG;
15111
15112    /* user IV optional */
15113    if (iv != NULL)
15114        expIv = iv;
15115    else
15116        expIv = defaultIV;
15117
15118    /* A = C[0], R[i] = C[i] */
15119    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
15120    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
15121    XMEMSET(t, 0, sizeof(t));
15122
15123    VECTOR_REGISTERS_PUSH;
15124
15125    /* initialize counter to 6n */
15126    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
15127    InitKeyWrapCounter(t, 6 * n);
15128
15129    for (j = 5; j >= 0; j--) {
15130        for (i = n; i >= 1; i--) {
15131
15132            /* calculate A */
15133            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
15134            DecrementKeyWrapCounter(t);
15135
15136            /* load R[i], starting at end of R */
15137            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
15138            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
15139            ret = wc_AesDecryptDirect(aes, tmp, tmp);
15140            if (ret != 0)
15141                break;
15142
15143            /* save R[i] */
15144            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
15145        }
15146        if (ret != 0)
15147            break;
15148    }
15149
15150    VECTOR_REGISTERS_POP;
15151
15152    if (ret != 0)
15153        return ret;
15154
15155    /* verify IV */
15156    if (ConstantCompare(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
15157        return BAD_KEYWRAP_IV_E;
15158
15159    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
15160}
15161
15162int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
15163                    byte* out, word32 outSz, const byte* iv)
15164{
15165    WC_DECLARE_VAR(aes, Aes, 1, 0);
15166    int ret;
15167
15168    (void)iv;
15169
15170    if (key == NULL)
15171        return BAD_FUNC_ARG;
15172
15173#ifdef WOLFSSL_SMALL_STACK
15174    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
15175                              DYNAMIC_TYPE_AES)) == NULL)
15176        return MEMORY_E;
15177#endif
15178
15179
15180    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
15181    if (ret != 0)
15182        goto out;
15183
15184    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
15185    if (ret != 0) {
15186        wc_AesFree(aes);
15187        goto out;
15188    }
15189
15190    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
15191
15192    wc_AesFree(aes);
15193
15194  out:
15195    WC_FREE_VAR_EX(aes, NULL, DYNAMIC_TYPE_AES);
15196
15197    return ret;
15198}
15199
15200#endif /* HAVE_AES_KEYWRAP */
15201
15202#ifdef WOLFSSL_AES_XTS
15203
15204/* Galois Field to use */
15205#define GF_XTS 0x87
15206
15207/* Set up keys for encryption and/or decryption.
15208 *
15209 * aes   buffer holding aes subkeys
15210 * heap  heap hint to use for memory. Can be NULL
15211 * devId id to use with async crypto. Can be 0
15212 *
15213 * return 0 on success
15214 */
15215int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
15216{
15217    int    ret = 0;
15218
15219    if (aes == NULL) {
15220        return BAD_FUNC_ARG;
15221    }
15222
15223    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
15224        return ret;
15225    }
15226    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
15227        (void)wc_AesFree(&aes->tweak);
15228        return ret;
15229    }
15230#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15231    if ((ret = wc_AesInit(&aes->aes_decrypt, heap, devId)) != 0) {
15232        (void)wc_AesFree(&aes->tweak);
15233        (void)wc_AesFree(&aes->aes);
15234        return ret;
15235    }
15236#endif
15237
15238    return 0;
15239}
15240
15241/* Set up keys for encryption and/or decryption.
15242 *
15243 * aes   buffer holding aes subkeys
15244 * key   AES key for encrypt/decrypt and tweak process (concatenated)
15245 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
15246 *       32 for a 16 byte key.
15247 * dir   direction: AES_ENCRYPTION, AES_DECRYPTION, or
15248 *       AES_ENCRYPTION_AND_DECRYPTION
15249 *
15250 * return 0 on success
15251 */
15252int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
15253{
15254    word32 keySz;
15255    int    ret = 0;
15256
15257    if (aes == NULL || key == NULL) {
15258        return BAD_FUNC_ARG;
15259    }
15260
15261    if ((dir != AES_ENCRYPTION) && (dir != AES_DECRYPTION)
15262#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15263        && (dir != AES_ENCRYPTION_AND_DECRYPTION)
15264#endif
15265        )
15266    {
15267        return BAD_FUNC_ARG;
15268    }
15269
15270    if ((len != (AES_128_KEY_SIZE*2)) &&
15271#ifndef HAVE_FIPS
15272        /* XTS-384 not allowed by FIPS and can not be treated like
15273         * RSA-4096 bit keys back in the day, can not vendor affirm
15274         * the use of 2 concatenated 192-bit keys (XTS-384) */
15275        (len != (AES_192_KEY_SIZE*2)) &&
15276#endif
15277        (len != (AES_256_KEY_SIZE*2)))
15278    {
15279        WOLFSSL_MSG("Unsupported key size");
15280        return WC_KEY_SIZE_E;
15281    }
15282
15283    keySz = len/2;
15284
15285#ifdef HAVE_FIPS
15286    if (XMEMCMP(key, key + keySz, keySz) == 0) {
15287        WOLFSSL_MSG("FIPS AES-XTS main and tweak keys must differ");
15288        return BAD_FUNC_ARG;
15289    }
15290#endif
15291
15292    if (dir == AES_ENCRYPTION
15293#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15294        || dir == AES_ENCRYPTION_AND_DECRYPTION
15295#endif
15296        )
15297    {
15298        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_ENCRYPTION);
15299    }
15300
15301#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15302    if ((ret == 0) && ((dir == AES_DECRYPTION)
15303                       || (dir == AES_ENCRYPTION_AND_DECRYPTION)))
15304        ret = wc_AesSetKey(&aes->aes_decrypt, key, keySz, NULL, AES_DECRYPTION);
15305#else
15306    if (dir == AES_DECRYPTION)
15307        ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, AES_DECRYPTION);
15308#endif
15309
15310    if (ret == 0)
15311        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
15312                AES_ENCRYPTION);
15313
15314#ifdef WOLFSSL_AESNI
15315    if (ret == 0) {
15316        /* With WC_C_DYNAMIC_FALLBACK, the main and tweak keys could have
15317         * conflicting _aesni status, but the AES-XTS asm implementations need
15318         * them to all be AESNI.  If any aren't, disable AESNI on all.
15319         */
15320    #ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15321        if ((((dir == AES_ENCRYPTION) ||
15322              (dir == AES_ENCRYPTION_AND_DECRYPTION))
15323             && (aes->aes.use_aesni != aes->tweak.use_aesni))
15324            ||
15325            (((dir == AES_DECRYPTION) ||
15326              (dir == AES_ENCRYPTION_AND_DECRYPTION))
15327             && (aes->aes_decrypt.use_aesni != aes->tweak.use_aesni)))
15328        {
15329        #ifdef WC_C_DYNAMIC_FALLBACK
15330            aes->aes.use_aesni = 0;
15331            aes->aes_decrypt.use_aesni = 0;
15332            aes->tweak.use_aesni = 0;
15333        #else
15334            ret = SYSLIB_FAILED_E;
15335        #endif
15336        }
15337    #else /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
15338        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
15339        #ifdef WC_C_DYNAMIC_FALLBACK
15340            aes->aes.use_aesni = 0;
15341            aes->tweak.use_aesni = 0;
15342        #else
15343            ret = SYSLIB_FAILED_E;
15344        #endif
15345        }
15346    #endif /* !WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS */
15347    }
15348#endif /* WOLFSSL_AESNI */
15349
15350    return ret;
15351}
15352
15353/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
15354 *
15355 * Note: is up to user to call wc_AesXtsFree when done.
15356 *
15357 * return 0 on success
15358 */
15359int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
15360        void* heap, int devId)
15361{
15362    int    ret = 0;
15363
15364    if (aes == NULL || key == NULL) {
15365        return BAD_FUNC_ARG;
15366    }
15367
15368    ret = wc_AesXtsInit(aes, heap, devId);
15369    if (ret != 0)
15370        return ret;
15371
15372    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
15373
15374    if (ret != 0)
15375        wc_AesXtsFree(aes);
15376
15377    return ret;
15378}
15379
15380
15381/* This is used to free up resources used by Aes structs
15382 *
15383 * aes AES keys to free
15384 *
15385 * return 0 on success
15386 */
15387int wc_AesXtsFree(XtsAes* aes)
15388{
15389    if (aes != NULL) {
15390        wc_AesFree(&aes->aes);
15391#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
15392        wc_AesFree(&aes->aes_decrypt);
15393#endif
15394        wc_AesFree(&aes->tweak);
15395    }
15396
15397    return 0;
15398}
15399
15400
15401/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
15402 * instead of a byte array. This just converts the word64 to a byte array and
15403 * calls wc_AesXtsEncrypt.
15404 *
15405 * aes    AES keys to use for block encrypt/decrypt
15406 * out    output buffer to hold cipher text
15407 * in     input plain text buffer to encrypt
15408 * sz     size of both out and in buffers
15409 * sector value to use for tweak
15410 *
15411 * returns 0 on success
15412 */
15413int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
15414        word32 sz, word64 sector)
15415{
15416    byte* pt;
15417    byte  i[WC_AES_BLOCK_SIZE];
15418
15419    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
15420#ifdef BIG_ENDIAN_ORDER
15421    sector = ByteReverseWord64(sector);
15422#endif
15423    pt = (byte*)&sector;
15424    XMEMCPY(i, pt, sizeof(word64));
15425
15426    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
15427}
15428
15429#ifdef HAVE_AES_DECRYPT
15430/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
15431 * instead of a byte array. This just converts the word64 to a byte array.
15432 *
15433 * aes    AES keys to use for block encrypt/decrypt
15434 * out    output buffer to hold plain text
15435 * in     input cipher text buffer to encrypt
15436 * sz     size of both out and in buffers
15437 * sector value to use for tweak
15438 *
15439 * returns 0 on success
15440 */
15441int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
15442        word64 sector)
15443{
15444    byte* pt;
15445    byte  i[WC_AES_BLOCK_SIZE];
15446
15447    XMEMSET(i, 0, WC_AES_BLOCK_SIZE);
15448#ifdef BIG_ENDIAN_ORDER
15449    sector = ByteReverseWord64(sector);
15450#endif
15451    pt = (byte*)&sector;
15452    XMEMCPY(i, pt, sizeof(word64));
15453
15454    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, WC_AES_BLOCK_SIZE);
15455}
15456#endif
15457
15458#ifdef WOLFSSL_AESNI
15459
15460#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP)
15461    #define USE_INTEL_SPEEDUP
15462#endif
15463
15464#if defined(USE_INTEL_SPEEDUP)
15465    #define HAVE_INTEL_AVX1
15466    #define HAVE_INTEL_AVX2
15467#endif /* USE_INTEL_SPEEDUP */
15468
15469void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
15470                     const unsigned char* i, const unsigned char* key,
15471                     const unsigned char* key2, int nr)
15472                     XASM_LINK("AES_XTS_encrypt_aesni");
15473#ifdef WOLFSSL_AESXTS_STREAM
15474void AES_XTS_init_aesni(unsigned char* i, const unsigned char* tweak_key,
15475                     int tweak_nr)
15476                     XASM_LINK("AES_XTS_init_aesni");
15477void AES_XTS_encrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
15478                     const unsigned char* key, unsigned char *i, int nr)
15479                     XASM_LINK("AES_XTS_encrypt_update_aesni");
15480#endif
15481#ifdef HAVE_INTEL_AVX1
15482void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
15483                     word32 sz, const unsigned char* i,
15484                     const unsigned char* key, const unsigned char* key2,
15485                     int nr)
15486                     XASM_LINK("AES_XTS_encrypt_avx1");
15487#ifdef WOLFSSL_AESXTS_STREAM
15488void AES_XTS_init_avx1(unsigned char* i, const unsigned char* tweak_key,
15489                     int tweak_nr)
15490                     XASM_LINK("AES_XTS_init_avx1");
15491void AES_XTS_encrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
15492                     const unsigned char* key, unsigned char *i, int nr)
15493                     XASM_LINK("AES_XTS_encrypt_update_avx1");
15494#endif
15495#endif /* HAVE_INTEL_AVX1 */
15496
15497#ifdef HAVE_AES_DECRYPT
15498void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
15499                     const unsigned char* i, const unsigned char* key,
15500                     const unsigned char* key2, int nr)
15501                     XASM_LINK("AES_XTS_decrypt_aesni");
15502#ifdef WOLFSSL_AESXTS_STREAM
15503void AES_XTS_decrypt_update_aesni(const unsigned char *in, unsigned char *out, word32 sz,
15504                     const unsigned char* key, unsigned char *i, int nr)
15505                     XASM_LINK("AES_XTS_decrypt_update_aesni");
15506#endif
15507#ifdef HAVE_INTEL_AVX1
15508void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
15509                     word32 sz, const unsigned char* i,
15510                     const unsigned char* key, const unsigned char* key2,
15511                     int nr)
15512                     XASM_LINK("AES_XTS_decrypt_avx1");
15513#ifdef WOLFSSL_AESXTS_STREAM
15514void AES_XTS_decrypt_update_avx1(const unsigned char *in, unsigned char *out, word32 sz,
15515                     const unsigned char* key, unsigned char *i, int nr)
15516                     XASM_LINK("AES_XTS_decrypt_update_avx1");
15517#endif
15518#endif /* HAVE_INTEL_AVX1 */
15519#endif /* HAVE_AES_DECRYPT */
15520
15521#endif /* WOLFSSL_AESNI */
15522
15523#ifdef HAVE_AES_ECB
15524#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15525    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
15526/* helper function for encrypting / decrypting full buffer at once */
15527static WARN_UNUSED_RESULT int _AesXtsHelper(
15528    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
15529{
15530    word32 outSz   = sz;
15531    word32 totalSz = (sz / WC_AES_BLOCK_SIZE) * WC_AES_BLOCK_SIZE; /* total bytes */
15532    byte*  pt      = out;
15533
15534    outSz -= WC_AES_BLOCK_SIZE;
15535
15536    while (outSz > 0) {
15537        word32 j;
15538        byte carry = 0;
15539
15540        /* multiply by shift left and propagate carry */
15541        for (j = 0; j < WC_AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
15542            byte tmpC;
15543
15544            tmpC   = (pt[j] >> 7) & 0x01;
15545            pt[j+WC_AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
15546            carry  = tmpC;
15547        }
15548        if (carry) {
15549            pt[WC_AES_BLOCK_SIZE] ^= GF_XTS;
15550        }
15551
15552        pt += WC_AES_BLOCK_SIZE;
15553    }
15554
15555    xorbuf(out, in, totalSz);
15556#ifndef WOLFSSL_RISCV_ASM
15557    if (dir == AES_ENCRYPTION) {
15558        return _AesEcbEncrypt(aes, out, out, totalSz);
15559    }
15560    else {
15561        return _AesEcbDecrypt(aes, out, out, totalSz);
15562    }
15563#else
15564    if (dir == AES_ENCRYPTION) {
15565        return wc_AesEcbEncrypt(aes, out, out, totalSz);
15566    }
15567    else {
15568        return wc_AesEcbDecrypt(aes, out, out, totalSz);
15569    }
15570#endif
15571}
15572#endif
15573#endif /* HAVE_AES_ECB */
15574
15575/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
15576 *
15577 * xaes  AES keys to use for block encrypt/decrypt
15578 * out   output buffer to hold cipher text
15579 * in    input plain text buffer to encrypt
15580 * sz    size of both out and in buffers
15581 * i     value to use for tweak
15582 *
15583 * returns 0 on success
15584 */
15585/* Software AES - XTS Encrypt  */
15586
15587#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15588    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
15589static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15590                                  word32 sz,
15591                                  byte *i);
15592static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15593        const byte* i)
15594{
15595    int ret;
15596    byte tweak_block[WC_AES_BLOCK_SIZE];
15597
15598    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
15599    if (ret != 0)
15600        return ret;
15601
15602    return AesXtsEncryptUpdate_sw(xaes, out, in, sz, tweak_block);
15603}
15604#endif
15605
15606#ifdef WOLFSSL_AESXTS_STREAM
15607
15608/* Block-streaming AES-XTS tweak setup.
15609 *
15610 * xaes  AES keys to use for block encrypt/decrypt
15611 * i     readwrite value to use for tweak
15612 *
15613 * returns 0 on success
15614 */
15615static int AesXtsInitTweak_sw(XtsAes* xaes, byte* i) {
15616    return wc_AesEncryptDirect(&xaes->tweak, i, i);
15617}
15618
15619#endif /* WOLFSSL_AESXTS_STREAM */
15620
15621#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
15622    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)) || defined(WOLFSSL_AESXTS_STREAM)
15623/* Block-streaming AES-XTS.
15624 *
15625 * Supply block-aligned input data with successive calls.  Final call need not
15626 * be block aligned.
15627 *
15628 * xaes  AES keys to use for block encrypt/decrypt
15629 * out   output buffer to hold cipher text
15630 * in    input plain text buffer to encrypt
15631 * sz    size of both out and in buffers
15632 *
15633 * returns 0 on success
15634 */
15635/* Software AES - XTS Encrypt  */
15636static int AesXtsEncryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
15637                                  word32 sz,
15638                                  byte *i)
15639{
15640    int ret = 0;
15641    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
15642    Aes *aes = &xaes->aes;
15643
15644#ifdef HAVE_AES_ECB
15645    /* encrypt all of buffer at once when possible */
15646    if (in != out) { /* can not handle inline */
15647        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
15648        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
15649            return ret;
15650    }
15651#endif
15652
15653    while (blocks > 0) {
15654        word32 j;
15655        byte carry = 0;
15656
15657#ifdef HAVE_AES_ECB
15658        if (in == out)
15659#endif
15660        { /* check for if inline */
15661            byte buf[WC_AES_BLOCK_SIZE];
15662
15663            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
15664            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15665            ret = wc_AesEncryptDirect(aes, out, buf);
15666            if (ret != 0)
15667                return ret;
15668        }
15669        xorbuf(out, i, WC_AES_BLOCK_SIZE);
15670
15671        /* multiply by shift left and propagate carry */
15672        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
15673            byte tmpC;
15674
15675            tmpC   = (i[j] >> 7) & 0x01;
15676            i[j] = (byte)((i[j] << 1) + carry);
15677            carry  = tmpC;
15678        }
15679        if (carry) {
15680            i[0] ^= GF_XTS;
15681        }
15682
15683        in  += WC_AES_BLOCK_SIZE;
15684        out += WC_AES_BLOCK_SIZE;
15685        sz  -= WC_AES_BLOCK_SIZE;
15686        blocks--;
15687    }
15688
15689    /* stealing operation of XTS to handle left overs */
15690    if (sz > 0) {
15691        byte buf[WC_AES_BLOCK_SIZE];
15692
15693        XMEMCPY(buf, out - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
15694        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
15695            return BUFFER_E;
15696        }
15697        if (in != out) {
15698            XMEMCPY(out, buf, sz);
15699            XMEMCPY(buf, in, sz);
15700        }
15701        else {
15702            byte buf2[WC_AES_BLOCK_SIZE];
15703
15704            XMEMCPY(buf2, buf, sz);
15705            XMEMCPY(buf, in, sz);
15706            XMEMCPY(out, buf2, sz);
15707        }
15708
15709        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
15710        ret = wc_AesEncryptDirect(aes, out - WC_AES_BLOCK_SIZE, buf);
15711        if (ret == 0)
15712            xorbuf(out - WC_AES_BLOCK_SIZE, i, WC_AES_BLOCK_SIZE);
15713    }
15714
15715    return ret;
15716}
15717#endif
15718
15719/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
15720 *
15721 * xaes  AES keys to use for block encrypt/decrypt
15722 * out   output buffer to hold cipher text
15723 * in    input plain text buffer to encrypt
15724 * sz    size of both out and in buffers
15725 * i     value to use for tweak
15726 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15727 *       adds a sanity check on how the user calls the function.
15728 *
15729 * returns 0 on success
15730 */
15731int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15732        const byte* i, word32 iSz)
15733{
15734    int ret;
15735
15736    Aes *aes;
15737
15738    if (xaes == NULL || out == NULL || in == NULL) {
15739        return BAD_FUNC_ARG;
15740    }
15741
15742#if FIPS_VERSION3_GE(6,0,0)
15743    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
15744     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
15745     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
15746     */
15747    if (sz > FIPS_AES_XTS_MAX_BYTES_PER_TWEAK) {
15748        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
15749        return BAD_FUNC_ARG;
15750    }
15751#endif
15752
15753    aes = &xaes->aes;
15754
15755    if (aes->keylen == 0) {
15756        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
15757        return BAD_FUNC_ARG;
15758    }
15759
15760    if (iSz < WC_AES_BLOCK_SIZE) {
15761        return BAD_FUNC_ARG;
15762    }
15763
15764    if (sz < WC_AES_BLOCK_SIZE) {
15765        WOLFSSL_MSG("Plain text input too small for encryption");
15766        return BAD_FUNC_ARG;
15767    }
15768
15769#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
15770      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15771    AES_XTS_encrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
15772        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15773    ret = 0;
15774#elif defined(WOLFSSL_AESNI)
15775    if (aes->use_aesni) {
15776        SAVE_VECTOR_REGISTERS(return _svr_ret;);
15777#if defined(HAVE_INTEL_AVX1)
15778        if (IS_INTEL_AVX1(intel_flags)) {
15779            AES_XTS_encrypt_avx1(in, out, sz, i,
15780                                 (const byte*)aes->key,
15781                                 (const byte*)xaes->tweak.key,
15782                                 (int)aes->rounds);
15783            ret = 0;
15784        }
15785        else
15786#endif
15787        {
15788            AES_XTS_encrypt_aesni(in, out, sz, i,
15789                                  (const byte*)aes->key,
15790                                  (const byte*)xaes->tweak.key,
15791                                  (int)aes->rounds);
15792            ret = 0;
15793        }
15794        RESTORE_VECTOR_REGISTERS();
15795    }
15796    else {
15797        ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
15798    }
15799#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
15800#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
15801    if (aes->use_aes_hw_crypto) {
15802        AES_XTS_encrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
15803            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15804        ret = 0;
15805    }
15806    else
15807#endif
15808#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
15809#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15810    if (sz >= 32)
15811#endif
15812    {
15813        AES_XTS_encrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
15814            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15815        ret = 0;
15816    }
15817#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15818    else
15819#endif
15820#endif
15821#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
15822    {
15823        AES_XTS_encrypt(in, out, sz, i, (byte*)xaes->aes.key,
15824            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
15825        ret = 0;
15826    }
15827#endif
15828#else
15829    ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
15830#endif
15831
15832    return ret;
15833}
15834
15835#ifdef WOLFSSL_AESXTS_STREAM
15836
15837/* Block-streaming AES-XTS.
15838 *
15839 * xaes  AES keys to use for block encrypt/decrypt
15840 * i     readwrite value to use for tweak
15841 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15842 *       adds a sanity check on how the user calls the function.
15843 *
15844 * returns 0 on success
15845 */
15846int wc_AesXtsEncryptInit(XtsAes* xaes, const byte* i, word32 iSz,
15847                         struct XtsAesStreamData *stream)
15848{
15849    int ret;
15850
15851    Aes *aes;
15852
15853    if ((xaes == NULL) || (i == NULL) || (stream == NULL)) {
15854        return BAD_FUNC_ARG;
15855    }
15856
15857    if (iSz < WC_AES_BLOCK_SIZE) {
15858        return BAD_FUNC_ARG;
15859    }
15860
15861    aes = &xaes->aes;
15862
15863    if (aes->keylen == 0) {
15864        WOLFSSL_MSG("wc_AesXtsEncrypt called with unset encryption key.");
15865        return BAD_FUNC_ARG;
15866    }
15867
15868    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
15869    stream->bytes_crypted_with_this_tweak = 0;
15870
15871    {
15872#ifdef WOLFSSL_AESNI
15873        if (aes->use_aesni) {
15874            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15875#if defined(HAVE_INTEL_AVX1)
15876            if (IS_INTEL_AVX1(intel_flags)) {
15877                AES_XTS_init_avx1(stream->tweak_block,
15878                                  (const byte*)xaes->tweak.key,
15879                                  (int)xaes->tweak.rounds);
15880                ret = 0;
15881            }
15882            else
15883#endif
15884            {
15885                AES_XTS_init_aesni(stream->tweak_block,
15886                                   (const byte*)xaes->tweak.key,
15887                                   (int)xaes->tweak.rounds);
15888                ret = 0;
15889            }
15890            RESTORE_VECTOR_REGISTERS();
15891        }
15892        else
15893#endif /* WOLFSSL_AESNI */
15894        {
15895            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
15896        }
15897    }
15898
15899    return ret;
15900}
15901
15902/* Block-streaming AES-XTS
15903 *
15904 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
15905 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsEncryptUpdate().
15906 * wc_AesXtsEncryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
15907 *
15908 * xaes  AES keys to use for block encrypt/decrypt
15909 * out   output buffer to hold cipher text
15910 * in    input plain text buffer to encrypt
15911 * sz    size of both out and in buffers -- must be >= WC_AES_BLOCK_SIZE.
15912 * i     value to use for tweak
15913 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
15914 *       adds a sanity check on how the user calls the function.
15915 *
15916 * returns 0 on success
15917 */
15918static int AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
15919                           struct XtsAesStreamData *stream)
15920{
15921    int ret;
15922
15923#ifdef WOLFSSL_AESNI
15924    Aes *aes;
15925#endif
15926
15927    if (xaes == NULL || out == NULL || in == NULL) {
15928        return BAD_FUNC_ARG;
15929    }
15930
15931#ifdef WOLFSSL_AESNI
15932    aes = &xaes->aes;
15933#endif
15934
15935    if (sz < WC_AES_BLOCK_SIZE) {
15936        WOLFSSL_MSG("Plain text input too small for encryption");
15937        return BAD_FUNC_ARG;
15938    }
15939
15940    if (stream->bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))
15941    {
15942        WOLFSSL_MSG("Call to AesXtsEncryptUpdate after previous finalizing call");
15943        return BAD_FUNC_ARG;
15944    }
15945
15946#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
15947    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
15948                             stream->bytes_crypted_with_this_tweak))
15949    {
15950        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
15951                    "in AesXtsEncryptUpdate().");
15952    }
15953#endif
15954#if FIPS_VERSION3_GE(6,0,0)
15955    /* SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
15956     * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
15957     * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes)
15958     */
15959    if (stream->bytes_crypted_with_this_tweak >
15960        FIPS_AES_XTS_MAX_BYTES_PER_TWEAK)
15961    {
15962        WOLFSSL_MSG("Request exceeds allowed bytes per SP800-38E");
15963        return BAD_FUNC_ARG;
15964    }
15965#endif
15966    {
15967#ifdef WOLFSSL_AESNI
15968        if (aes->use_aesni) {
15969            SAVE_VECTOR_REGISTERS(return _svr_ret;);
15970#if defined(HAVE_INTEL_AVX1)
15971            if (IS_INTEL_AVX1(intel_flags)) {
15972                AES_XTS_encrypt_update_avx1(in, out, sz,
15973                                            (const byte*)aes->key,
15974                                            stream->tweak_block,
15975                                            (int)aes->rounds);
15976                ret = 0;
15977            }
15978            else
15979#endif
15980            {
15981                AES_XTS_encrypt_update_aesni(in, out, sz,
15982                                            (const byte*)aes->key,
15983                                            stream->tweak_block,
15984                                            (int)aes->rounds);
15985                ret = 0;
15986            }
15987            RESTORE_VECTOR_REGISTERS();
15988        }
15989        else
15990#endif /* WOLFSSL_AESNI */
15991        {
15992            ret = AesXtsEncryptUpdate_sw(xaes, out, in, sz, stream->tweak_block);
15993        }
15994    }
15995
15996    return ret;
15997}
15998
15999int wc_AesXtsEncryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16000                           struct XtsAesStreamData *stream)
16001{
16002    if (stream == NULL)
16003        return BAD_FUNC_ARG;
16004    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
16005        return BAD_FUNC_ARG;
16006    return AesXtsEncryptUpdate(xaes, out, in, sz, stream);
16007}
16008
16009int wc_AesXtsEncryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16010                           struct XtsAesStreamData *stream)
16011{
16012    int ret;
16013    if (stream == NULL)
16014        return BAD_FUNC_ARG;
16015    if (sz > 0)
16016        ret = AesXtsEncryptUpdate(xaes, out, in, sz, stream);
16017    else
16018        ret = 0;
16019    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
16020     * after finalization.
16021     */
16022    stream->bytes_crypted_with_this_tweak |= 1U;
16023    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
16024#ifdef WOLFSSL_CHECK_MEM_ZERO
16025    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
16026#endif
16027    return ret;
16028}
16029
16030#endif /* WOLFSSL_AESXTS_STREAM */
16031
16032#ifdef HAVE_AES_DECRYPT
16033
16034/* Same process as encryption but use aes_decrypt key.
16035 *
16036 * xaes  AES keys to use for block encrypt/decrypt
16037 * out   output buffer to hold plain text
16038 * in    input cipher text buffer to decrypt
16039 * sz    size of both out and in buffers
16040 * i     value to use for tweak
16041 *
16042 * returns 0 on success
16043 */
16044/* Software AES - XTS Decrypt */
16045
16046#if !defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
16047    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))
16048static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
16049                                  word32 sz, byte *i);
16050
16051static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16052        const byte* i)
16053{
16054    int ret;
16055    byte tweak_block[WC_AES_BLOCK_SIZE];
16056
16057    ret = wc_AesEncryptDirect(&xaes->tweak, tweak_block, i);
16058    if (ret != 0)
16059        return ret;
16060
16061    return AesXtsDecryptUpdate_sw(xaes, out, in, sz, tweak_block);
16062}
16063#endif
16064
16065#if (!defined(WOLFSSL_ARMASM) || (!defined(__aarch64__) && \
16066    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO))) || defined(WOLFSSL_AESXTS_STREAM)
16067/* Block-streaming AES-XTS.
16068 *
16069 * Same process as encryption but use decrypt key.
16070 *
16071 * Supply block-aligned input data with successive calls.  Final call need not
16072 * be block aligned.
16073 *
16074 * xaes  AES keys to use for block encrypt/decrypt
16075 * out   output buffer to hold plain text
16076 * in    input cipher text buffer to decrypt
16077 * sz    size of both out and in buffers
16078 * i     value to use for tweak
16079 *
16080 * returns 0 on success
16081 */
16082/* Software AES - XTS Decrypt */
16083static int AesXtsDecryptUpdate_sw(XtsAes* xaes, byte* out, const byte* in,
16084                                  word32 sz, byte *i)
16085{
16086    int ret = 0;
16087    word32 blocks = (sz / WC_AES_BLOCK_SIZE);
16088#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16089    Aes *aes = &xaes->aes_decrypt;
16090#else
16091    Aes *aes = &xaes->aes;
16092#endif
16093    word32 j;
16094    byte carry = 0;
16095    byte stl = (sz % WC_AES_BLOCK_SIZE);
16096
16097    /* if Stealing then break out of loop one block early to handle special
16098     * case */
16099    if (stl > 0) {
16100        blocks--;
16101    }
16102
16103#ifdef HAVE_AES_ECB
16104    /* decrypt all of buffer at once when possible */
16105    if (in != out) { /* can not handle inline */
16106        XMEMCPY(out, i, WC_AES_BLOCK_SIZE);
16107        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
16108            return ret;
16109    }
16110#endif
16111
16112    while (blocks > 0) {
16113#ifdef HAVE_AES_ECB
16114        if (in == out)
16115#endif
16116        { /* check for if inline */
16117            byte buf[WC_AES_BLOCK_SIZE];
16118
16119            XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
16120            xorbuf(buf, i, WC_AES_BLOCK_SIZE);
16121            ret = wc_AesDecryptDirect(aes, out, buf);
16122            if (ret != 0)
16123                return ret;
16124        }
16125        xorbuf(out, i, WC_AES_BLOCK_SIZE);
16126
16127        /* multiply by shift left and propagate carry */
16128        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
16129            byte tmpC;
16130
16131            tmpC   = (i[j] >> 7) & 0x01;
16132            i[j] = (byte)((i[j] << 1) + carry);
16133            carry  = tmpC;
16134        }
16135        if (carry) {
16136            i[0] ^= GF_XTS;
16137        }
16138        carry = 0;
16139
16140        in  += WC_AES_BLOCK_SIZE;
16141        out += WC_AES_BLOCK_SIZE;
16142        sz  -= WC_AES_BLOCK_SIZE;
16143        blocks--;
16144    }
16145
16146    /* stealing operation of XTS to handle left overs */
16147    if (sz >= WC_AES_BLOCK_SIZE) {
16148        byte buf[WC_AES_BLOCK_SIZE];
16149        byte tmp2[WC_AES_BLOCK_SIZE];
16150
16151        /* multiply by shift left and propagate carry */
16152        for (j = 0; j < WC_AES_BLOCK_SIZE; j++) {
16153            byte tmpC;
16154
16155            tmpC   = (i[j] >> 7) & 0x01;
16156            tmp2[j] = (byte)((i[j] << 1) + carry);
16157            carry  = tmpC;
16158        }
16159        if (carry) {
16160            tmp2[0] ^= GF_XTS;
16161        }
16162
16163        XMEMCPY(buf, in, WC_AES_BLOCK_SIZE);
16164        xorbuf(buf, tmp2, WC_AES_BLOCK_SIZE);
16165        ret = wc_AesDecryptDirect(aes, out, buf);
16166        if (ret != 0)
16167            return ret;
16168        xorbuf(out, tmp2, WC_AES_BLOCK_SIZE);
16169
16170        /* tmp2 holds partial | last */
16171        XMEMCPY(tmp2, out, WC_AES_BLOCK_SIZE);
16172        in  += WC_AES_BLOCK_SIZE;
16173        out += WC_AES_BLOCK_SIZE;
16174        sz  -= WC_AES_BLOCK_SIZE;
16175
16176        /* Make buffer with end of cipher text | last */
16177        XMEMCPY(buf, tmp2, WC_AES_BLOCK_SIZE);
16178        if (sz >= WC_AES_BLOCK_SIZE) { /* extra sanity check before copy */
16179            return BUFFER_E;
16180        }
16181        XMEMCPY(buf, in,   sz);
16182        XMEMCPY(out, tmp2, sz);
16183
16184        xorbuf(buf, i, WC_AES_BLOCK_SIZE);
16185        ret = wc_AesDecryptDirect(aes, tmp2, buf);
16186        if (ret != 0)
16187            return ret;
16188        xorbuf(tmp2, i, WC_AES_BLOCK_SIZE);
16189        XMEMCPY(out - WC_AES_BLOCK_SIZE, tmp2, WC_AES_BLOCK_SIZE);
16190    }
16191
16192    return ret;
16193}
16194#endif
16195
16196/* Same process as encryption but Aes key is AES_DECRYPTION type.
16197 *
16198 * xaes  AES keys to use for block encrypt/decrypt
16199 * out   output buffer to hold plain text
16200 * in    input cipher text buffer to decrypt
16201 * sz    size of both out and in buffers
16202 * i     value to use for tweak
16203 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
16204 *       adds a sanity check on how the user calls the function.
16205 *
16206 * returns 0 on success
16207 */
16208int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16209        const byte* i, word32 iSz)
16210{
16211    int ret;
16212    Aes *aes;
16213
16214    if (xaes == NULL || out == NULL || in == NULL) {
16215        return BAD_FUNC_ARG;
16216    }
16217
16218#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16219    aes = &xaes->aes_decrypt;
16220#else
16221    aes = &xaes->aes;
16222#endif
16223
16224/* FIPS TODO: SP800-38E - Restrict data unit to 2^20 blocks per key. A block is
16225 * WC_AES_BLOCK_SIZE or 16-bytes (128-bits). So each key may only be used to
16226 * protect up to 1,048,576 blocks of WC_AES_BLOCK_SIZE (16,777,216 bytes or
16227 * 134,217,728-bits) Add helpful printout and message along with BAD_FUNC_ARG
16228 * return whenever sz / WC_AES_BLOCK_SIZE > 1,048,576 or equal to that and sz is
16229 * not a sequence of complete blocks.
16230 */
16231
16232    if (aes->keylen == 0) {
16233        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
16234        return BAD_FUNC_ARG;
16235    }
16236
16237    if (iSz < WC_AES_BLOCK_SIZE) {
16238        return BAD_FUNC_ARG;
16239    }
16240
16241    if (sz < WC_AES_BLOCK_SIZE) {
16242        WOLFSSL_MSG("Cipher text input too small for decryption");
16243        return BAD_FUNC_ARG;
16244    }
16245
16246#if !defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \
16247      !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16248    AES_XTS_decrypt_AARCH32(in, out, sz, i, (byte*)xaes->aes.key,
16249        (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
16250    ret = 0;
16251#elif defined(WOLFSSL_AESNI)
16252    if (aes->use_aesni) {
16253        SAVE_VECTOR_REGISTERS(return _svr_ret;);
16254#if defined(HAVE_INTEL_AVX1)
16255        if (IS_INTEL_AVX1(intel_flags)) {
16256            AES_XTS_decrypt_avx1(in, out, sz, i,
16257                                 (const byte*)aes->key,
16258                                 (const byte*)xaes->tweak.key,
16259                                 (int)aes->rounds);
16260            ret = 0;
16261        }
16262        else
16263#endif
16264        {
16265            AES_XTS_decrypt_aesni(in, out, sz, i,
16266                                  (const byte*)aes->key,
16267                                  (const byte*)xaes->tweak.key,
16268                                  (int)aes->rounds);
16269            ret = 0;
16270        }
16271        RESTORE_VECTOR_REGISTERS();
16272    }
16273    else {
16274        ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
16275    }
16276#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM)
16277#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
16278    if (aes->use_aes_hw_crypto) {
16279        AES_XTS_decrypt_AARCH64(in, out, sz, i, (byte*)xaes->aes.key,
16280            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
16281        ret = 0;
16282    }
16283    else
16284#endif
16285#if defined(__aarch64__) && !defined(WOLFSSL_ARMASM_NO_NEON)
16286#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16287    if (sz >= 64)
16288#endif
16289    {
16290        AES_XTS_decrypt_NEON(in, out, sz, i, (byte*)xaes->aes.key,
16291            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
16292        ret = 0;
16293    }
16294#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16295    else
16296#endif
16297#endif
16298#ifndef WOLFSSL_ARMASM_NEON_NO_TABLE_LOOKUP
16299    {
16300        AES_XTS_decrypt(in, out, sz, i, (byte*)xaes->aes.key,
16301            (byte*)xaes->tweak.key, (byte*)xaes->aes.tmp, xaes->aes.rounds);
16302        ret = 0;
16303    }
16304#endif
16305#else
16306    ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
16307#endif
16308
16309    return ret;
16310}
16311
16312#ifdef WOLFSSL_AESXTS_STREAM
16313
16314/* Same process as encryption but Aes key is AES_DECRYPTION type.
16315 *
16316 * xaes  AES keys to use for block encrypt/decrypt
16317 * i     readwrite value to use for tweak
16318 * iSz   size of i buffer, should always be WC_AES_BLOCK_SIZE but having this input
16319 *       adds a sanity check on how the user calls the function.
16320 *
16321 * returns 0 on success
16322 */
16323int wc_AesXtsDecryptInit(XtsAes* xaes, const byte* i, word32 iSz,
16324                         struct XtsAesStreamData *stream)
16325{
16326    int ret;
16327    Aes *aes;
16328
16329    if (xaes == NULL) {
16330        return BAD_FUNC_ARG;
16331    }
16332
16333#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16334    aes = &xaes->aes_decrypt;
16335#else
16336    aes = &xaes->aes;
16337#endif
16338
16339    if (aes->keylen == 0) {
16340        WOLFSSL_MSG("wc_AesXtsDecrypt called with unset decryption key.");
16341        return BAD_FUNC_ARG;
16342    }
16343
16344    if (iSz < WC_AES_BLOCK_SIZE) {
16345        return BAD_FUNC_ARG;
16346    }
16347
16348    XMEMCPY(stream->tweak_block, i, WC_AES_BLOCK_SIZE);
16349    stream->bytes_crypted_with_this_tweak = 0;
16350
16351    {
16352#ifdef WOLFSSL_AESNI
16353        if (aes->use_aesni) {
16354            SAVE_VECTOR_REGISTERS(return _svr_ret;);
16355#if defined(HAVE_INTEL_AVX1)
16356            if (IS_INTEL_AVX1(intel_flags)) {
16357                AES_XTS_init_avx1(stream->tweak_block,
16358                                  (const byte*)xaes->tweak.key,
16359                                  (int)xaes->tweak.rounds);
16360                ret = 0;
16361            }
16362            else
16363#endif
16364            {
16365                AES_XTS_init_aesni(stream->tweak_block,
16366                                   (const byte*)xaes->tweak.key,
16367                                   (int)xaes->tweak.rounds);
16368                ret = 0;
16369            }
16370            RESTORE_VECTOR_REGISTERS();
16371        }
16372        else
16373#endif /* WOLFSSL_AESNI */
16374        {
16375            ret = AesXtsInitTweak_sw(xaes, stream->tweak_block);
16376        }
16377
16378    }
16379
16380    return ret;
16381}
16382
16383/* Block-streaming AES-XTS
16384 *
16385 * Note that sz must be >= WC_AES_BLOCK_SIZE in each call, and must be a multiple
16386 * of WC_AES_BLOCK_SIZE in each call to wc_AesXtsDecryptUpdate().
16387 * wc_AesXtsDecryptFinal() can handle any length >= WC_AES_BLOCK_SIZE.
16388 *
16389 * xaes  AES keys to use for block encrypt/decrypt
16390 * out   output buffer to hold plain text
16391 * in    input cipher text buffer to decrypt
16392 * sz    size of both out and in buffers
16393 * i     tweak buffer of size WC_AES_BLOCK_SIZE.
16394 *
16395 * returns 0 on success
16396 */
16397static int AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16398                           struct XtsAesStreamData *stream)
16399{
16400    int ret;
16401#ifdef WOLFSSL_AESNI
16402    Aes *aes;
16403#endif
16404
16405    if (xaes == NULL || out == NULL || in == NULL) {
16406        return BAD_FUNC_ARG;
16407    }
16408
16409#ifdef WOLFSSL_AESNI
16410#ifdef WC_AES_XTS_SUPPORT_SIMULTANEOUS_ENC_AND_DEC_KEYS
16411    aes = &xaes->aes_decrypt;
16412#else
16413    aes = &xaes->aes;
16414#endif
16415#endif
16416
16417    if (sz < WC_AES_BLOCK_SIZE) {
16418        WOLFSSL_MSG("Cipher text input too small for decryption");
16419        return BAD_FUNC_ARG;
16420    }
16421
16422    if (stream->bytes_crypted_with_this_tweak &
16423        ((word32)WC_AES_BLOCK_SIZE - 1U))
16424    {
16425        WOLFSSL_MSG("AesXtsDecryptUpdate after previous finalizing call");
16426        return BAD_FUNC_ARG;
16427    }
16428
16429#ifndef WC_AESXTS_STREAM_NO_REQUEST_ACCOUNTING
16430    if (! WC_SAFE_SUM_WORD32(stream->bytes_crypted_with_this_tweak, sz,
16431                             stream->bytes_crypted_with_this_tweak))
16432    {
16433        WOLFSSL_MSG("Overflow of stream->bytes_crypted_with_this_tweak "
16434                    "in AesXtsDecryptUpdate().");
16435    }
16436#endif
16437
16438    {
16439#ifdef WOLFSSL_AESNI
16440        if (aes->use_aesni) {
16441            SAVE_VECTOR_REGISTERS(return _svr_ret;);
16442#if defined(HAVE_INTEL_AVX1)
16443            if (IS_INTEL_AVX1(intel_flags)) {
16444                AES_XTS_decrypt_update_avx1(in, out, sz,
16445                                            (const byte*)aes->key,
16446                                            stream->tweak_block,
16447                                            (int)aes->rounds);
16448                ret = 0;
16449            }
16450            else
16451#endif
16452            {
16453                AES_XTS_decrypt_update_aesni(in, out, sz,
16454                                             (const byte*)aes->key,
16455                                             stream->tweak_block,
16456                                             (int)aes->rounds);
16457                ret = 0;
16458            }
16459            RESTORE_VECTOR_REGISTERS();
16460        }
16461        else
16462#endif /* WOLFSSL_AESNI */
16463        {
16464            ret = AesXtsDecryptUpdate_sw(xaes, out, in, sz,
16465                                         stream->tweak_block);
16466        }
16467    }
16468
16469    return ret;
16470}
16471
16472int wc_AesXtsDecryptUpdate(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16473                           struct XtsAesStreamData *stream)
16474{
16475    if (stream == NULL)
16476        return BAD_FUNC_ARG;
16477    if (sz & ((word32)WC_AES_BLOCK_SIZE - 1U))
16478        return BAD_FUNC_ARG;
16479    return AesXtsDecryptUpdate(xaes, out, in, sz, stream);
16480}
16481
16482int wc_AesXtsDecryptFinal(XtsAes* xaes, byte* out, const byte* in, word32 sz,
16483                           struct XtsAesStreamData *stream)
16484{
16485    int ret;
16486    if (stream == NULL)
16487        return BAD_FUNC_ARG;
16488    if (sz > 0)
16489        ret = AesXtsDecryptUpdate(xaes, out, in, sz, stream);
16490    else
16491        ret = 0;
16492    ForceZero(stream->tweak_block, WC_AES_BLOCK_SIZE);
16493    /* force the count odd, to assure error on attempt to AesXtsEncryptUpdate()
16494     * after finalization.
16495     */
16496    stream->bytes_crypted_with_this_tweak |= 1U;
16497#ifdef WOLFSSL_CHECK_MEM_ZERO
16498    wc_MemZero_Check(stream->tweak_block, WC_AES_BLOCK_SIZE);
16499#endif
16500    return ret;
16501}
16502
16503#endif /* WOLFSSL_AESXTS_STREAM */
16504#endif /* HAVE_AES_DECRYPT */
16505
16506/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
16507 * sectorSz bytes
16508 *
16509 * xaes     AES keys to use for block encrypt
16510 * out      output buffer to hold cipher text
16511 * in       input plain text buffer to encrypt
16512 * sz       size of both out and in buffers
16513 * sector   value to use for tweak
16514 * sectorSz size of the sector
16515 *
16516 * returns 0 on success
16517 */
16518int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
16519        word32 sz, word64 sector, word32 sectorSz)
16520{
16521    int ret  = 0;
16522    word32 iter = 0;
16523    word32 sectorCount;
16524    word32 remainder;
16525
16526    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
16527        return BAD_FUNC_ARG;
16528    }
16529
16530    if (sz < WC_AES_BLOCK_SIZE) {
16531        WOLFSSL_MSG("Cipher text input too small for encryption");
16532        return BAD_FUNC_ARG;
16533    }
16534
16535    sectorCount  = sz / sectorSz;
16536    remainder = sz % sectorSz;
16537
16538    while (sectorCount) {
16539        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
16540                in + (iter * sectorSz), sectorSz, sector);
16541        if (ret != 0)
16542            break;
16543
16544        sectorCount--;
16545        iter++;
16546        sector++;
16547    }
16548
16549    if (remainder && ret == 0)
16550        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
16551                in + (iter * sectorSz), remainder, sector);
16552
16553    return ret;
16554}
16555
16556#ifdef HAVE_AES_DECRYPT
16557
16558/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
16559 *
16560 * xaes     AES keys to use for block decrypt
16561 * out      output buffer to hold cipher text
16562 * in       input plain text buffer to encrypt
16563 * sz       size of both out and in buffers
16564 * sector   value to use for tweak
16565 * sectorSz size of the sector
16566 *
16567 * returns 0 on success
16568 */
16569int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
16570        word32 sz, word64 sector, word32 sectorSz)
16571{
16572    int ret  = 0;
16573    word32 iter = 0;
16574    word32 sectorCount;
16575    word32 remainder;
16576
16577    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
16578        return BAD_FUNC_ARG;
16579    }
16580
16581    if (sz < WC_AES_BLOCK_SIZE) {
16582        WOLFSSL_MSG("Cipher text input too small for decryption");
16583        return BAD_FUNC_ARG;
16584    }
16585
16586    sectorCount  = sz / sectorSz;
16587    remainder = sz % sectorSz;
16588
16589    while (sectorCount) {
16590        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
16591                in + (iter * sectorSz), sectorSz, sector);
16592        if (ret != 0)
16593            break;
16594
16595        sectorCount--;
16596        iter++;
16597        sector++;
16598    }
16599
16600    if (remainder && ret == 0)
16601        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
16602                in + (iter * sectorSz), remainder, sector);
16603
16604    return ret;
16605}
16606#endif /* HAVE_AES_DECRYPT */
16607#endif /* WOLFSSL_AES_XTS */
16608
16609#ifdef WOLFSSL_CMAC
16610
16611int wc_local_CmacUpdateAes(struct Cmac *cmac, const byte* in, word32 inSz) {
16612    int ret = 0;
16613    Aes *aes = &cmac->aes;
16614#ifdef WC_AES_HAVE_PREFETCH_ARG
16615    int did_prefetches = 0;
16616#endif
16617
16618    VECTOR_REGISTERS_PUSH;
16619
16620    while ((ret == 0) && (inSz != 0)) {
16621        word32 add = min(inSz, WC_AES_BLOCK_SIZE - cmac->bufferSz);
16622        XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
16623
16624        cmac->bufferSz += add;
16625        inSz -= add;
16626        in += add;
16627
16628        if (cmac->bufferSz == WC_AES_BLOCK_SIZE && inSz != 0) {
16629            xorbuf(cmac->buffer, cmac->digest, WC_AES_BLOCK_SIZE);
16630            ret = AesEncrypt_preFetchOpt(aes, cmac->buffer,
16631                                            cmac->digest, &did_prefetches);
16632            if (ret == 0) {
16633                cmac->totalSz += WC_AES_BLOCK_SIZE;
16634                cmac->bufferSz = 0;
16635            }
16636        }
16637    }
16638
16639    VECTOR_REGISTERS_POP;
16640
16641    return ret;
16642}
16643
16644#endif /* WOLFSSL_CMAC */
16645
16646#ifdef WOLFSSL_AES_SIV
16647
16648/*
16649 * See RFC 5297 Section 2.4.
16650 */
16651static WARN_UNUSED_RESULT int S2V(
16652    const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc,
16653    const byte* nonce, word32 nonceSz, const byte* data,
16654    word32 dataSz, byte* out)
16655{
16656#ifdef WOLFSSL_SMALL_STACK
16657    byte* tmp[3] = {NULL, NULL, NULL};
16658    int i;
16659    Cmac* cmac;
16660#else
16661    byte tmp[3][WC_AES_BLOCK_SIZE];
16662    Cmac cmac[1];
16663#endif
16664    word32 macSz = WC_AES_BLOCK_SIZE;
16665    int ret = 0;
16666    byte tmpi = 0;
16667    word32 ai;
16668    word32 zeroBytes;
16669
16670#ifdef WOLFSSL_SMALL_STACK
16671    for (i = 0; i < 3; ++i) {
16672        tmp[i] = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
16673        if (tmp[i] == NULL) {
16674            ret = MEMORY_E;
16675            break;
16676        }
16677    }
16678    if (ret == 0)
16679#endif
16680
16681    if ((numAssoc > 126) || ((nonceSz > 0) && (numAssoc > 125))) {
16682        /* See RFC 5297 Section 7. */
16683        WOLFSSL_MSG("Maximum number of ADs (including the nonce) for AES SIV is"
16684                    " 126.");
16685        ret = BAD_FUNC_ARG;
16686    }
16687
16688    if (ret == 0) {
16689        XMEMSET(tmp[1], 0, WC_AES_BLOCK_SIZE);
16690        XMEMSET(tmp[2], 0, WC_AES_BLOCK_SIZE);
16691
16692        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], WC_AES_BLOCK_SIZE,
16693                                 key, keySz);
16694    }
16695
16696    if (ret == 0) {
16697        /* Loop over authenticated associated data AD1..ADn */
16698        for (ai = 0; ai < numAssoc; ++ai) {
16699            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
16700            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, assoc[ai].assoc,
16701                                     assoc[ai].assocSz, key, keySz);
16702            if (ret != 0)
16703                break;
16704            xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
16705            tmpi = (byte)(1 - tmpi);
16706        }
16707
16708        /* Add nonce as final AD. See RFC 5297 Section 3. */
16709        if ((ret == 0) && (nonceSz > 0)) {
16710            ShiftAndXorRb(tmp[1-tmpi], tmp[tmpi]);
16711            ret = wc_AesCmacGenerate(tmp[tmpi], &macSz, nonce,
16712                                     nonceSz, key, keySz);
16713            if (ret == 0) {
16714                xorbuf(tmp[1-tmpi], tmp[tmpi], WC_AES_BLOCK_SIZE);
16715            }
16716            tmpi = (byte)(1U - tmpi);
16717        }
16718
16719        /* For simplicity of the remaining code, make sure the "final" result
16720           is always in tmp[0]. */
16721        if (tmpi == 1) {
16722            XMEMCPY(tmp[0], tmp[1], WC_AES_BLOCK_SIZE);
16723        }
16724    }
16725
16726    if (ret == 0) {
16727        if (dataSz >= WC_AES_BLOCK_SIZE) {
16728
16729            WC_ALLOC_VAR_EX(cmac, Cmac, 1, NULL, DYNAMIC_TYPE_CMAC,
16730                ret=MEMORY_E);
16731            if (WC_VAR_OK(cmac))
16732            {
16733            #ifdef WOLFSSL_CHECK_MEM_ZERO
16734                /* Aes part is checked by wc_AesFree. */
16735                wc_MemZero_Add("wc_AesCmacGenerate cmac",
16736                    ((unsigned char *)cmac) + sizeof(Aes),
16737                    sizeof(Cmac) - sizeof(Aes));
16738            #endif
16739                xorbuf(tmp[0], data + (dataSz - WC_AES_BLOCK_SIZE),
16740                       WC_AES_BLOCK_SIZE);
16741                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
16742                if (ret == 0) {
16743                    ret = wc_CmacUpdate(cmac, data, dataSz - WC_AES_BLOCK_SIZE);
16744                }
16745                if (ret == 0) {
16746                    ret = wc_CmacUpdate(cmac, tmp[0], WC_AES_BLOCK_SIZE);
16747                }
16748                if (ret == 0) {
16749                    ret = wc_CmacFinal(cmac, out, &macSz);
16750                }
16751            }
16752        #ifdef WOLFSSL_SMALL_STACK
16753            XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
16754        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
16755            wc_MemZero_Check(cmac, sizeof(Cmac));
16756        #endif
16757        }
16758        else {
16759            XMEMCPY(tmp[2], data, dataSz);
16760            tmp[2][dataSz] |= 0x80;
16761            zeroBytes = WC_AES_BLOCK_SIZE - (dataSz + 1);
16762            if (zeroBytes != 0) {
16763                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
16764            }
16765            ShiftAndXorRb(tmp[1], tmp[0]);
16766            xorbuf(tmp[1], tmp[2], WC_AES_BLOCK_SIZE);
16767            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], WC_AES_BLOCK_SIZE, key,
16768                                     keySz);
16769        }
16770    }
16771
16772#ifdef WOLFSSL_SMALL_STACK
16773    for (i = 0; i < 3; ++i) {
16774        if (tmp[i] != NULL) {
16775            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
16776        }
16777    }
16778#endif
16779
16780    return ret;
16781}
16782
16783static WARN_UNUSED_RESULT int AesSivCipher(
16784    const byte* key, word32 keySz, const AesSivAssoc* assoc,
16785    word32 numAssoc, const byte* nonce, word32 nonceSz,
16786    const byte* data, word32 dataSz, byte* siv, byte* out,
16787    int enc)
16788{
16789    int ret = 0;
16790    WC_DECLARE_VAR(aes, Aes, 1, 0);
16791    byte sivTmp[WC_AES_BLOCK_SIZE];
16792
16793    if (key == NULL || siv == NULL || out == NULL) {
16794        WOLFSSL_MSG("Bad parameter");
16795        ret = BAD_FUNC_ARG;
16796    }
16797
16798    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
16799        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
16800        ret = BAD_FUNC_ARG;
16801    }
16802
16803    if (ret == 0) {
16804        if (enc == 1) {
16805            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, data,
16806                      dataSz, sivTmp);
16807            if (ret != 0) {
16808                WOLFSSL_MSG("S2V failed.");
16809            }
16810            else {
16811                XMEMCPY(siv, sivTmp, WC_AES_BLOCK_SIZE);
16812            }
16813        }
16814        else {
16815            XMEMCPY(sivTmp, siv, WC_AES_BLOCK_SIZE);
16816        }
16817    }
16818
16819    if (ret == 0) {
16820#ifdef WOLFSSL_SMALL_STACK
16821        aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
16822#else
16823        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
16824#endif
16825        if (ret != 0) {
16826            WOLFSSL_MSG("Failed to initialized AES object.");
16827        }
16828    }
16829
16830    if (ret == 0) {
16831        if (dataSz > 0) {
16832            sivTmp[12] &= 0x7f;
16833            sivTmp[8] &= 0x7f;
16834            ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
16835                               AES_ENCRYPTION);
16836            if (ret != 0) {
16837                WOLFSSL_MSG("Failed to set key for AES-CTR.");
16838            }
16839            else {
16840                ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
16841                if (ret != 0) {
16842                    WOLFSSL_MSG("AES-CTR encryption failed.");
16843                }
16844            }
16845        }
16846
16847        if (ret == 0 && enc == 0) {
16848            ret = S2V(key, keySz / 2, assoc, numAssoc, nonce, nonceSz, out,
16849                      dataSz, sivTmp);
16850            if (ret != 0) {
16851                WOLFSSL_MSG("S2V failed.");
16852            }
16853
16854            if (ConstantCompare(siv, sivTmp, WC_AES_BLOCK_SIZE) != 0) {
16855                WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
16856                ret = AES_SIV_AUTH_E;
16857            }
16858        }
16859
16860    #ifdef WOLFSSL_SMALL_STACK
16861        wc_AesDelete(aes, NULL);
16862    #else
16863        wc_AesFree(aes);
16864    #endif
16865    }
16866
16867    ForceZero(sivTmp, sizeof(sivTmp));
16868
16869    return ret;
16870}
16871
16872/*
16873 * See RFC 5297 Section 2.6.
16874 */
16875int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
16876                     word32 assocSz, const byte* nonce, word32 nonceSz,
16877                     const byte* in, word32 inSz, byte* siv, byte* out)
16878{
16879    AesSivAssoc ad;
16880    ad.assoc = assoc;
16881    ad.assocSz = assocSz;
16882    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
16883                        siv, out, 1);
16884}
16885
16886/*
16887 * See RFC 5297 Section 2.7.
16888 */
16889int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
16890                     word32 assocSz, const byte* nonce, word32 nonceSz,
16891                     const byte* in, word32 inSz, byte* siv, byte* out)
16892{
16893    AesSivAssoc ad;
16894    ad.assoc = assoc;
16895    ad.assocSz = assocSz;
16896    return AesSivCipher(key, keySz, &ad, 1U, nonce, nonceSz, in, inSz,
16897                        siv, out, 0);
16898}
16899
16900/*
16901 * See RFC 5297 Section 2.6.
16902 */
16903int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
16904                        word32 numAssoc, const byte* nonce, word32 nonceSz,
16905                        const byte* in, word32 inSz, byte* siv, byte* out)
16906{
16907    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
16908                        siv, out, 1);
16909}
16910
16911/*
16912 * See RFC 5297 Section 2.7.
16913 */
16914int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
16915                        word32 numAssoc, const byte* nonce, word32 nonceSz,
16916                        const byte* in, word32 inSz, byte* siv, byte* out)
16917{
16918    return AesSivCipher(key, keySz, assoc, numAssoc, nonce, nonceSz, in, inSz,
16919                        siv, out, 0);
16920}
16921
16922#endif /* WOLFSSL_AES_SIV */
16923
16924#if defined(WOLFSSL_AES_EAX)
16925
16926/*
16927 * AES EAX one-shot API
16928 * Encrypts input data and computes an auth tag over the input
16929 * auth data and ciphertext
16930 *
16931 * Returns 0 on success
16932 * Returns error code on failure
16933 */
16934int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
16935                          const byte* in, word32 inSz,
16936                          const byte* nonce, word32 nonceSz,
16937                          /* output computed auth tag */
16938                          byte* authTag, word32 authTagSz,
16939                          /* input data to authenticate */
16940                          const byte* authIn, word32 authInSz)
16941{
16942#if defined(WOLFSSL_SMALL_STACK)
16943    AesEax *eax;
16944#else
16945    AesEax eax_mem;
16946    AesEax *eax = &eax_mem;
16947#endif
16948    int ret;
16949    int eaxInited = 0;
16950
16951    if (key == NULL || out == NULL || in == NULL || nonce == NULL
16952                              || authTag == NULL || authIn == NULL) {
16953        return BAD_FUNC_ARG;
16954    }
16955
16956#if defined(WOLFSSL_SMALL_STACK)
16957    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
16958                                 NULL,
16959                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
16960        return MEMORY_E;
16961    }
16962#endif
16963
16964    if ((ret = wc_AesEaxInit(eax,
16965                             key, keySz,
16966                             nonce, nonceSz,
16967                             authIn, authInSz)) != 0) {
16968        goto cleanup;
16969    }
16970    eaxInited = 1;
16971
16972    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
16973        goto cleanup;
16974    }
16975
16976    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
16977        goto cleanup;
16978    }
16979
16980cleanup:
16981    if (eaxInited)
16982        wc_AesEaxFree(eax);
16983#if defined(WOLFSSL_SMALL_STACK)
16984    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
16985#endif
16986    return ret;
16987}
16988
16989
16990/*
16991 * AES EAX one-shot API
16992 * Decrypts and authenticates data against a supplied auth tag
16993 *
16994 * Returns 0 on success
16995 * Returns error code on failure
16996 */
16997int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
16998                          const byte* in, word32 inSz,
16999                          const byte* nonce, word32 nonceSz,
17000                          /* auth tag to verify against */
17001                          const byte* authTag, word32 authTagSz,
17002                          /* input data to authenticate */
17003                          const byte* authIn, word32 authInSz)
17004{
17005#if defined(WOLFSSL_SMALL_STACK)
17006    AesEax *eax;
17007#else
17008    AesEax eax_mem;
17009    AesEax *eax = &eax_mem;
17010#endif
17011    int ret;
17012    int eaxInited = 0;
17013
17014    if (key == NULL || out == NULL || in == NULL || nonce == NULL
17015                              || authTag == NULL || authIn == NULL) {
17016        return BAD_FUNC_ARG;
17017    }
17018
17019    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ
17020            || authTagSz > WC_AES_BLOCK_SIZE) {
17021        return BAD_FUNC_ARG;
17022    }
17023
17024#if defined(WOLFSSL_SMALL_STACK)
17025    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
17026                                 NULL,
17027                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
17028        return MEMORY_E;
17029    }
17030#endif
17031
17032    if ((ret = wc_AesEaxInit(eax,
17033                             key, keySz,
17034                             nonce, nonceSz,
17035                             authIn, authInSz)) != 0) {
17036
17037        goto cleanup;
17038    }
17039    eaxInited = 1;
17040
17041    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
17042        goto cleanup;
17043    }
17044
17045    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
17046        goto cleanup;
17047    }
17048
17049cleanup:
17050    if (eaxInited)
17051        wc_AesEaxFree(eax);
17052#if defined(WOLFSSL_SMALL_STACK)
17053    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
17054#endif
17055    return ret;
17056}
17057
17058
17059/*
17060 * AES EAX Incremental API:
17061 * Initializes an AES EAX encryption or decryption operation. This must be
17062 * called before any other EAX APIs are used on the AesEax struct
17063 *
17064 * Returns 0 on success
17065 * Returns error code on failure
17066 */
17067int  wc_AesEaxInit(AesEax* eax,
17068                   const byte* key, word32 keySz,
17069                   const byte* nonce, word32 nonceSz,
17070                   const byte* authIn, word32 authInSz)
17071{
17072    int ret = 0;
17073    word32 cmacSize;
17074    int aesInited = 0;
17075    int nonceCmacInited = 0;
17076    int aadCmacInited = 0;
17077
17078    if (eax == NULL || key == NULL ||  nonce == NULL) {
17079        return BAD_FUNC_ARG;
17080    }
17081
17082    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
17083
17084    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
17085        goto out;
17086    }
17087    aesInited = 1;
17088
17089    if ((ret = wc_AesSetKey(&eax->aes,
17090                            key,
17091                            keySz,
17092                            NULL,
17093                            AES_ENCRYPTION)) != 0) {
17094        goto out;
17095    }
17096
17097    /*
17098    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
17099    *   N' = OMAC^0_K(N)
17100    */
17101    if ((ret = wc_InitCmac(&eax->nonceCmac,
17102                           key,
17103                           keySz,
17104                           WC_CMAC_AES,
17105                           NULL)) != 0) {
17106        return ret;
17107    }
17108    nonceCmacInited = 1;
17109
17110    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
17111                             eax->prefixBuf,
17112                             sizeof(eax->prefixBuf))) != 0) {
17113        goto out;
17114    }
17115
17116    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
17117        goto out;
17118    }
17119
17120    cmacSize = WC_AES_BLOCK_SIZE;
17121    if ((ret = wc_CmacFinal(&eax->nonceCmac,
17122                            eax->nonceCmacFinal,
17123                            &cmacSize)) != 0) {
17124        goto out;
17125    }
17126
17127    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
17128        goto out;
17129    }
17130
17131    /*
17132     * start the OMAC used to build the auth tag chunk for the AD .
17133     * This CMAC is continued in subsequent update calls when more auth data is
17134     * provided
17135     *   H' = OMAC^1_K(H)
17136     */
17137    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 1;
17138    if ((ret = wc_InitCmac(&eax->aadCmac,
17139                           key,
17140                           keySz,
17141                           WC_CMAC_AES,
17142                           NULL)) != 0) {
17143        goto out;
17144    }
17145    aadCmacInited = 1;
17146
17147    if ((ret = wc_CmacUpdate(&eax->aadCmac,
17148                             eax->prefixBuf,
17149                             sizeof(eax->prefixBuf))) != 0) {
17150        goto out;
17151    }
17152
17153    if (authIn != NULL) {
17154        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
17155            goto out;
17156        }
17157    }
17158
17159    /*
17160     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
17161     * updated in subsequent calls to encrypt/decrypt
17162     *  C' = OMAC^2_K(C)
17163     */
17164    eax->prefixBuf[WC_AES_BLOCK_SIZE-1] = 2;
17165    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
17166                           key,
17167                           keySz,
17168                           WC_CMAC_AES,
17169                           NULL)) != 0) {
17170        goto out;
17171    }
17172
17173    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
17174                             eax->prefixBuf,
17175                             sizeof(eax->prefixBuf))) != 0) {
17176        goto out;
17177    }
17178
17179out:
17180
17181    if (ret != 0) {
17182        if (aesInited)
17183            wc_AesFree(&eax->aes);
17184        if (nonceCmacInited)
17185            wc_CmacFree(&eax->nonceCmac);
17186        if (aadCmacInited)
17187            wc_CmacFree(&eax->aadCmac);
17188    }
17189
17190    return ret;
17191}
17192
17193
17194/*
17195 * AES EAX Incremental API:
17196 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
17197 * the authentication stream
17198 *
17199 * Returns 0 on success
17200 * Returns error code on failure
17201 */
17202int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
17203                            const byte* in, word32 inSz,
17204                            const byte* authIn, word32 authInSz)
17205{
17206    int ret;
17207
17208    if (eax == NULL || out == NULL ||  in == NULL) {
17209        return BAD_FUNC_ARG;
17210    }
17211
17212    /*
17213     * Encrypt the plaintext using AES CTR
17214     *  C = CTR(M)
17215     */
17216    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
17217        return ret;
17218    }
17219
17220    /*
17221     * update OMAC with new ciphertext
17222     *  C' = OMAC^2_K(C)
17223     */
17224    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
17225        return ret;
17226    }
17227
17228    /* If there exists new auth data, update the OMAC for that as well */
17229    if (authIn != NULL) {
17230        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
17231            return ret;
17232        }
17233    }
17234
17235    return 0;
17236}
17237
17238
17239/*
17240 * AES EAX Incremental API:
17241 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
17242 * the authentication stream
17243 *
17244 * Returns 0 on success
17245 * Returns error code on failure
17246 */
17247int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
17248                            const byte* in, word32 inSz,
17249                            const byte* authIn, word32 authInSz)
17250{
17251    int ret;
17252
17253    if (eax == NULL || out == NULL ||  in == NULL) {
17254        return BAD_FUNC_ARG;
17255    }
17256
17257    /*
17258     * Decrypt the plaintext using AES CTR
17259     *  C = CTR(M)
17260     */
17261    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
17262        return ret;
17263    }
17264
17265    /*
17266     * update OMAC with new ciphertext
17267     *  C' = OMAC^2_K(C)
17268     */
17269    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
17270        return ret;
17271    }
17272
17273    /* If there exists new auth data, update the OMAC for that as well */
17274    if (authIn != NULL) {
17275        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
17276            return ret;
17277        }
17278    }
17279
17280    return 0;
17281}
17282
17283
17284/*
17285 * AES EAX Incremental API:
17286 * Provides additional auth data information to the authentication
17287 * stream for an authenticated encryption or decryption operation
17288 *
17289 * Returns 0 on success
17290 * Returns error code on failure
17291 */
17292int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
17293{
17294    if (eax == NULL) {
17295        return BAD_FUNC_ARG;
17296    }
17297    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
17298}
17299
17300
17301/*
17302 * AES EAX Incremental API:
17303 * Finalizes the authenticated encryption operation, computing the auth tag
17304 * over previously supplied auth data and computed ciphertext
17305 *
17306 * Returns 0 on success
17307 * Returns error code on failure
17308 */
17309int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
17310{
17311    word32 cmacSize;
17312    int ret;
17313    word32 i;
17314
17315    if (eax == NULL || authTag == NULL || authTagSz == 0 ||
17316            authTagSz > WC_AES_BLOCK_SIZE) {
17317        return BAD_FUNC_ARG;
17318    }
17319
17320    /* Complete the OMAC for the ciphertext */
17321    cmacSize = WC_AES_BLOCK_SIZE;
17322    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
17323                                  eax->ciphertextCmacFinal,
17324                                  &cmacSize)) != 0) {
17325        return ret;
17326    }
17327
17328    /* Complete the OMAC for auth data */
17329    cmacSize = WC_AES_BLOCK_SIZE;
17330    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
17331                                  eax->aadCmacFinal,
17332                                  &cmacSize)) != 0) {
17333        return ret;
17334    }
17335
17336    /*
17337     * Concatenate all three auth tag chunks into the final tag, truncating
17338     * at the specified tag length
17339     *   T = Tag [first authTagSz bytes]
17340     */
17341    for (i = 0; i < authTagSz; i++) {
17342        authTag[i] = eax->nonceCmacFinal[i]
17343                    ^ eax->aadCmacFinal[i]
17344                    ^ eax->ciphertextCmacFinal[i];
17345    }
17346
17347    return 0;
17348}
17349
17350
17351/*
17352 * AES EAX Incremental API:
17353 * Finalizes the authenticated decryption operation, computing the auth tag
17354 * for the previously supplied auth data and cipher text and validating it
17355 * against a provided auth tag
17356 *
17357 * Returns 0 on success
17358 * Return error code for failure
17359 */
17360int wc_AesEaxDecryptFinal(AesEax* eax,
17361                          const byte* authIn, word32 authInSz)
17362{
17363    int ret;
17364    word32 i;
17365    word32 cmacSize;
17366
17367#if defined(WOLFSSL_SMALL_STACK)
17368    byte *authTag;
17369#else
17370    byte authTag[WC_AES_BLOCK_SIZE];
17371#endif
17372
17373    if (eax == NULL || authIn == NULL || authInSz > WC_AES_BLOCK_SIZE
17374            || authInSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
17375        return BAD_FUNC_ARG;
17376    }
17377
17378    /* Complete the OMAC for the ciphertext */
17379    cmacSize = WC_AES_BLOCK_SIZE;
17380    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
17381                                  eax->ciphertextCmacFinal,
17382                                  &cmacSize)) != 0) {
17383        return ret;
17384    }
17385
17386    /* Complete the OMAC for auth data */
17387    cmacSize = WC_AES_BLOCK_SIZE;
17388    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
17389                                  eax->aadCmacFinal,
17390                                  &cmacSize)) != 0) {
17391        return ret;
17392    }
17393
17394#if defined(WOLFSSL_SMALL_STACK)
17395    authTag = (byte*)XMALLOC(WC_AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17396    if (authTag == NULL) {
17397        return MEMORY_E;
17398    }
17399#endif
17400
17401    /*
17402     * Concatenate all three auth tag chunks into the final tag, truncating
17403     * at the specified tag length
17404     *   T = Tag [first authInSz bytes]
17405     */
17406    for (i = 0; i < authInSz; i++) {
17407        authTag[i] = eax->nonceCmacFinal[i]
17408                    ^ eax->aadCmacFinal[i]
17409                    ^ eax->ciphertextCmacFinal[i];
17410    }
17411
17412    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
17413        ret = AES_EAX_AUTH_E;
17414    }
17415    else {
17416        ret = 0;
17417    }
17418
17419#if defined(WOLFSSL_SMALL_STACK)
17420    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
17421#endif
17422
17423    return ret;
17424}
17425
17426/*
17427 * Frees the underlying CMAC and AES contexts. Must be called when done using
17428 * the AES EAX context structure.
17429 *
17430 * Returns 0 on success
17431 * Returns error code on failure
17432 */
17433int wc_AesEaxFree(AesEax* eax)
17434{
17435    if (eax == NULL) {
17436        return BAD_FUNC_ARG;
17437    }
17438
17439    (void)wc_CmacFree(&eax->ciphertextCmac);
17440    (void)wc_CmacFree(&eax->aadCmac);
17441    wc_AesFree(&eax->aes);
17442
17443    return 0;
17444}
17445
17446#endif /* WOLFSSL_AES_EAX */
17447
17448#ifdef WOLFSSL_AES_CTS
17449
17450
17451/* One-shot API */
17452int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out,
17453                     const byte* in, word32 inSz,
17454                     const byte* iv)
17455{
17456    WC_DECLARE_VAR(aes, Aes, 1, 0);
17457    int ret = 0;
17458    word32 outSz = inSz;
17459
17460    if (key == NULL || out == NULL || in == NULL || iv == NULL)
17461        return BAD_FUNC_ARG;
17462
17463#ifdef WOLFSSL_SMALL_STACK
17464    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
17465#else
17466    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17467#endif
17468    if (ret == 0)
17469        ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION);
17470    if (ret == 0)
17471        ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz);
17472    if (ret == 0) {
17473        out += outSz;
17474        outSz = inSz - outSz;
17475        ret = wc_AesCtsEncryptFinal(aes, out, &outSz);
17476    }
17477
17478#ifdef WOLFSSL_SMALL_STACK
17479    wc_AesDelete(aes, NULL);
17480#else
17481    wc_AesFree(aes);
17482#endif
17483    return ret;
17484}
17485
17486int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out,
17487                     const byte* in, word32 inSz,
17488                     const byte* iv)
17489{
17490    WC_DECLARE_VAR(aes, Aes, 1, 0);
17491    int ret = 0;
17492    word32 outSz = inSz;
17493
17494    if (key == NULL || out == NULL || in == NULL || iv == NULL) {
17495        return BAD_FUNC_ARG;
17496    }
17497
17498#ifdef WOLFSSL_SMALL_STACK
17499    aes = wc_AesNew(NULL, INVALID_DEVID, &ret);
17500#else
17501    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
17502#endif
17503    if (ret == 0)
17504        ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION);
17505    if (ret == 0)
17506        ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz);
17507    if (ret == 0) {
17508        out += outSz;
17509        outSz = inSz - outSz;
17510        ret = wc_AesCtsDecryptFinal(aes, out, &outSz);
17511    }
17512
17513#ifdef WOLFSSL_SMALL_STACK
17514    wc_AesDelete(aes, NULL);
17515#else
17516    wc_AesFree(aes);
17517#endif
17518    return ret;
17519}
17520
17521static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz,
17522                        const byte* in, word32 inSz, int enc)
17523{
17524    word32 blocks = 0;
17525    int ret = 0;
17526    word32 writtenSz = 0;
17527    word32 tmpOutSz;
17528
17529    if (aes == NULL || out == NULL || in == NULL || outSz == NULL)
17530        return BAD_FUNC_ARG;
17531
17532    /* Error out early for easy sanity check */
17533    if (*outSz < inSz)
17534        return BUFFER_E;
17535    tmpOutSz = *outSz;
17536
17537    /* We need to store last two blocks of plaintext */
17538    if (aes->left > 0) {
17539        word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left);
17540        XMEMCPY(aes->ctsBlock + aes->left, in, copySz);
17541        aes->left += copySz;
17542        in += copySz;
17543        inSz -= copySz;
17544
17545        if (aes->left == WC_AES_BLOCK_SIZE * 2) {
17546            if (inSz > WC_AES_BLOCK_SIZE) {
17547                if (tmpOutSz < WC_AES_BLOCK_SIZE * 2)
17548                    return BUFFER_E;
17549                if (enc) {
17550                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
17551                                           WC_AES_BLOCK_SIZE * 2);
17552                }
17553                else {
17554                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
17555                                           WC_AES_BLOCK_SIZE * 2);
17556                }
17557                if (ret != 0)
17558                    return ret;
17559                out += WC_AES_BLOCK_SIZE * 2;
17560                writtenSz += WC_AES_BLOCK_SIZE * 2;
17561                tmpOutSz -= WC_AES_BLOCK_SIZE * 2;
17562                aes->left = 0;
17563            }
17564            else if (inSz > 0) {
17565                if (tmpOutSz < WC_AES_BLOCK_SIZE)
17566                    return BUFFER_E;
17567                if (enc) {
17568                    ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock,
17569                                           WC_AES_BLOCK_SIZE);
17570                }
17571                else {
17572                    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock,
17573                                           WC_AES_BLOCK_SIZE);
17574                }
17575                if (ret != 0)
17576                    return ret;
17577                out += WC_AES_BLOCK_SIZE;
17578                writtenSz += WC_AES_BLOCK_SIZE;
17579                tmpOutSz -= WC_AES_BLOCK_SIZE;
17580                /* Move the last block in ctsBlock to the beginning for
17581                 * next operation */
17582                XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE,
17583                        WC_AES_BLOCK_SIZE);
17584                XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz);
17585                aes->left = WC_AES_BLOCK_SIZE + inSz;
17586                *outSz = writtenSz;
17587                return ret; /* Return the result of encryption */
17588            }
17589            else {
17590                /* Can't output data as we need > 1 block for Final call */
17591                *outSz = writtenSz;
17592                return 0;
17593            }
17594        }
17595        else {
17596            /* All input has been absorbed into aes->ctsBlock */
17597            *outSz = 0;
17598            return 0;
17599        }
17600    }
17601    if (inSz > WC_AES_BLOCK_SIZE) {
17602        /* We need to store the last two full or partial blocks */
17603        blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE;
17604        blocks -= 2;
17605    }
17606    if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE)
17607        return BUFFER_E;
17608    if (enc)
17609        ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
17610    else
17611        ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE);
17612    in += blocks * WC_AES_BLOCK_SIZE;
17613    inSz -= blocks * WC_AES_BLOCK_SIZE;
17614    XMEMCPY(aes->ctsBlock, in, inSz);
17615    aes->left = inSz;
17616    writtenSz += blocks * WC_AES_BLOCK_SIZE;
17617    *outSz = writtenSz;
17618    return ret;
17619}
17620
17621/* Incremental API */
17622int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz,
17623                           const byte* in, word32 inSz)
17624{
17625    return AesCtsUpdate(aes, out, outSz, in, inSz, 1);
17626}
17627
17628int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz)
17629{
17630    int ret = 0;
17631
17632    if (aes == NULL || out == NULL || outSz == NULL)
17633        return BAD_FUNC_ARG;
17634    if (*outSz < aes->left)
17635        return BUFFER_E;
17636
17637    /* Input must be at least two complete or partial blocks */
17638    if (aes->left <= WC_AES_BLOCK_SIZE)
17639        return BAD_FUNC_ARG;
17640
17641    /* Zero padding */
17642    XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left);
17643
17644    ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock,
17645                           WC_AES_BLOCK_SIZE * 2);
17646    if (ret != 0)
17647        return ret;
17648
17649    XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
17650    XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock,
17651            aes->left - WC_AES_BLOCK_SIZE);
17652    *outSz = aes->left;
17653    return ret;
17654}
17655
17656int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz,
17657                           const byte* in, word32 inSz)
17658{
17659    return AesCtsUpdate(aes, out, outSz, in, inSz, 0);
17660}
17661
17662int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz)
17663{
17664    int ret = 0;
17665    byte iv[WC_AES_BLOCK_SIZE];
17666    byte tmp[WC_AES_BLOCK_SIZE];
17667    word32 partialSz;
17668    word32 padSz;
17669
17670    if (aes == NULL || out == NULL || outSz == NULL)
17671        return BAD_FUNC_ARG;
17672    if (*outSz < aes->left)
17673        return BUFFER_E;
17674
17675    /* Input must be at least two complete or partial blocks */
17676    if (aes->left <= WC_AES_BLOCK_SIZE)
17677        return BAD_FUNC_ARG;
17678
17679    partialSz = aes->left - WC_AES_BLOCK_SIZE;
17680    padSz = 2 * WC_AES_BLOCK_SIZE - aes->left;
17681    /* Zero pad */
17682    XMEMSET(aes->ctsBlock + aes->left, 0, padSz);
17683
17684    /* Store IV */
17685    XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE);
17686    /* Load IV */
17687    XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE);
17688
17689    ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE);
17690    if (ret != 0)
17691        return ret;
17692
17693    /* Write out partial block */
17694    XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz);
17695    /* Retrieve the padding */
17696    XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz);
17697    /* Restore IV */
17698    XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE);
17699
17700    ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE,
17701                           WC_AES_BLOCK_SIZE);
17702    if (ret != 0)
17703        return ret;
17704
17705    *outSz = aes->left;
17706    return ret;
17707}
17708
17709#endif /* WOLFSSL_AES_CTS */
17710
17711#endif /* !NO_AES */