cjson
fuzzing
inputs
test1 test10 test11 test2 test3 test3.bu test3.uf test3.uu test4 test5 test6 test7 test8 test9library_config
cJSONConfig.cmake.in cJSONConfigVersion.cmake.in libcjson.pc.in libcjson_utils.pc.in uninstall.cmaketests
inputs
test1 test1.expected test10 test10.expected test11 test11.expected test2 test2.expected test3 test3.expected test4 test4.expected test5 test5.expected test6 test7 test7.expected test8 test8.expected test9 test9.expectedjson-patch-tests
.editorconfig .gitignore .npmignore README.md cjson-utils-tests.json package.json spec_tests.json tests.jsonunity
auto
colour_prompt.rb colour_reporter.rb generate_config.yml generate_module.rb generate_test_runner.rb parse_output.rb stylize_as_junit.rb test_file_filter.rb type_sanitizer.rb unity_test_summary.py unity_test_summary.rb unity_to_junit.pydocs
ThrowTheSwitchCodingStandard.md UnityAssertionsCheatSheetSuitableforPrintingandPossiblyFraming.pdf UnityAssertionsReference.md UnityConfigurationGuide.md UnityGettingStartedGuide.md UnityHelperScriptsGuide.md license.txtexamples
unity_config.hcurl
.github
scripts
cleancmd.pl cmp-config.pl cmp-pkg-config.sh codespell-ignore.words codespell.sh distfiles.sh pyspelling.words pyspelling.yaml randcurl.pl requirements-docs.txt requirements-proselint.txt requirements.txt shellcheck-ci.sh shellcheck.sh spellcheck.curl trimmarkdownheader.pl typos.sh typos.toml verify-examples.pl verify-synopsis.pl yamlcheck.sh yamlcheck.yamlworkflows
appveyor-status.yml checkdocs.yml checksrc.yml checkurls.yml codeql.yml configure-vs-cmake.yml curl-for-win.yml distcheck.yml fuzz.yml http3-linux.yml label.yml linux-old.yml linux.yml macos.yml non-native.yml windows.ymlCMake
CurlSymbolHiding.cmake CurlTests.c FindBrotli.cmake FindCares.cmake FindGSS.cmake FindGnuTLS.cmake FindLDAP.cmake FindLibbacktrace.cmake FindLibgsasl.cmake FindLibidn2.cmake FindLibpsl.cmake FindLibssh.cmake FindLibssh2.cmake FindLibuv.cmake FindMbedTLS.cmake FindNGHTTP2.cmake FindNGHTTP3.cmake FindNGTCP2.cmake FindNettle.cmake FindQuiche.cmake FindRustls.cmake FindWolfSSL.cmake FindZstd.cmake Macros.cmake OtherTests.cmake PickyWarnings.cmake Utilities.cmake cmake_uninstall.in.cmake curl-config.in.cmake unix-cache.cmake win32-cache.cmakedocs
cmdline-opts
.gitignore CMakeLists.txt MANPAGE.md Makefile.am Makefile.inc _AUTHORS.md _BUGS.md _DESCRIPTION.md _ENVIRONMENT.md _EXITCODES.md _FILES.md _GLOBBING.md _NAME.md _OPTIONS.md _OUTPUT.md _PROGRESS.md _PROTOCOLS.md _PROXYPREFIX.md _SEEALSO.md _SYNOPSIS.md _URL.md _VARIABLES.md _VERSION.md _WWW.md abstract-unix-socket.md alt-svc.md anyauth.md append.md aws-sigv4.md basic.md ca-native.md cacert.md capath.md cert-status.md cert-type.md cert.md ciphers.md compressed-ssh.md compressed.md config.md connect-timeout.md connect-to.md continue-at.md cookie-jar.md cookie.md create-dirs.md create-file-mode.md crlf.md crlfile.md curves.md data-ascii.md data-binary.md data-raw.md data-urlencode.md data.md delegation.md digest.md disable-eprt.md disable-epsv.md disable.md disallow-username-in-url.md dns-interface.md dns-ipv4-addr.md dns-ipv6-addr.md dns-servers.md doh-cert-status.md doh-insecure.md doh-url.md dump-ca-embed.md dump-header.md ech.md egd-file.md engine.md etag-compare.md etag-save.md expect100-timeout.md fail-early.md fail-with-body.md fail.md false-start.md follow.md form-escape.md form-string.md form.md ftp-account.md ftp-alternative-to-user.md ftp-create-dirs.md ftp-method.md ftp-pasv.md ftp-port.md ftp-pret.md ftp-skip-pasv-ip.md ftp-ssl-ccc-mode.md ftp-ssl-ccc.md ftp-ssl-control.md get.md globoff.md happy-eyeballs-timeout-ms.md haproxy-clientip.md haproxy-protocol.md head.md header.md help.md hostpubmd5.md hostpubsha256.md hsts.md http0.9.md http1.0.md http1.1.md http2-prior-knowledge.md http2.md http3-only.md http3.md ignore-content-length.md insecure.md interface.md ip-tos.md ipfs-gateway.md ipv4.md ipv6.md json.md junk-session-cookies.md keepalive-cnt.md keepalive-time.md key-type.md key.md knownhosts.md krb.md libcurl.md limit-rate.md list-only.md local-port.md location-trusted.md location.md login-options.md mail-auth.md mail-from.md mail-rcpt-allowfails.md mail-rcpt.md mainpage.idx manual.md max-filesize.md max-redirs.md max-time.md metalink.md mptcp.md negotiate.md netrc-file.md netrc-optional.md netrc.md next.md no-alpn.md no-buffer.md no-clobber.md no-keepalive.md no-npn.md no-progress-meter.md no-sessionid.md noproxy.md ntlm-wb.md ntlm.md oauth2-bearer.md out-null.md output-dir.md output.md parallel-immediate.md parallel-max-host.md parallel-max.md parallel.md pass.md path-as-is.md pinnedpubkey.md post301.md post302.md post303.md preproxy.md progress-bar.md proto-default.md proto-redir.md proto.md proxy-anyauth.md proxy-basic.md proxy-ca-native.md proxy-cacert.md proxy-capath.md proxy-cert-type.md proxy-cert.md proxy-ciphers.md proxy-crlfile.md proxy-digest.md proxy-header.md proxy-http2.md proxy-insecure.md proxy-key-type.md proxy-key.md proxy-negotiate.md proxy-ntlm.md proxy-pass.md proxy-pinnedpubkey.md proxy-service-name.md proxy-ssl-allow-beast.md proxy-ssl-auto-client-cert.md proxy-tls13-ciphers.md proxy-tlsauthtype.md proxy-tlspassword.md proxy-tlsuser.md proxy-tlsv1.md proxy-user.md proxy.md proxy1.0.md proxytunnel.md pubkey.md quote.md random-file.md range.md rate.md raw.md referer.md remote-header-name.md remote-name-all.md remote-name.md remote-time.md remove-on-error.md request-target.md request.md resolve.md retry-all-errors.md retry-connrefused.md retry-delay.md retry-max-time.md retry.md sasl-authzid.md sasl-ir.md service-name.md show-error.md show-headers.md sigalgs.md silent.md skip-existing.md socks4.md socks4a.md socks5-basic.md socks5-gssapi-nec.md socks5-gssapi-service.md socks5-gssapi.md socks5-hostname.md socks5.md speed-limit.md speed-time.md ssl-allow-beast.md ssl-auto-client-cert.md ssl-no-revoke.md ssl-reqd.md ssl-revoke-best-effort.md ssl-sessions.md ssl.md sslv2.md sslv3.md stderr.md styled-output.md suppress-connect-headers.md tcp-fastopen.md tcp-nodelay.md telnet-option.md tftp-blksize.md tftp-no-options.md time-cond.md tls-earlydata.md tls-max.md tls13-ciphers.md tlsauthtype.md tlspassword.md tlsuser.md tlsv1.0.md tlsv1.1.md tlsv1.2.md tlsv1.3.md tlsv1.md tr-encoding.md trace-ascii.md trace-config.md trace-ids.md trace-time.md trace.md unix-socket.md upload-file.md upload-flags.md url-query.md url.md use-ascii.md user-agent.md user.md variable.md verbose.md version.md vlan-priority.md write-out.md xattr.mdexamples
.checksrc .gitignore 10-at-a-time.c CMakeLists.txt Makefile.am Makefile.example Makefile.inc README.md adddocsref.pl address-scope.c altsvc.c anyauthput.c block_ip.c cacertinmem.c certinfo.c chkspeed.c connect-to.c cookie_interface.c crawler.c debug.c default-scheme.c ephiperfifo.c evhiperfifo.c externalsocket.c fileupload.c ftp-delete.c ftp-wildcard.c ftpget.c ftpgetinfo.c ftpgetresp.c ftpsget.c ftpupload.c ftpuploadfrommem.c ftpuploadresume.c getinfo.c getinmemory.c getredirect.c getreferrer.c ghiper.c headerapi.c hiperfifo.c hsts-preload.c htmltidy.c htmltitle.cpp http-options.c http-post.c http2-download.c http2-pushinmemory.c http2-serverpush.c http2-upload.c http3-present.c http3.c httpcustomheader.c httpput-postfields.c httpput.c https.c imap-append.c imap-authzid.c imap-copy.c imap-create.c imap-delete.c imap-examine.c imap-fetch.c imap-list.c imap-lsub.c imap-multi.c imap-noop.c imap-search.c imap-ssl.c imap-store.c imap-tls.c interface.c ipv6.c keepalive.c localport.c log_failed_transfers.c maxconnects.c multi-app.c multi-debugcallback.c multi-double.c multi-event.c multi-formadd.c multi-legacy.c multi-post.c multi-single.c multi-uv.c netrc.c parseurl.c persistent.c pop3-authzid.c pop3-dele.c pop3-list.c pop3-multi.c pop3-noop.c pop3-retr.c pop3-ssl.c pop3-stat.c pop3-tls.c pop3-top.c pop3-uidl.c post-callback.c postinmemory.c postit2-formadd.c postit2.c progressfunc.c protofeats.c range.c resolve.c rtsp-options.c sendrecv.c sepheaders.c sessioninfo.c sftpget.c sftpuploadresume.c shared-connection-cache.c simple.c simplepost.c simplessl.c smooth-gtk-thread.c smtp-authzid.c smtp-expn.c smtp-mail.c smtp-mime.c smtp-multi.c smtp-ssl.c smtp-tls.c smtp-vrfy.c sslbackend.c synctime.c threaded.c unixsocket.c url2file.c urlapi.c usercertinmem.c version-check.pl websocket-cb.c websocket-updown.c websocket.c xmlstream.cinternals
BUFQ.md BUFREF.md CHECKSRC.md CLIENT-READERS.md CLIENT-WRITERS.md CODE_STYLE.md CONNECTION-FILTERS.md CREDENTIALS.md CURLX.md DYNBUF.md HASH.md LLIST.md MID.md MQTT.md MULTI-EV.md NEW-PROTOCOL.md PEERS.md PORTING.md RATELIMITS.md README.md SCORECARD.md SPLAY.md STRPARSE.md THRDPOOL-AND-QUEUE.md TIME-KEEPING.md TLS-SESSIONS.md UINT_SETS.md WEBSOCKET.mdlibcurl
opts
CMakeLists.txt CURLINFO_ACTIVESOCKET.md CURLINFO_APPCONNECT_TIME.md CURLINFO_APPCONNECT_TIME_T.md CURLINFO_CAINFO.md CURLINFO_CAPATH.md CURLINFO_CERTINFO.md CURLINFO_CONDITION_UNMET.md CURLINFO_CONNECT_TIME.md CURLINFO_CONNECT_TIME_T.md CURLINFO_CONN_ID.md CURLINFO_CONTENT_LENGTH_DOWNLOAD.md CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md CURLINFO_CONTENT_LENGTH_UPLOAD.md CURLINFO_CONTENT_LENGTH_UPLOAD_T.md CURLINFO_CONTENT_TYPE.md CURLINFO_COOKIELIST.md CURLINFO_EARLYDATA_SENT_T.md CURLINFO_EFFECTIVE_METHOD.md CURLINFO_EFFECTIVE_URL.md CURLINFO_FILETIME.md CURLINFO_FILETIME_T.md CURLINFO_FTP_ENTRY_PATH.md CURLINFO_HEADER_SIZE.md CURLINFO_HTTPAUTH_AVAIL.md CURLINFO_HTTPAUTH_USED.md CURLINFO_HTTP_CONNECTCODE.md CURLINFO_HTTP_VERSION.md CURLINFO_LASTSOCKET.md CURLINFO_LOCAL_IP.md CURLINFO_LOCAL_PORT.md CURLINFO_NAMELOOKUP_TIME.md CURLINFO_NAMELOOKUP_TIME_T.md CURLINFO_NUM_CONNECTS.md CURLINFO_OS_ERRNO.md CURLINFO_POSTTRANSFER_TIME_T.md CURLINFO_PRETRANSFER_TIME.md CURLINFO_PRETRANSFER_TIME_T.md CURLINFO_PRIMARY_IP.md CURLINFO_PRIMARY_PORT.md CURLINFO_PRIVATE.md CURLINFO_PROTOCOL.md CURLINFO_PROXYAUTH_AVAIL.md CURLINFO_PROXYAUTH_USED.md CURLINFO_PROXY_ERROR.md CURLINFO_PROXY_SSL_VERIFYRESULT.md CURLINFO_QUEUE_TIME_T.md CURLINFO_REDIRECT_COUNT.md CURLINFO_REDIRECT_TIME.md CURLINFO_REDIRECT_TIME_T.md CURLINFO_REDIRECT_URL.md CURLINFO_REFERER.md CURLINFO_REQUEST_SIZE.md CURLINFO_RESPONSE_CODE.md CURLINFO_RETRY_AFTER.md CURLINFO_RTSP_CLIENT_CSEQ.md CURLINFO_RTSP_CSEQ_RECV.md CURLINFO_RTSP_SERVER_CSEQ.md CURLINFO_RTSP_SESSION_ID.md CURLINFO_SCHEME.md CURLINFO_SIZE_DELIVERED.md CURLINFO_SIZE_DOWNLOAD.md CURLINFO_SIZE_DOWNLOAD_T.md CURLINFO_SIZE_UPLOAD.md CURLINFO_SIZE_UPLOAD_T.md CURLINFO_SPEED_DOWNLOAD.md CURLINFO_SPEED_DOWNLOAD_T.md CURLINFO_SPEED_UPLOAD.md CURLINFO_SPEED_UPLOAD_T.md CURLINFO_SSL_ENGINES.md CURLINFO_SSL_VERIFYRESULT.md CURLINFO_STARTTRANSFER_TIME.md CURLINFO_STARTTRANSFER_TIME_T.md CURLINFO_TLS_SESSION.md CURLINFO_TLS_SSL_PTR.md CURLINFO_TOTAL_TIME.md CURLINFO_TOTAL_TIME_T.md CURLINFO_USED_PROXY.md CURLINFO_XFER_ID.md CURLMINFO_XFERS_ADDED.md CURLMINFO_XFERS_CURRENT.md CURLMINFO_XFERS_DONE.md CURLMINFO_XFERS_PENDING.md CURLMINFO_XFERS_RUNNING.md CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE.md CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE.md CURLMOPT_MAXCONNECTS.md CURLMOPT_MAX_CONCURRENT_STREAMS.md CURLMOPT_MAX_HOST_CONNECTIONS.md CURLMOPT_MAX_PIPELINE_LENGTH.md CURLMOPT_MAX_TOTAL_CONNECTIONS.md CURLMOPT_NETWORK_CHANGED.md CURLMOPT_NOTIFYDATA.md CURLMOPT_NOTIFYFUNCTION.md CURLMOPT_PIPELINING.md CURLMOPT_PIPELINING_SERVER_BL.md CURLMOPT_PIPELINING_SITE_BL.md CURLMOPT_PUSHDATA.md CURLMOPT_PUSHFUNCTION.md CURLMOPT_QUICK_EXIT.md CURLMOPT_RESOLVE_THREADS_MAX.md CURLMOPT_SOCKETDATA.md CURLMOPT_SOCKETFUNCTION.md CURLMOPT_TIMERDATA.md CURLMOPT_TIMERFUNCTION.md CURLOPT_ABSTRACT_UNIX_SOCKET.md CURLOPT_ACCEPTTIMEOUT_MS.md CURLOPT_ACCEPT_ENCODING.md CURLOPT_ADDRESS_SCOPE.md CURLOPT_ALTSVC.md CURLOPT_ALTSVC_CTRL.md CURLOPT_APPEND.md CURLOPT_AUTOREFERER.md CURLOPT_AWS_SIGV4.md CURLOPT_BUFFERSIZE.md CURLOPT_CAINFO.md CURLOPT_CAINFO_BLOB.md CURLOPT_CAPATH.md CURLOPT_CA_CACHE_TIMEOUT.md CURLOPT_CERTINFO.md CURLOPT_CHUNK_BGN_FUNCTION.md CURLOPT_CHUNK_DATA.md CURLOPT_CHUNK_END_FUNCTION.md CURLOPT_CLOSESOCKETDATA.md CURLOPT_CLOSESOCKETFUNCTION.md CURLOPT_CONNECTTIMEOUT.md CURLOPT_CONNECTTIMEOUT_MS.md CURLOPT_CONNECT_ONLY.md CURLOPT_CONNECT_TO.md CURLOPT_CONV_FROM_NETWORK_FUNCTION.md CURLOPT_CONV_FROM_UTF8_FUNCTION.md CURLOPT_CONV_TO_NETWORK_FUNCTION.md CURLOPT_COOKIE.md CURLOPT_COOKIEFILE.md CURLOPT_COOKIEJAR.md CURLOPT_COOKIELIST.md CURLOPT_COOKIESESSION.md CURLOPT_COPYPOSTFIELDS.md CURLOPT_CRLF.md CURLOPT_CRLFILE.md CURLOPT_CURLU.md CURLOPT_CUSTOMREQUEST.md CURLOPT_DEBUGDATA.md CURLOPT_DEBUGFUNCTION.md CURLOPT_DEFAULT_PROTOCOL.md CURLOPT_DIRLISTONLY.md CURLOPT_DISALLOW_USERNAME_IN_URL.md CURLOPT_DNS_CACHE_TIMEOUT.md CURLOPT_DNS_INTERFACE.md CURLOPT_DNS_LOCAL_IP4.md CURLOPT_DNS_LOCAL_IP6.md CURLOPT_DNS_SERVERS.md CURLOPT_DNS_SHUFFLE_ADDRESSES.md CURLOPT_DNS_USE_GLOBAL_CACHE.md CURLOPT_DOH_SSL_VERIFYHOST.md CURLOPT_DOH_SSL_VERIFYPEER.md CURLOPT_DOH_SSL_VERIFYSTATUS.md CURLOPT_DOH_URL.md CURLOPT_ECH.md CURLOPT_EGDSOCKET.md CURLOPT_ERRORBUFFER.md CURLOPT_EXPECT_100_TIMEOUT_MS.md CURLOPT_FAILONERROR.md CURLOPT_FILETIME.md CURLOPT_FNMATCH_DATA.md CURLOPT_FNMATCH_FUNCTION.md CURLOPT_FOLLOWLOCATION.md CURLOPT_FORBID_REUSE.md CURLOPT_FRESH_CONNECT.md CURLOPT_FTPPORT.md CURLOPT_FTPSSLAUTH.md CURLOPT_FTP_ACCOUNT.md CURLOPT_FTP_ALTERNATIVE_TO_USER.md CURLOPT_FTP_CREATE_MISSING_DIRS.md CURLOPT_FTP_FILEMETHOD.md CURLOPT_FTP_SKIP_PASV_IP.md CURLOPT_FTP_SSL_CCC.md CURLOPT_FTP_USE_EPRT.md CURLOPT_FTP_USE_EPSV.md CURLOPT_FTP_USE_PRET.md CURLOPT_GSSAPI_DELEGATION.md CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.md CURLOPT_HAPROXYPROTOCOL.md CURLOPT_HAPROXY_CLIENT_IP.md CURLOPT_HEADER.md CURLOPT_HEADERDATA.md CURLOPT_HEADERFUNCTION.md CURLOPT_HEADEROPT.md CURLOPT_HSTS.md CURLOPT_HSTSREADDATA.md CURLOPT_HSTSREADFUNCTION.md CURLOPT_HSTSWRITEDATA.md CURLOPT_HSTSWRITEFUNCTION.md CURLOPT_HSTS_CTRL.md CURLOPT_HTTP09_ALLOWED.md CURLOPT_HTTP200ALIASES.md CURLOPT_HTTPAUTH.md CURLOPT_HTTPGET.md CURLOPT_HTTPHEADER.md CURLOPT_HTTPPOST.md CURLOPT_HTTPPROXYTUNNEL.md CURLOPT_HTTP_CONTENT_DECODING.md CURLOPT_HTTP_TRANSFER_DECODING.md CURLOPT_HTTP_VERSION.md CURLOPT_IGNORE_CONTENT_LENGTH.md CURLOPT_INFILESIZE.md CURLOPT_INFILESIZE_LARGE.md CURLOPT_INTERFACE.md CURLOPT_INTERLEAVEDATA.md CURLOPT_INTERLEAVEFUNCTION.md CURLOPT_IOCTLDATA.md CURLOPT_IOCTLFUNCTION.md CURLOPT_IPRESOLVE.md CURLOPT_ISSUERCERT.md CURLOPT_ISSUERCERT_BLOB.md CURLOPT_KEEP_SENDING_ON_ERROR.md CURLOPT_KEYPASSWD.md CURLOPT_KRBLEVEL.md CURLOPT_LOCALPORT.md CURLOPT_LOCALPORTRANGE.md CURLOPT_LOGIN_OPTIONS.md CURLOPT_LOW_SPEED_LIMIT.md CURLOPT_LOW_SPEED_TIME.md CURLOPT_MAIL_AUTH.md CURLOPT_MAIL_FROM.md CURLOPT_MAIL_RCPT.md CURLOPT_MAIL_RCPT_ALLOWFAILS.md CURLOPT_MAXAGE_CONN.md CURLOPT_MAXCONNECTS.md CURLOPT_MAXFILESIZE.md CURLOPT_MAXFILESIZE_LARGE.md CURLOPT_MAXLIFETIME_CONN.md CURLOPT_MAXREDIRS.md CURLOPT_MAX_RECV_SPEED_LARGE.md CURLOPT_MAX_SEND_SPEED_LARGE.md CURLOPT_MIMEPOST.md CURLOPT_MIME_OPTIONS.md CURLOPT_NETRC.md CURLOPT_NETRC_FILE.md CURLOPT_NEW_DIRECTORY_PERMS.md CURLOPT_NEW_FILE_PERMS.md CURLOPT_NOBODY.md CURLOPT_NOPROGRESS.md CURLOPT_NOPROXY.md CURLOPT_NOSIGNAL.md CURLOPT_OPENSOCKETDATA.md CURLOPT_OPENSOCKETFUNCTION.md CURLOPT_PASSWORD.md CURLOPT_PATH_AS_IS.md CURLOPT_PINNEDPUBLICKEY.md CURLOPT_PIPEWAIT.md CURLOPT_PORT.md CURLOPT_POST.md CURLOPT_POSTFIELDS.md CURLOPT_POSTFIELDSIZE.md CURLOPT_POSTFIELDSIZE_LARGE.md CURLOPT_POSTQUOTE.md CURLOPT_POSTREDIR.md CURLOPT_PREQUOTE.md CURLOPT_PREREQDATA.md CURLOPT_PREREQFUNCTION.md CURLOPT_PRE_PROXY.md CURLOPT_PRIVATE.md CURLOPT_PROGRESSDATA.md CURLOPT_PROGRESSFUNCTION.md CURLOPT_PROTOCOLS.md CURLOPT_PROTOCOLS_STR.md CURLOPT_PROXY.md CURLOPT_PROXYAUTH.md CURLOPT_PROXYHEADER.md CURLOPT_PROXYPASSWORD.md CURLOPT_PROXYPORT.md CURLOPT_PROXYTYPE.md CURLOPT_PROXYUSERNAME.md CURLOPT_PROXYUSERPWD.md CURLOPT_PROXY_CAINFO.md CURLOPT_PROXY_CAINFO_BLOB.md CURLOPT_PROXY_CAPATH.md CURLOPT_PROXY_CRLFILE.md CURLOPT_PROXY_ISSUERCERT.md CURLOPT_PROXY_ISSUERCERT_BLOB.md CURLOPT_PROXY_KEYPASSWD.md CURLOPT_PROXY_PINNEDPUBLICKEY.md CURLOPT_PROXY_SERVICE_NAME.md CURLOPT_PROXY_SSLCERT.md CURLOPT_PROXY_SSLCERTTYPE.md CURLOPT_PROXY_SSLCERT_BLOB.md CURLOPT_PROXY_SSLKEY.md CURLOPT_PROXY_SSLKEYTYPE.md CURLOPT_PROXY_SSLKEY_BLOB.md CURLOPT_PROXY_SSLVERSION.md CURLOPT_PROXY_SSL_CIPHER_LIST.md CURLOPT_PROXY_SSL_OPTIONS.md CURLOPT_PROXY_SSL_VERIFYHOST.md CURLOPT_PROXY_SSL_VERIFYPEER.md CURLOPT_PROXY_TLS13_CIPHERS.md CURLOPT_PROXY_TLSAUTH_PASSWORD.md CURLOPT_PROXY_TLSAUTH_TYPE.md CURLOPT_PROXY_TLSAUTH_USERNAME.md CURLOPT_PROXY_TRANSFER_MODE.md CURLOPT_PUT.md CURLOPT_QUICK_EXIT.md CURLOPT_QUOTE.md CURLOPT_RANDOM_FILE.md CURLOPT_RANGE.md CURLOPT_READDATA.md CURLOPT_READFUNCTION.md CURLOPT_REDIR_PROTOCOLS.md CURLOPT_REDIR_PROTOCOLS_STR.md CURLOPT_REFERER.md CURLOPT_REQUEST_TARGET.md CURLOPT_RESOLVE.md CURLOPT_RESOLVER_START_DATA.md CURLOPT_RESOLVER_START_FUNCTION.md CURLOPT_RESUME_FROM.md CURLOPT_RESUME_FROM_LARGE.md CURLOPT_RTSP_CLIENT_CSEQ.md CURLOPT_RTSP_REQUEST.md CURLOPT_RTSP_SERVER_CSEQ.md CURLOPT_RTSP_SESSION_ID.md CURLOPT_RTSP_STREAM_URI.md CURLOPT_RTSP_TRANSPORT.md CURLOPT_SASL_AUTHZID.md CURLOPT_SASL_IR.md CURLOPT_SEEKDATA.md CURLOPT_SEEKFUNCTION.md CURLOPT_SERVER_RESPONSE_TIMEOUT.md CURLOPT_SERVER_RESPONSE_TIMEOUT_MS.md CURLOPT_SERVICE_NAME.md CURLOPT_SHARE.md CURLOPT_SOCKOPTDATA.md CURLOPT_SOCKOPTFUNCTION.md CURLOPT_SOCKS5_AUTH.md CURLOPT_SOCKS5_GSSAPI_NEC.md CURLOPT_SOCKS5_GSSAPI_SERVICE.md CURLOPT_SSH_AUTH_TYPES.md CURLOPT_SSH_COMPRESSION.md CURLOPT_SSH_HOSTKEYDATA.md CURLOPT_SSH_HOSTKEYFUNCTION.md CURLOPT_SSH_HOST_PUBLIC_KEY_MD5.md CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256.md CURLOPT_SSH_KEYDATA.md CURLOPT_SSH_KEYFUNCTION.md CURLOPT_SSH_KNOWNHOSTS.md CURLOPT_SSH_PRIVATE_KEYFILE.md CURLOPT_SSH_PUBLIC_KEYFILE.md CURLOPT_SSLCERT.md CURLOPT_SSLCERTTYPE.md CURLOPT_SSLCERT_BLOB.md CURLOPT_SSLENGINE.md CURLOPT_SSLENGINE_DEFAULT.md CURLOPT_SSLKEY.md CURLOPT_SSLKEYTYPE.md CURLOPT_SSLKEY_BLOB.md CURLOPT_SSLVERSION.md CURLOPT_SSL_CIPHER_LIST.md CURLOPT_SSL_CTX_DATA.md CURLOPT_SSL_CTX_FUNCTION.md CURLOPT_SSL_EC_CURVES.md CURLOPT_SSL_ENABLE_ALPN.md CURLOPT_SSL_ENABLE_NPN.md CURLOPT_SSL_FALSESTART.md CURLOPT_SSL_OPTIONS.md CURLOPT_SSL_SESSIONID_CACHE.md CURLOPT_SSL_SIGNATURE_ALGORITHMS.md CURLOPT_SSL_VERIFYHOST.md CURLOPT_SSL_VERIFYPEER.md CURLOPT_SSL_VERIFYSTATUS.md CURLOPT_STDERR.md CURLOPT_STREAM_DEPENDS.md CURLOPT_STREAM_DEPENDS_E.md CURLOPT_STREAM_WEIGHT.md CURLOPT_SUPPRESS_CONNECT_HEADERS.md CURLOPT_TCP_FASTOPEN.md CURLOPT_TCP_KEEPALIVE.md CURLOPT_TCP_KEEPCNT.md CURLOPT_TCP_KEEPIDLE.md CURLOPT_TCP_KEEPINTVL.md CURLOPT_TCP_NODELAY.md CURLOPT_TELNETOPTIONS.md CURLOPT_TFTP_BLKSIZE.md CURLOPT_TFTP_NO_OPTIONS.md CURLOPT_TIMECONDITION.md CURLOPT_TIMEOUT.md CURLOPT_TIMEOUT_MS.md CURLOPT_TIMEVALUE.md CURLOPT_TIMEVALUE_LARGE.md CURLOPT_TLS13_CIPHERS.md CURLOPT_TLSAUTH_PASSWORD.md CURLOPT_TLSAUTH_TYPE.md CURLOPT_TLSAUTH_USERNAME.md CURLOPT_TRAILERDATA.md CURLOPT_TRAILERFUNCTION.md CURLOPT_TRANSFERTEXT.md CURLOPT_TRANSFER_ENCODING.md CURLOPT_UNIX_SOCKET_PATH.md CURLOPT_UNRESTRICTED_AUTH.md CURLOPT_UPKEEP_INTERVAL_MS.md CURLOPT_UPLOAD.md CURLOPT_UPLOAD_BUFFERSIZE.md CURLOPT_UPLOAD_FLAGS.md CURLOPT_URL.md CURLOPT_USERAGENT.md CURLOPT_USERNAME.md CURLOPT_USERPWD.md CURLOPT_USE_SSL.md CURLOPT_VERBOSE.md CURLOPT_WILDCARDMATCH.md CURLOPT_WRITEDATA.md CURLOPT_WRITEFUNCTION.md CURLOPT_WS_OPTIONS.md CURLOPT_XFERINFODATA.md CURLOPT_XFERINFOFUNCTION.md CURLOPT_XOAUTH2_BEARER.md CURLSHOPT_LOCKFUNC.md CURLSHOPT_SHARE.md CURLSHOPT_UNLOCKFUNC.md CURLSHOPT_UNSHARE.md CURLSHOPT_USERDATA.md Makefile.am Makefile.incinclude
curl
Makefile.am curl.h curlver.h easy.h header.h mprintf.h multi.h options.h stdcheaders.h system.h typecheck-gcc.h urlapi.h websockets.hlib
curlx
base64.c base64.h basename.c basename.h dynbuf.c dynbuf.h fopen.c fopen.h inet_ntop.c inet_ntop.h inet_pton.c inet_pton.h multibyte.c multibyte.h nonblock.c nonblock.h snprintf.c snprintf.h strcopy.c strcopy.h strdup.c strdup.h strerr.c strerr.h strparse.c strparse.h timediff.c timediff.h timeval.c timeval.h version_win32.c version_win32.h wait.c wait.h warnless.c warnless.h winapi.c winapi.hvauth
cleartext.c cram.c digest.c digest.h digest_sspi.c gsasl.c krb5_gssapi.c krb5_sspi.c ntlm.c ntlm_sspi.c oauth2.c spnego_gssapi.c spnego_sspi.c vauth.c vauth.hvquic
curl_ngtcp2.c curl_ngtcp2.h curl_quiche.c curl_quiche.h vquic-tls.c vquic-tls.h vquic.c vquic.h vquic_int.hvtls
apple.c apple.h cipher_suite.c cipher_suite.h gtls.c gtls.h hostcheck.c hostcheck.h keylog.c keylog.h mbedtls.c mbedtls.h openssl.c openssl.h rustls.c rustls.h schannel.c schannel.h schannel_int.h schannel_verify.c vtls.c vtls.h vtls_int.h vtls_scache.c vtls_scache.h vtls_spack.c vtls_spack.h wolfssl.c wolfssl.h x509asn1.c x509asn1.hm4
.gitignore curl-amissl.m4 curl-apple-sectrust.m4 curl-compilers.m4 curl-confopts.m4 curl-functions.m4 curl-gnutls.m4 curl-mbedtls.m4 curl-openssl.m4 curl-override.m4 curl-reentrant.m4 curl-rustls.m4 curl-schannel.m4 curl-sysconfig.m4 curl-wolfssl.m4 xc-am-iface.m4 xc-cc-check.m4 xc-lt-iface.m4 xc-val-flgs.m4 zz40-xc-ovr.m4 zz50-xc-ovr.m4projects
OS400
.checksrc README.OS400 ccsidcurl.c ccsidcurl.h config400.default curl.cmd curl.inc.in curlcl.c curlmain.c initscript.sh make-docs.sh make-include.sh make-lib.sh make-src.sh make-tests.sh makefile.sh os400sys.c os400sys.hWindows
tmpl
.gitattributes README.txt curl-all.sln curl.sln curl.vcxproj curl.vcxproj.filters libcurl.sln libcurl.vcxproj libcurl.vcxproj.filtersvms
Makefile.am backup_gnv_curl_src.com build_curl-config_script.com build_gnv_curl.com build_gnv_curl_pcsi_desc.com build_gnv_curl_pcsi_text.com build_gnv_curl_release_notes.com build_libcurl_pc.com build_vms.com clean_gnv_curl.com compare_curl_source.com config_h.com curl_crtl_init.c curl_gnv_build_steps.txt curl_release_note_start.txt curl_startup.com curlmsg.h curlmsg.msg curlmsg.sdl curlmsg_vms.h generate_config_vms_h_curl.com generate_vax_transfer.com gnv_conftest.c_first gnv_curl_configure.sh gnv_libcurl_symbols.opt gnv_link_curl.com macro32_exactcase.patch make_gnv_curl_install.sh make_pcsi_curl_kit_name.com pcsi_gnv_curl_file_list.txt pcsi_product_gnv_curl.com readme report_openssl_version.c setup_gnv_curl_build.com stage_curl_install.com vms_eco_level.hscripts
.checksrc CMakeLists.txt Makefile.am badwords badwords-all badwords.txt cd2cd cd2nroff cdall checksrc-all.pl checksrc.pl cmakelint.sh completion.pl contributors.sh contrithanks.sh coverage.sh delta dmaketgz extract-unit-protos firefox-db2pem.sh installcheck.sh maketgz managen mdlinkcheck mk-ca-bundle.pl mk-unity.pl nroff2cd perlcheck.sh pythonlint.sh randdisable release-notes.pl release-tools.sh schemetable.c singleuse.pl spacecheck.pl top-complexity top-length verify-release wcurlsrc
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc config2setopts.c config2setopts.h curl.rc curlinfo.c mk-file-embed.pl mkhelp.pl slist_wc.c slist_wc.h terminal.c terminal.h tool_cb_dbg.c tool_cb_dbg.h tool_cb_hdr.c tool_cb_hdr.h tool_cb_prg.c tool_cb_prg.h tool_cb_rea.c tool_cb_rea.h tool_cb_see.c tool_cb_see.h tool_cb_soc.c tool_cb_soc.h tool_cb_wrt.c tool_cb_wrt.h tool_cfgable.c tool_cfgable.h tool_dirhie.c tool_dirhie.h tool_doswin.c tool_doswin.h tool_easysrc.c tool_easysrc.h tool_filetime.c tool_filetime.h tool_findfile.c tool_findfile.h tool_formparse.c tool_formparse.h tool_getparam.c tool_getparam.h tool_getpass.c tool_getpass.h tool_help.c tool_help.h tool_helpers.c tool_helpers.h tool_hugehelp.h tool_ipfs.c tool_ipfs.h tool_libinfo.c tool_libinfo.h tool_listhelp.c tool_main.c tool_main.h tool_msgs.c tool_msgs.h tool_operate.c tool_operate.h tool_operhlp.c tool_operhlp.h tool_paramhlp.c tool_paramhlp.h tool_parsecfg.c tool_parsecfg.h tool_progress.c tool_progress.h tool_sdecls.h tool_setopt.c tool_setopt.h tool_setup.h tool_ssls.c tool_ssls.h tool_stderr.c tool_stderr.h tool_urlglob.c tool_urlglob.h tool_util.c tool_util.h tool_version.h tool_vms.c tool_vms.h tool_writeout.c tool_writeout.h tool_writeout_json.c tool_writeout_json.h tool_xattr.c tool_xattr.h var.c var.htests
certs
.gitignore CMakeLists.txt Makefile.am Makefile.inc genserv.pl srp-verifier-conf srp-verifier-db test-ca.cnf test-ca.prm test-client-cert.prm test-client-eku-only.prm test-localhost-san-first.prm test-localhost-san-last.prm test-localhost.nn.prm test-localhost.prm test-localhost0h.prmdata
.gitignore DISABLED Makefile.am data-xml1 data1400.c data1401.c data1402.c data1403.c data1404.c data1405.c data1406.c data1407.c data1420.c data1461.txt data1463.txt data1465.c data1481.c data1705-1.md data1705-2.md data1705-3.md data1705-4.md data1705-stdout.1 data1706-1.md data1706-2.md data1706-3.md data1706-4.md data1706-stdout.txt data320.html test1 test10 test100 test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 test1008 test1009 test101 test1010 test1011 test1012 test1013 test1014 test1015 test1016 test1017 test1018 test1019 test102 test1020 test1021 test1022 test1023 test1024 test1025 test1026 test1027 test1028 test1029 test103 test1030 test1031 test1032 test1033 test1034 test1035 test1036 test1037 test1038 test1039 test104 test1040 test1041 test1042 test1043 test1044 test1045 test1046 test1047 test1048 test1049 test105 test1050 test1051 test1052 test1053 test1054 test1055 test1056 test1057 test1058 test1059 test106 test1060 test1061 test1062 test1063 test1064 test1065 test1066 test1067 test1068 test1069 test107 test1070 test1071 test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 test108 test1080 test1081 test1082 test1083 test1084 test1085 test1086 test1087 test1088 test1089 test109 test1090 test1091 test1092 test1093 test1094 test1095 test1096 test1097 test1098 test1099 test11 test110 test1100 test1101 test1102 test1103 test1104 test1105 test1106 test1107 test1108 test1109 test111 test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 test112 test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 test1128 test1129 test113 test1130 test1131 test1132 test1133 test1134 test1135 test1136 test1137 test1138 test1139 test114 test1140 test1141 test1142 test1143 test1144 test1145 test1146 test1147 test1148 test1149 test115 test1150 test1151 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 test116 test1160 test1161 test1162 test1163 test1164 test1165 test1166 test1167 test1168 test1169 test117 test1170 test1171 test1172 test1173 test1174 test1175 test1176 test1177 test1178 test1179 test118 test1180 test1181 test1182 test1183 test1184 test1185 test1186 test1187 test1188 test1189 test119 test1190 test1191 test1192 test1193 test1194 test1195 test1196 test1197 test1198 test1199 test12 test120 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 test1208 test1209 test121 test1210 test1211 test1212 test1213 test1214 test1215 test1216 test1217 test1218 test1219 test122 test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 test1228 test1229 test123 test1230 test1231 test1232 test1233 test1234 test1235 test1236 test1237 test1238 test1239 test124 test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 test1248 test1249 test125 test1250 test1251 test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 test126 test1260 test1261 test1262 test1263 test1264 test1265 test1266 test1267 test1268 test1269 test127 test1270 test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 test1279 test128 test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 test1288 test1289 test129 test1290 test1291 test1292 test1293 test1294 test1295 test1296 test1297 test1298 test1299 test13 test130 test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 test1308 test1309 test131 test1310 test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 test1319 test132 test1320 test1321 test1322 test1323 test1324 test1325 test1326 test1327 test1328 test1329 test133 test1330 test1331 test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 test134 test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 test1348 test1349 test135 test1350 test1351 test1352 test1353 test1354 test1355 test1356 test1357 test1358 test1359 test136 test1360 test1361 test1362 test1363 test1364 test1365 test1366 test1367 test1368 test1369 test137 test1370 test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 test1379 test138 test1380 test1381 test1382 test1383 test1384 test1385 test1386 test1387 test1388 test1389 test139 test1390 test1391 test1392 test1393 test1394 test1395 test1396 test1397 test1398 test1399 test14 test140 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 test1408 test1409 test141 test1410 test1411 test1412 test1413 test1414 test1415 test1416 test1417 test1418 test1419 test142 test1420 test1421 test1422 test1423 test1424 test1425 test1426 test1427 test1428 test1429 test143 test1430 test1431 test1432 test1433 test1434 test1435 test1436 test1437 test1438 test1439 test144 test1440 test1441 test1442 test1443 test1444 test1445 test1446 test1447 test1448 test1449 test145 test1450 test1451 test1452 test1453 test1454 test1455 test1456 test1457 test1458 test1459 test146 test1460 test1461 test1462 test1463 test1464 test1465 test1466 test1467 test1468 test1469 test147 test1470 test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 test1479 test148 test1480 test1481 test1482 test1483 test1484 test1485 test1486 test1487 test1488 test1489 test149 test1490 test1491 test1492 test1493 test1494 test1495 test1496 test1497 test1498 test1499 test15 test150 test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 test1508 test1509 test151 test1510 test1511 test1512 test1513 test1514 test1515 test1516 test1517 test1518 test1519 test152 test1520 test1521 test1522 test1523 test1524 test1525 test1526 test1527 test1528 test1529 test153 test1530 test1531 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 test154 test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 test1548 test1549 test155 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 test1558 test1559 test156 test1560 test1561 test1562 test1563 test1564 test1565 test1566 test1567 test1568 test1569 test157 test1570 test1571 test1572 test1573 test1574 test1575 test1576 test1577 test1578 test1579 test158 test1580 test1581 test1582 test1583 test1584 test1585 test1586 test1587 test1588 test1589 test159 test1590 test1591 test1592 test1593 test1594 test1595 test1596 test1597 test1598 test1599 test16 test160 test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 test1608 test1609 test161 test1610 test1611 test1612 test1613 test1614 test1615 test1616 test1617 test1618 test1619 test162 test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 test1628 test1629 test163 test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 test1638 test1639 test164 test1640 test1641 test1642 test1643 test1644 test1645 test165 test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 test1658 test1659 test166 test1660 test1661 test1662 test1663 test1664 test1665 test1666 test1667 test1668 test1669 test167 test1670 test1671 test1672 test1673 test1674 test1675 test1676 test168 test1680 test1681 test1682 test1683 test1684 test1685 test169 test17 test170 test1700 test1701 test1702 test1703 test1704 test1705 test1706 test1707 test1708 test1709 test171 test1710 test1711 test1712 test1713 test1714 test1715 test172 test1720 test1721 test173 test174 test175 test176 test177 test178 test179 test18 test180 test1800 test1801 test1802 test181 test182 test183 test184 test1847 test1848 test1849 test185 test1850 test1851 test186 test187 test188 test189 test19 test190 test1900 test1901 test1902 test1903 test1904 test1905 test1906 test1907 test1908 test1909 test191 test1910 test1911 test1912 test1913 test1914 test1915 test1916 test1917 test1918 test1919 test192 test1920 test1921 test193 test1933 test1934 test1935 test1936 test1937 test1938 test1939 test194 test1940 test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 test195 test1955 test1956 test1957 test1958 test1959 test196 test1960 test1964 test1965 test1966 test197 test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 test1978 test1979 test198 test1980 test1981 test1982 test1983 test1984 test199 test2 test20 test200 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 test2008 test2009 test201 test2010 test2011 test2012 test2013 test2014 test202 test2023 test2024 test2025 test2026 test2027 test2028 test2029 test203 test2030 test2031 test2032 test2033 test2034 test2035 test2037 test2038 test2039 test204 test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 test2048 test2049 test205 test2050 test2051 test2052 test2053 test2054 test2055 test2056 test2057 test2058 test2059 test206 test2060 test2061 test2062 test2063 test2064 test2065 test2066 test2067 test2068 test2069 test207 test2070 test2071 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 test208 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 test2088 test2089 test209 test2090 test2091 test2092 test21 test210 test2100 test2101 test2102 test2103 test2104 test211 test212 test213 test214 test215 test216 test217 test218 test219 test22 test220 test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 test221 test222 test223 test224 test225 test226 test227 test228 test229 test23 test230 test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 test2309 test231 test232 test233 test234 test235 test236 test237 test238 test239 test24 test240 test2400 test2401 test2402 test2403 test2404 test2405 test2406 test2407 test2408 test2409 test241 test2410 test2411 test242 test243 test244 test245 test246 test247 test248 test249 test25 test250 test2500 test2501 test2502 test2503 test2504 test2505 test2506 test251 test252 test253 test254 test255 test256 test257 test258 test259 test26 test260 test2600 test2601 test2602 test2603 test2604 test2605 test261 test262 test263 test264 test265 test266 test267 test268 test269 test27 test270 test2700 test2701 test2702 test2703 test2704 test2705 test2706 test2707 test2708 test2709 test271 test2710 test2711 test2712 test2713 test2714 test2715 test2716 test2717 test2718 test2719 test272 test2720 test2721 test2722 test2723 test273 test274 test275 test276 test277 test278 test279 test28 test280 test281 test282 test283 test284 test285 test286 test287 test288 test289 test29 test290 test291 test292 test293 test294 test295 test296 test297 test298 test299 test3 test30 test300 test3000 test3001 test3002 test3003 test3004 test3005 test3006 test3007 test3008 test3009 test301 test3010 test3011 test3012 test3013 test3014 test3015 test3016 test3017 test3018 test3019 test302 test3020 test3021 test3022 test3023 test3024 test3025 test3026 test3027 test3028 test3029 test303 test3030 test3031 test3032 test3033 test3034 test3035 test3036 test304 test305 test306 test307 test308 test309 test31 test310 test3100 test3101 test3102 test3103 test3104 test3105 test3106 test311 test312 test313 test314 test315 test316 test317 test318 test319 test32 test320 test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 test3208 test3209 test321 test3210 test3211 test3212 test3213 test3214 test3215 test3216 test3217 test3218 test3219 test322 test3220 test323 test324 test325 test326 test327 test328 test329 test33 test330 test3300 test3301 test3302 test331 test332 test333 test334 test335 test336 test337 test338 test339 test34 test340 test341 test342 test343 test344 test345 test346 test347 test348 test349 test35 test350 test351 test352 test353 test354 test355 test356 test357 test358 test359 test36 test360 test361 test362 test363 test364 test365 test366 test367 test368 test369 test37 test370 test371 test372 test373 test374 test375 test376 test378 test379 test38 test380 test381 test383 test384 test385 test386 test387 test388 test389 test39 test390 test391 test392 test393 test394 test395 test396 test397 test398 test399 test4 test40 test400 test4000 test4001 test401 test402 test403 test404 test405 test406 test407 test408 test409 test41 test410 test411 test412 test413 test414 test415 test416 test417 test418 test419 test42 test420 test421 test422 test423 test424 test425 test426 test427 test428 test429 test43 test430 test431 test432 test433 test434 test435 test436 test437 test438 test439 test44 test440 test441 test442 test443 test444 test445 test446 test447 test448 test449 test45 test450 test451 test452 test453 test454 test455 test456 test457 test458 test459 test46 test460 test461 test462 test463 test467 test468 test469 test47 test470 test471 test472 test473 test474 test475 test476 test477 test478 test479 test48 test480 test481 test482 test483 test484 test485 test486 test487 test488 test489 test49 test490 test491 test492 test493 test494 test495 test496 test497 test498 test499 test5 test50 test500 test501 test502 test503 test504 test505 test506 test507 test508 test509 test51 test510 test511 test512 test513 test514 test515 test516 test517 test518 test519 test52 test520 test521 test522 test523 test524 test525 test526 test527 test528 test529 test53 test530 test531 test532 test533 test534 test535 test536 test537 test538 test539 test54 test540 test541 test542 test543 test544 test545 test546 test547 test548 test549 test55 test550 test551 test552 test553 test554 test555 test556 test557 test558 test559 test56 test560 test561 test562 test563 test564 test565 test566 test567 test568 test569 test57 test570 test571 test572 test573 test574 test575 test576 test577 test578 test579 test58 test580 test581 test582 test583 test584 test585 test586 test587 test588 test589 test59 test590 test591 test592 test593 test594 test595 test596 test597 test598 test599 test6 test60 test600 test601 test602 test603 test604 test605 test606 test607 test608 test609 test61 test610 test611 test612 test613 test614 test615 test616 test617 test618 test619 test62 test620 test621 test622 test623 test624 test625 test626 test627 test628 test629 test63 test630 test631 test632 test633 test634 test635 test636 test637 test638 test639 test64 test640 test641 test642 test643 test644 test645 test646 test647 test648 test649 test65 test650 test651 test652 test653 test654 test655 test656 test658 test659 test66 test660 test661 test662 test663 test664 test665 test666 test667 test668 test669 test67 test670 test671 test672 test673 test674 test675 test676 test677 test678 test679 test68 test680 test681 test682 test683 test684 test685 test686 test687 test688 test689 test69 test690 test691 test692 test693 test694 test695 test696 test697 test698 test699 test7 test70 test700 test701 test702 test703 test704 test705 test706 test707 test708 test709 test71 test710 test711 test712 test713 test714 test715 test716 test717 test718 test719 test72 test720 test721 test722 test723 test724 test725 test726 test727 test728 test729 test73 test730 test731 test732 test733 test734 test735 test736 test737 test738 test739 test74 test740 test741 test742 test743 test744 test745 test746 test747 test748 test749 test75 test750 test751 test752 test753 test754 test755 test756 test757 test758 test759 test76 test760 test761 test762 test763 test764 test765 test766 test767 test768 test769 test77 test770 test771 test772 test773 test774 test775 test776 test777 test778 test779 test78 test780 test781 test782 test783 test784 test785 test786 test787 test788 test789 test79 test790 test791 test792 test793 test794 test795 test796 test797 test798 test799 test8 test80 test800 test801 test802 test803 test804 test805 test806 test807 test808 test809 test81 test810 test811 test812 test813 test814 test815 test816 test817 test818 test819 test82 test820 test821 test822 test823 test824 test825 test826 test827 test828 test829 test83 test830 test831 test832 test833 test834 test835 test836 test837 test838 test839 test84 test840 test841 test842 test843 test844 test845 test846 test847 test848 test849 test85 test850 test851 test852 test853 test854 test855 test856 test857 test858 test859 test86 test860 test861 test862 test863 test864 test865 test866 test867 test868 test869 test87 test870 test871 test872 test873 test874 test875 test876 test877 test878 test879 test88 test880 test881 test882 test883 test884 test885 test886 test887 test888 test889 test89 test890 test891 test892 test893 test894 test895 test896 test897 test898 test899 test9 test90 test900 test901 test902 test903 test904 test905 test906 test907 test908 test909 test91 test910 test911 test912 test913 test914 test915 test916 test917 test918 test919 test92 test920 test921 test922 test923 test924 test925 test926 test927 test928 test929 test93 test930 test931 test932 test933 test934 test935 test936 test937 test938 test939 test94 test940 test941 test942 test943 test944 test945 test946 test947 test948 test949 test95 test950 test951 test952 test953 test954 test955 test956 test957 test958 test959 test96 test960 test961 test962 test963 test964 test965 test966 test967 test968 test969 test97 test970 test971 test972 test973 test974 test975 test976 test977 test978 test979 test98 test980 test981 test982 test983 test984 test985 test986 test987 test988 test989 test99 test990 test991 test992 test993 test994 test995 test996 test997 test998 test999http
testenv
__init__.py caddy.py certs.py client.py curl.py dante.py dnsd.py env.py httpd.py nghttpx.py ports.py sshd.py vsftpd.py ws_echo_server.pylibtest
.gitignore CMakeLists.txt Makefile.am Makefile.inc cli_ftp_upload.c cli_h2_pausing.c cli_h2_serverpush.c cli_h2_upgrade_extreme.c cli_hx_download.c cli_hx_upload.c cli_tls_session_reuse.c cli_upload_pausing.c cli_ws_data.c cli_ws_pingpong.c first.c first.h lib1156.c lib1301.c lib1308.c lib1485.c lib1500.c lib1501.c lib1502.c lib1506.c lib1507.c lib1508.c lib1509.c lib1510.c lib1511.c lib1512.c lib1513.c lib1514.c lib1515.c lib1517.c lib1518.c lib1520.c lib1522.c lib1523.c lib1525.c lib1526.c lib1527.c lib1528.c lib1529.c lib1530.c lib1531.c lib1532.c lib1533.c lib1534.c lib1535.c lib1536.c lib1537.c lib1538.c lib1540.c lib1541.c lib1542.c lib1545.c lib1549.c lib1550.c lib1551.c lib1552.c lib1553.c lib1554.c lib1555.c lib1556.c lib1557.c lib1558.c lib1559.c lib1560.c lib1564.c lib1565.c lib1567.c lib1568.c lib1569.c lib1571.c lib1576.c lib1582.c lib1587.c lib1588.c lib1589.c lib1591.c lib1592.c lib1593.c lib1594.c lib1597.c lib1598.c lib1599.c lib1662.c lib1900.c lib1901.c lib1902.c lib1903.c lib1905.c lib1906.c lib1907.c lib1908.c lib1910.c lib1911.c lib1912.c lib1913.c lib1915.c lib1916.c lib1918.c lib1919.c lib1920.c lib1921.c lib1933.c lib1934.c lib1935.c lib1936.c lib1937.c lib1938.c lib1939.c lib1940.c lib1945.c lib1947.c lib1948.c lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c lib1964.c lib1965.c lib1970.c lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c lib2023.c lib2032.c lib2082.c lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c lib2402.c lib2404.c lib2405.c lib2502.c lib2504.c lib2505.c lib2506.c lib2700.c lib3010.c lib3025.c lib3026.c lib3027.c lib3033.c lib3034.c lib3100.c lib3101.c lib3102.c lib3103.c lib3104.c lib3105.c lib3207.c lib3208.c lib500.c lib501.c lib502.c lib503.c lib504.c lib505.c lib506.c lib507.c lib508.c lib509.c lib510.c lib511.c lib512.c lib513.c lib514.c lib515.c lib516.c lib517.c lib518.c lib519.c lib520.c lib521.c lib523.c lib524.c lib525.c lib526.c lib530.c lib533.c lib536.c lib537.c lib539.c lib540.c lib541.c lib542.c lib543.c lib544.c lib547.c lib549.c lib552.c lib553.c lib554.c lib555.c lib556.c lib557.c lib558.c lib559.c lib560.c lib562.c lib564.c lib566.c lib567.c lib568.c lib569.c lib570.c lib571.c lib572.c lib573.c lib574.c lib575.c lib576.c lib578.c lib579.c lib582.c lib583.c lib586.c lib589.c lib590.c lib591.c lib597.c lib598.c lib599.c lib643.c lib650.c lib651.c lib652.c lib653.c lib654.c lib655.c lib658.c lib659.c lib661.c lib666.c lib667.c lib668.c lib670.c lib674.c lib676.c lib677.c lib678.c lib694.c lib695.c lib751.c lib753.c lib757.c lib758.c lib766.c memptr.c mk-lib1521.pl test1013.pl test1022.pl test307.pl test610.pl test613.pl testtrace.c testtrace.h testutil.c testutil.h unitcheck.hserver
.checksrc .gitignore CMakeLists.txt Makefile.am Makefile.inc dnsd.c first.c first.h getpart.c mqttd.c resolve.c rtspd.c sockfilt.c socksd.c sws.c tftpd.c util.ctunit
.gitignore CMakeLists.txt Makefile.am Makefile.inc README.md tool1394.c tool1604.c tool1621.c tool1622.c tool1623.c tool1720.cunit
.gitignore CMakeLists.txt Makefile.am Makefile.inc README.md unit1300.c unit1302.c unit1303.c unit1304.c unit1305.c unit1307.c unit1309.c unit1323.c unit1330.c unit1395.c unit1396.c unit1397.c unit1398.c unit1399.c unit1600.c unit1601.c unit1602.c unit1603.c unit1605.c unit1606.c unit1607.c unit1608.c unit1609.c unit1610.c unit1611.c unit1612.c unit1614.c unit1615.c unit1616.c unit1620.c unit1625.c unit1626.c unit1627.c unit1636.c unit1650.c unit1651.c unit1652.c unit1653.c unit1654.c unit1655.c unit1656.c unit1657.c unit1658.c unit1660.c unit1661.c unit1663.c unit1664.c unit1666.c unit1667.c unit1668.c unit1669.c unit1674.c unit1675.c unit1676.c unit1979.c unit1980.c unit2600.c unit2601.c unit2602.c unit2603.c unit2604.c unit2605.c unit3200.c unit3205.c unit3211.c unit3212.c unit3213.c unit3214.c unit3216.c unit3219.c unit3300.c unit3301.c unit3302.cexamples
.env config.ini crypto_test.lua env_test.lua fs_example.lua http_server.lua https_test.lua ini_example.lua json.lua log.lua path_fs_example.lua process_example.lua request_download.lua request_test.lua run_all.lua sqlite_example.lua sqlite_http_template.lua stash_test.lua template_test.lua timer.lua websocket.luainiparser
example
iniexample.c iniwrite.c parse.c twisted-errors.ini twisted-genhuge.py twisted-ofkey.ini twisted-ofval.ini twisted.initest
CMakeLists.txt test_dictionary.c test_iniparser.c unity-config.yml unity_config.hjinjac
libjinjac
src
CMakeLists.txt ast.c ast.h block_statement.c block_statement.h buffer.c buffer.h buildin.c buildin.h common.h convert.c convert.h flex_decl.h jfunction.c jfunction.h jinja_expression.l jinja_expression.y jinjac_parse.c jinjac_parse.h jinjac_stream.c jinjac_stream.h jlist.c jlist.h jobject.c jobject.h parameter.c parameter.h str_obj.c str_obj.h trace.c trace.htest
.gitignore CMakeLists.txt autotest.rb test_01.expected test_01.jinja test_01b.expected test_01b.jinja test_01c.expected test_01c.jinja test_01d.expected test_01d.jinja test_02.expected test_02.jinja test_03.expected test_03.jinja test_04.expected test_04.jinja test_05.expected test_05.jinja test_06.expected test_06.jinja test_07.expected test_07.jinja test_08.expected test_08.jinja test_08b.expected test_08b.jinja test_09.expected test_09.jinja test_10.expected test_10.jinja test_11.expected test_11.jinja test_12.expected test_12.jinja test_13.expected test_13.jinja test_14.expected test_14.jinja test_15.expected test_15.jinja test_16.expected test_16.jinja test_17.expected test_17.jinja test_18.expected test_18.jinja test_18b.expected test_18b.jinja test_18c.expected test_18c.jinja test_19.expected test_19.jinja test_19b.expected test_19b.jinja test_19c.expected test_19c.jinja test_19d.expected test_19d.jinja test_19e.expected test_19e.jinja test_19f.expected test_19f.jinja test_20.expected test_20.jinja test_21.expected test_21.jinja test_22.expected test_22.jinja test_22a.expected test_22a.jinja test_22b.expected test_22b.jinja test_23.expected test_23.jinja test_24.expected test_24.jinjalibev
Changes LICENSE Makefile Makefile.am Makefile.in README Symbols.ev Symbols.event aclocal.m4 autogen.sh compile config.guess config.h config.h.in config.status config.sub configure configure.ac depcomp ev++.h ev.3 ev.c ev.h ev.pod ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_vars.h ev_win32.c ev_wrap.h event.c event.h install-sh libev.m4 libtool ltmain.sh missing mkinstalldirs stamp-h1luajit
doc
bluequad-print.css bluequad.css contact.html ext_buffer.html ext_c_api.html ext_ffi.html ext_ffi_api.html ext_ffi_semantics.html ext_ffi_tutorial.html ext_jit.html ext_profiler.html extensions.html install.html luajit.html running.htmldynasm
dasm_arm.h dasm_arm.lua dasm_arm64.h dasm_arm64.lua dasm_mips.h dasm_mips.lua dasm_mips64.lua dasm_ppc.h dasm_ppc.lua dasm_proto.h dasm_x64.lua dasm_x86.h dasm_x86.lua dynasm.luasrc
host
.gitignore README buildvm.c buildvm.h buildvm_asm.c buildvm_fold.c buildvm_lib.c buildvm_libbc.h buildvm_peobj.c genlibbc.lua genminilua.lua genversion.lua minilua.cjit
.gitignore bc.lua bcsave.lua dis_arm.lua dis_arm64.lua dis_arm64be.lua dis_mips.lua dis_mips64.lua dis_mips64el.lua dis_mips64r6.lua dis_mips64r6el.lua dis_mipsel.lua dis_ppc.lua dis_x64.lua dis_x86.lua dump.lua p.lua v.lua zone.luawolfssl
.github
workflows
ada.yml arduino.yml async-examples.yml async.yml atecc608-sim.yml bind.yml cmake-autoconf.yml cmake.yml codespell.yml coverity-scan-fixes.yml cryptocb-only.yml curl.yml cyrus-sasl.yml disable-pk-algs.yml docker-Espressif.yml docker-OpenWrt.yml emnet-nonblock.yml fil-c.yml freertos-mem-track.yml gencertbuf.yml grpc.yml haproxy.yml hostap-vm.yml intelasm-c-fallback.yml ipmitool.yml jwt-cpp.yml krb5.yml libspdm.yml libssh2.yml libvncserver.yml linuxkm.yml macos-apple-native-cert-validation.yml mbedtls.sh mbedtls.yml membrowse-comment.yml membrowse-onboard.yml membrowse-report.yml memcached.sh memcached.yml mono.yml mosquitto.yml msmtp.yml msys2.yml multi-arch.yml multi-compiler.yml net-snmp.yml nginx.yml no-malloc.yml no-tls.yml nss.sh nss.yml ntp.yml ocsp.yml openldap.yml openssh.yml openssl-ech.yml opensslcoexist.yml openvpn.yml os-check.yml packaging.yml pam-ipmi.yml pq-all.yml pr-commit-check.yml psk.yml puf.yml python.yml rng-tools.yml rust-wrapper.yml se050-sim.yml smallStackSize.yml socat.yml softhsm.yml sssd.yml stm32-sim.yml stsafe-a120-sim.yml stunnel.yml symbol-prefixes.yml threadx.yml tls-anvil.yml trackmemory.yml watcomc.yml win-csharp-test.yml wolfCrypt-Wconversion.yml wolfboot-integration.yml wolfsm.yml xcode.yml zephyr-4.x.yml zephyr.ymlIDE
ARDUINO
Arduino_README_prepend.md README.md include.am keywords.txt library.properties.template wolfssl-arduino.cpp wolfssl-arduino.sh wolfssl.hECLIPSE
Espressif
ESP-IDF
examples
template
CMakeLists.txt Makefile README.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp8266wolfssl_benchmark
VisualGDB
wolfssl_benchmark_IDF_v4.4_ESP32.sln wolfssl_benchmark_IDF_v4.4_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32.sln wolfssl_benchmark_IDF_v5_ESP32.vgdbproj wolfssl_benchmark_IDF_v5_ESP32C3.sln wolfssl_benchmark_IDF_v5_ESP32C3.vgdbproj wolfssl_benchmark_IDF_v5_ESP32S3.sln wolfssl_benchmark_IDF_v5_ESP32S3.vgdbprojwolfssl_client
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_client_ESP8266.vgdbprojwolfssl_server
CMakeLists.txt Makefile README.md README_server_sm.md partitions_singleapp_large.csv sdkconfig.defaults sdkconfig.defaults.esp32c2 sdkconfig.defaults.esp8266 wolfssl_server_ESP8266.vgdbprojwolfssl_test
VisualGDB
wolfssl_test-IDF_v5_ESP32.sln wolfssl_test-IDF_v5_ESP32.vgdbproj wolfssl_test-IDF_v5_ESP32C3.sln wolfssl_test-IDF_v5_ESP32C3.vgdbproj wolfssl_test-IDF_v5_ESP32C6.sln wolfssl_test-IDF_v5_ESP32C6.vgdbproj wolfssl_test_IDF_v5_ESP32S3.sln wolfssl_test_IDF_v5_ESP32S3.vgdbprojGCC-ARM
Makefile Makefile.bench Makefile.client Makefile.common Makefile.server Makefile.static Makefile.test README.md include.am linker.ld linker_fips.ldIAR-EWARM
embOS
SAMV71_XULT
embOS_SAMV71_XULT_user_settings
user_settings.h user_settings_simple_example.h user_settings_verbose_example.hembOS_wolfcrypt_benchmark_SAMV71_XULT
README_wolfcrypt_benchmark wolfcrypt_benchmark.ewd wolfcrypt_benchmark.ewpINTIME-RTOS
Makefile README.md include.am libwolfssl.c libwolfssl.vcxproj user_settings.h wolfExamples.c wolfExamples.h wolfExamples.sln wolfExamples.vcxproj wolfssl-lib.sln wolfssl-lib.vcxprojMQX
Makefile README-jp.md README.md client-tls.c include.am server-tls.c user_config.h user_settings.hMSVS-2019-AZSPHERE
wolfssl_new_azsphere
.gitignore CMakeLists.txt CMakeSettings.json app_manifest.json applibs_versions.h launch.vs.json main.cNETOS
Makefile.wolfcrypt.inc README.md include.am user_settings.h user_settings.h-cert2425 user_settings.h-cert3389 wolfssl_netos_custom.cPlatformIO
examples
wolfssl_benchmark
CMakeLists.txt README.md platformio.ini sdkconfig.defaults wolfssl_benchmark.code-workspaceROWLEY-CROSSWORKS-ARM
Kinetis_FlashPlacement.xml README.md arm_startup.c benchmark_main.c hw.h include.am kinetis_hw.c retarget.c test_main.c user_settings.h wolfssl.hzp wolfssl_ltc.hzpRenesas
e2studio
RA6M3
README.md README_APRA6M_en.md README_APRA6M_jp.md include.amRX72N
EnvisionKit
Simple
README_EN.md README_JP.mdwolfssl_demo
key_data.c key_data.h user_settings.h wolfssl_demo.c wolfssl_demo.h wolfssl_tsip_unit_test.cSTM32Cube
README.md STM32_Benchmarks.md default_conf.ftl include.am main.c wolfssl_example.c wolfssl_example.hWIN
README.txt include.am test.vcxproj user_settings.h user_settings_dtls.h wolfssl-fips.sln wolfssl-fips.vcxprojWIN-SRTP-KDF-140-3
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojWIN10
README.txt include.am resource.h test.vcxproj user_settings.h wolfssl-fips.rc wolfssl-fips.sln wolfssl-fips.vcxprojXCODE
Benchmark
include.amXilinxSDK
README.md bench.sh combine.sh eclipse_formatter_profile.xml graph.sh include.am user_settings.h wolfssl_example.capple-universal
wolfssl-multiplatform
iotsafe
Makefile README.md ca-cert.c devices.c devices.h include.am main.c memory-tls.c startup.c target.ld user_settings.hmynewt
README.md apps.wolfcrypttest.pkg.yml crypto.wolfssl.pkg.yml crypto.wolfssl.syscfg.yml include.am setup.shcerts
1024
ca-cert.der ca-cert.pem ca-key.der ca-key.pem client-cert.der client-cert.pem client-key.der client-key.pem client-keyPub.der dh1024.der dh1024.pem dsa-pub-1024.pem dsa1024.der dsa1024.pem include.am rsa1024.der server-cert.der server-cert.pem server-key.der server-key.pemcrl
extra-crls
ca-int-cert-revoked.pem claim-root.pem crl_critical_entry.pem crlnum_57oct.pem crlnum_64oct.pem general-server-crl.pem large_crlnum.pem large_crlnum2.pemdilithium
bench_dilithium_level2_key.der bench_dilithium_level3_key.der bench_dilithium_level5_key.der include.amecc
bp256r1-key.der bp256r1-key.pem ca-secp256k1-cert.pem ca-secp256k1-key.pem client-bp256r1-cert.der client-bp256r1-cert.pem client-secp256k1-cert.der client-secp256k1-cert.pem genecc.sh include.am secp256k1-key.der secp256k1-key.pem secp256k1-param.pem secp256k1-privkey.der secp256k1-privkey.pem server-bp256r1-cert.der server-bp256r1-cert.pem server-secp256k1-cert.der server-secp256k1-cert.pem server2-secp256k1-cert.der server2-secp256k1-cert.pem wolfssl.cnf wolfssl_384.cnfed25519
ca-ed25519-key.der ca-ed25519-key.pem ca-ed25519-priv.der ca-ed25519-priv.pem ca-ed25519.der ca-ed25519.pem client-ed25519-key.der client-ed25519-key.pem client-ed25519-priv.der client-ed25519-priv.pem client-ed25519.der client-ed25519.pem eddsa-ed25519.der eddsa-ed25519.pem gen-ed25519-certs.sh gen-ed25519-keys.sh gen-ed25519.sh include.am root-ed25519-key.der root-ed25519-key.pem root-ed25519-priv.der root-ed25519-priv.pem root-ed25519.der root-ed25519.pem server-ed25519-cert.pem server-ed25519-key.der server-ed25519-key.pem server-ed25519-priv.der server-ed25519-priv.pem server-ed25519.der server-ed25519.pemed448
ca-ed448-key.der ca-ed448-key.pem ca-ed448-priv.der ca-ed448-priv.pem ca-ed448.der ca-ed448.pem client-ed448-key.der client-ed448-key.pem client-ed448-priv.der client-ed448-priv.pem client-ed448.der client-ed448.pem gen-ed448-certs.sh gen-ed448-keys.sh include.am root-ed448-key.der root-ed448-key.pem root-ed448-priv.der root-ed448-priv.pem root-ed448.der root-ed448.pem server-ed448-cert.pem server-ed448-key.der server-ed448-key.pem server-ed448-priv.der server-ed448-priv.pem server-ed448.der server-ed448.pemexternal
DigiCertGlobalRootCA.pem README.txt ca-digicert-ev.pem ca-globalsign-root.pem ca-google-root.pem ca_collection.pem include.amintermediate
ca_false_intermediate
gentestcert.sh int_ca.key server.key test_ca.key test_ca.pem test_int_not_cacert.pem test_sign_bynoca_srv.pem wolfssl_base.conf wolfssl_srv.conflms
bc_hss_L2_H5_W8_root.der bc_hss_L3_H5_W4_root.der bc_lms_chain_ca.der bc_lms_chain_leaf.der bc_lms_native_bc_root.der bc_lms_sha256_h10_w8_root.der bc_lms_sha256_h5_w4_root.der include.ammldsa
README.txt include.am mldsa44-cert.der mldsa44-cert.pem mldsa44-key.pem mldsa44_bare-priv.der mldsa44_bare-seed.der mldsa44_oqskeypair.der mldsa44_priv-only.der mldsa44_pub-spki.der mldsa44_seed-only.der mldsa44_seed-priv.der mldsa65-cert.der mldsa65-cert.pem mldsa65-key.pem mldsa65_bare-priv.der mldsa65_bare-seed.der mldsa65_oqskeypair.der mldsa65_priv-only.der mldsa65_pub-spki.der mldsa65_seed-only.der mldsa65_seed-priv.der mldsa87-cert.der mldsa87-cert.pem mldsa87-key.pem mldsa87_bare-priv.der mldsa87_bare-seed.der mldsa87_oqskeypair.der mldsa87_priv-only.der mldsa87_pub-spki.der mldsa87_seed-only.der mldsa87_seed-priv.derocsp
imposter-root-ca-cert.der imposter-root-ca-cert.pem imposter-root-ca-key.der imposter-root-ca-key.pem include.am index-ca-and-intermediate-cas.txt index-ca-and-intermediate-cas.txt.attr index-intermediate1-ca-issued-certs.txt index-intermediate1-ca-issued-certs.txt.attr index-intermediate2-ca-issued-certs.txt index-intermediate2-ca-issued-certs.txt.attr index-intermediate3-ca-issued-certs.txt index-intermediate3-ca-issued-certs.txt.attr intermediate1-ca-cert.der intermediate1-ca-cert.pem intermediate1-ca-key.der intermediate1-ca-key.pem intermediate2-ca-cert.der intermediate2-ca-cert.pem intermediate2-ca-key.der intermediate2-ca-key.pem intermediate3-ca-cert.der intermediate3-ca-cert.pem intermediate3-ca-key.der intermediate3-ca-key.pem ocsp-responder-cert.der ocsp-responder-cert.pem ocsp-responder-key.der ocsp-responder-key.pem openssl.cnf renewcerts-for-test.sh renewcerts.sh root-ca-cert.der root-ca-cert.pem root-ca-crl.pem root-ca-key.der root-ca-key.pem server1-cert.der server1-cert.pem server1-chain-noroot.pem server1-key.der server1-key.pem server2-cert.der server2-cert.pem server2-key.der server2-key.pem server3-cert.der server3-cert.pem server3-key.der server3-key.pem server4-cert.der server4-cert.pem server4-key.der server4-key.pem server5-cert.der server5-cert.pem server5-key.der server5-key.pem test-leaf-response.der test-multi-response.der test-response-nointern.der test-response-rsapss.der test-response.derp521
ca-p521-key.der ca-p521-key.pem ca-p521-priv.der ca-p521-priv.pem ca-p521.der ca-p521.pem client-p521-key.der client-p521-key.pem client-p521-priv.der client-p521-priv.pem client-p521.der client-p521.pem gen-p521-certs.sh gen-p521-keys.sh include.am root-p521-key.der root-p521-key.pem root-p521-priv.der root-p521-priv.pem root-p521.der root-p521.pem server-p521-cert.pem server-p521-key.der server-p521-key.pem server-p521-priv.der server-p521-priv.pem server-p521.der server-p521.pemrpk
client-cert-rpk.der client-ecc-cert-rpk.der include.am server-cert-rpk.der server-ecc-cert-rpk.derrsapss
ca-3072-rsapss-key.der ca-3072-rsapss-key.pem ca-3072-rsapss-priv.der ca-3072-rsapss-priv.pem ca-3072-rsapss.der ca-3072-rsapss.pem ca-rsapss-key.der ca-rsapss-key.pem ca-rsapss-priv.der ca-rsapss-priv.pem ca-rsapss.der ca-rsapss.pem client-3072-rsapss-key.der client-3072-rsapss-key.pem client-3072-rsapss-priv.der client-3072-rsapss-priv.pem client-3072-rsapss.der client-3072-rsapss.pem client-rsapss-key.der client-rsapss-key.pem client-rsapss-priv.der client-rsapss-priv.pem client-rsapss.der client-rsapss.pem gen-rsapss-keys.sh include.am renew-rsapss-certs.sh root-3072-rsapss-key.der root-3072-rsapss-key.pem root-3072-rsapss-priv.der root-3072-rsapss-priv.pem root-3072-rsapss.der root-3072-rsapss.pem root-rsapss-key.der root-rsapss-key.pem root-rsapss-priv.der root-rsapss-priv.pem root-rsapss.der root-rsapss.pem server-3072-rsapss-cert.pem server-3072-rsapss-key.der server-3072-rsapss-key.pem server-3072-rsapss-priv.der server-3072-rsapss-priv.pem server-3072-rsapss.der server-3072-rsapss.pem server-mix-rsapss-cert.pem server-rsapss-cert.pem server-rsapss-key.der server-rsapss-key.pem server-rsapss-priv.der server-rsapss-priv.pem server-rsapss.der server-rsapss.pemslhdsa
bench_slhdsa_sha2_128f_key.der bench_slhdsa_sha2_128s_key.der bench_slhdsa_sha2_192f_key.der bench_slhdsa_sha2_192s_key.der bench_slhdsa_sha2_256f_key.der bench_slhdsa_sha2_256s_key.der bench_slhdsa_shake128f_key.der bench_slhdsa_shake128s_key.der bench_slhdsa_shake192f_key.der bench_slhdsa_shake192s_key.der bench_slhdsa_shake256f_key.der bench_slhdsa_shake256s_key.der client-mldsa44-priv.pem client-mldsa44-sha2.der client-mldsa44-sha2.pem client-mldsa44-shake.der client-mldsa44-shake.pem gen-slhdsa-mldsa-certs.sh include.am root-slhdsa-sha2-128s-priv.der root-slhdsa-sha2-128s-priv.pem root-slhdsa-sha2-128s.der root-slhdsa-sha2-128s.pem root-slhdsa-shake-128s-priv.der root-slhdsa-shake-128s-priv.pem root-slhdsa-shake-128s.der root-slhdsa-shake-128s.pem server-mldsa44-priv.pem server-mldsa44-sha2.der server-mldsa44-sha2.pem server-mldsa44-shake.der server-mldsa44-shake.pemsm2
ca-sm2-key.der ca-sm2-key.pem ca-sm2-priv.der ca-sm2-priv.pem ca-sm2.der ca-sm2.pem client-sm2-key.der client-sm2-key.pem client-sm2-priv.der client-sm2-priv.pem client-sm2.der client-sm2.pem fix_sm2_spki.py gen-sm2-certs.sh gen-sm2-keys.sh include.am root-sm2-key.der root-sm2-key.pem root-sm2-priv.der root-sm2-priv.pem root-sm2.der root-sm2.pem self-sm2-cert.pem self-sm2-key.pem self-sm2-priv.pem server-sm2-cert.der server-sm2-cert.pem server-sm2-key.der server-sm2-key.pem server-sm2-priv.der server-sm2-priv.pem server-sm2.der server-sm2.pemstatickeys
dh-ffdhe2048-params.pem dh-ffdhe2048-pub.der dh-ffdhe2048-pub.pem dh-ffdhe2048.der dh-ffdhe2048.pem ecc-secp256r1.der ecc-secp256r1.pem gen-static.sh include.am x25519-pub.der x25519-pub.pem x25519.der x25519.pemtest
catalog.txt cert-bad-neg-int.der cert-bad-oid.der cert-bad-utf8.der cert-ext-ia.cfg cert-ext-ia.der cert-ext-ia.pem cert-ext-joi.cfg cert-ext-joi.der cert-ext-joi.pem cert-ext-mnc.der cert-ext-multiple.cfg cert-ext-multiple.der cert-ext-multiple.pem cert-ext-nc-combined.der cert-ext-nc-combined.pem cert-ext-nc.cfg cert-ext-nc.der cert-ext-nc.pem cert-ext-ncdns.der cert-ext-ncdns.pem cert-ext-ncip.der cert-ext-ncip.pem cert-ext-ncmixed.der cert-ext-ncmulti.der cert-ext-ncmulti.pem cert-ext-ncrid.der cert-ext-ncrid.pem cert-ext-nct.cfg cert-ext-nct.der cert-ext-nct.pem cert-ext-ndir-exc.cfg cert-ext-ndir-exc.der cert-ext-ndir-exc.pem cert-ext-ndir.cfg cert-ext-ndir.der cert-ext-ndir.pem cert-ext-ns.der cert-over-max-altnames.cfg cert-over-max-altnames.der cert-over-max-altnames.pem cert-over-max-nc.cfg cert-over-max-nc.der cert-over-max-nc.pem client-ecc-cert-ski.hex cn-ip-literal.der cn-ip-wildcard.der crit-cert.pem crit-key.pem dh1024.der dh1024.pem dh512.der dh512.pem digsigku.pem encrypteddata.msg gen-badsig.sh gen-ext-certs.sh gen-testcerts.sh include.am kari-keyid-cms.msg ktri-keyid-cms.msg ossl-trusted-cert.pem server-badaltname.der server-badaltname.pem server-badaltnull.der server-badaltnull.pem server-badcn.der server-badcn.pem server-badcnnull.der server-badcnnull.pem server-cert-ecc-badsig.der server-cert-ecc-badsig.pem server-cert-rsa-badsig.der server-cert-rsa-badsig.pem server-duplicate-policy.pem server-garbage.der server-garbage.pem server-goodalt.der server-goodalt.pem server-goodaltwild.der server-goodaltwild.pem server-goodcn.der server-goodcn.pem server-goodcnwild.der server-goodcnwild.pem server-localhost.der server-localhost.pem smime-test-canon.p7s smime-test-multipart-badsig.p7s smime-test-multipart.p7s smime-test.p7stest-pathlen
assemble-chains.sh chainA-ICA1-key.pem chainA-ICA1-pathlen0.pem chainA-assembled.pem chainA-entity-key.pem chainA-entity.pem chainB-ICA1-key.pem chainB-ICA1-pathlen0.pem chainB-ICA2-key.pem chainB-ICA2-pathlen1.pem chainB-assembled.pem chainB-entity-key.pem chainB-entity.pem chainC-ICA1-key.pem chainC-ICA1-pathlen1.pem chainC-assembled.pem chainC-entity-key.pem chainC-entity.pem chainD-ICA1-key.pem chainD-ICA1-pathlen127.pem chainD-assembled.pem chainD-entity-key.pem chainD-entity.pem chainE-ICA1-key.pem chainE-ICA1-pathlen128.pem chainE-assembled.pem chainE-entity-key.pem chainE-entity.pem chainF-ICA1-key.pem chainF-ICA1-pathlen1.pem chainF-ICA2-key.pem chainF-ICA2-pathlen0.pem chainF-assembled.pem chainF-entity-key.pem chainF-entity.pem chainG-ICA1-key.pem chainG-ICA1-pathlen0.pem chainG-ICA2-key.pem chainG-ICA2-pathlen1.pem chainG-ICA3-key.pem chainG-ICA3-pathlen99.pem chainG-ICA4-key.pem chainG-ICA4-pathlen5.pem chainG-ICA5-key.pem chainG-ICA5-pathlen20.pem chainG-ICA6-key.pem chainG-ICA6-pathlen10.pem chainG-ICA7-key.pem chainG-ICA7-pathlen100.pem chainG-assembled.pem chainG-entity-key.pem chainG-entity.pem chainH-ICA1-key.pem chainH-ICA1-pathlen0.pem chainH-ICA2-key.pem chainH-ICA2-pathlen2.pem chainH-ICA3-key.pem chainH-ICA3-pathlen2.pem chainH-ICA4-key.pem chainH-ICA4-pathlen2.pem chainH-assembled.pem chainH-entity-key.pem chainH-entity.pem chainI-ICA1-key.pem chainI-ICA1-no_pathlen.pem chainI-ICA2-key.pem chainI-ICA2-no_pathlen.pem chainI-ICA3-key.pem chainI-ICA3-pathlen2.pem chainI-assembled.pem chainI-entity-key.pem chainI-entity.pem chainJ-ICA1-key.pem chainJ-ICA1-no_pathlen.pem chainJ-ICA2-key.pem chainJ-ICA2-no_pathlen.pem chainJ-ICA3-key.pem chainJ-ICA3-no_pathlen.pem chainJ-ICA4-key.pem chainJ-ICA4-pathlen2.pem chainJ-assembled.pem chainJ-entity-key.pem chainJ-entity.pem include.am refreshkeys.shtest-serial0
ee_normal.pem ee_serial0.pem generate_certs.sh include.am intermediate_serial0.pem root_serial0.pem root_serial0_key.pem selfsigned_nonca_serial0.pemxmss
bc_xmss_chain_ca.der bc_xmss_chain_leaf.der bc_xmss_sha2_10_256_root.der bc_xmss_sha2_16_256_root.der bc_xmssmt_sha2_20_2_256_root.der bc_xmssmt_sha2_20_4_256_root.der bc_xmssmt_sha2_40_8_256_root.der include.amcmake
Config.cmake.in README.md config.in functions.cmake include.am options.h.in wolfssl-config-version.cmake.in wolfssl-targets.cmake.indebian
changelog.in control.in copyright include.am libwolfssl-dev.install libwolfssl.install rules.indoc
dox_comments
header_files
aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h puf.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wc_she.h wc_slhdsa.h wolfio.hheader_files-ja
aes.h arc4.h ascon.h asn.h asn_public.h blake2.h bn.h camellia.h chacha.h chacha20_poly1305.h cmac.h coding.h compress.h cryptocb.h curve25519.h curve448.h des3.h dh.h doxygen_groups.h doxygen_pages.h dsa.h ecc.h eccsi.h ed25519.h ed448.h error-crypt.h evp.h hash.h hmac.h iotsafe.h kdf.h logging.h md2.h md4.h md5.h memory.h ocsp.h pem.h pkcs11.h pkcs7.h poly1305.h psa.h pwdbased.h quic.h random.h ripemd.h rsa.h sakke.h sha.h sha256.h sha3.h sha512.h signature.h siphash.h srp.h ssl.h tfm.h types.h wc_encrypt.h wc_port.h wolfio.hexamples
async
Makefile README.md async_client.c async_server.c async_tls.c async_tls.h include.am user_settings.hconfigs
README.md include.am user_settings_EBSnet.h user_settings_all.h user_settings_arduino.h user_settings_baremetal.h user_settings_ca.h user_settings_curve25519nonblock.h user_settings_dtls13.h user_settings_eccnonblock.h user_settings_espressif.h user_settings_fipsv2.h user_settings_fipsv5.h user_settings_min_ecc.h user_settings_openssl_compat.h user_settings_pkcs7.h user_settings_platformio.h user_settings_pq.h user_settings_rsa_only.h user_settings_stm32.h user_settings_template.h user_settings_tls12.h user_settings_tls13.h user_settings_wolfboot_keytools.h user_settings_wolfssh.h user_settings_wolftpm.hechoclient
echoclient.c echoclient.h echoclient.sln echoclient.vcproj echoclient.vcxproj include.am quitlinuxkm
Kbuild Makefile README.md get_thread_size.c include.am linuxkm-fips-hash-wrapper.sh linuxkm-fips-hash.c linuxkm_memory.c linuxkm_memory.h linuxkm_wc_port.h lkcapi_aes_glue.c lkcapi_dh_glue.c lkcapi_ecdh_glue.c lkcapi_ecdsa_glue.c lkcapi_glue.c lkcapi_rsa_glue.c lkcapi_sha_glue.c module_exports.c.template module_hooks.c pie_redirect_table.c wolfcrypt.lds x86_vector_register_glue.cm4
ax_add_am_macro.m4 ax_am_jobserver.m4 ax_am_macros.m4 ax_append_compile_flags.m4 ax_append_flag.m4 ax_append_link_flags.m4 ax_append_to_file.m4 ax_atomic.m4 ax_bsdkm.m4 ax_check_compile_flag.m4 ax_check_link_flag.m4 ax_compiler_version.m4 ax_count_cpus.m4 ax_create_generic_config.m4 ax_debug.m4 ax_file_escapes.m4 ax_harden_compiler_flags.m4 ax_linuxkm.m4 ax_print_to_file.m4 ax_pthread.m4 ax_require_defined.m4 ax_tls.m4 ax_vcs_checkout.m4 hexversion.m4 lib_socket_nsl.m4 visibility.m4mqx
wolfcrypt_benchmark
ReferencedRSESystems.xml wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_benchmark_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchwolfcrypt_test
ReferencedRSESystems.xml wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfcrypt_test_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchwolfssl_client
ReferencedRSESystems.xml wolfssl_client_twrk70f120m_Int_Flash_DDRData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_DDRData_Release_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.jlink wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_JTrace.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Debug_PnE_U-MultiLink.launch wolfssl_client_twrk70f120m_Int_Flash_SramData_Release_PnE_U-MultiLink.launchscripts
aria-cmake-build-test.sh asn1_oid_sum.pl benchmark.test benchmark_compare.sh cleanup_testfiles.sh crl-gen-openssl.test crl-revoked.test dertoc.pl dtls.test dtlscid.test external.test google.test include.am makedistsmall.sh memtest.sh ocsp-responder-openssl-interop.test ocsp-stapling-with-ca-as-responder.test ocsp-stapling-with-wolfssl-responder.test ocsp-stapling.test ocsp-stapling2.test ocsp-stapling_tls13multi.test ocsp.test openssl.test openssl_srtp.test pem.test ping.test pkcallbacks.test psk.test resume.test rsapss.test sniffer-gen.sh sniffer-ipv6.pcap sniffer-static-rsa.pcap sniffer-testsuite.test sniffer-tls12-keylog.out sniffer-tls12-keylog.pcap sniffer-tls12-keylog.sslkeylog sniffer-tls13-dh-resume.pcap sniffer-tls13-dh.pcap sniffer-tls13-ecc-resume.pcap sniffer-tls13-ecc.pcap sniffer-tls13-hrr.pcap sniffer-tls13-keylog.out sniffer-tls13-keylog.pcap sniffer-tls13-keylog.sslkeylog sniffer-tls13-x25519-resume.pcap sniffer-tls13-x25519.pcap stm32l4-v4_0_1_build.sh tls13.test trusted_peer.test unit.test.in user_settings_asm.shsrc
bio.c conf.c crl.c dtls.c dtls13.c include.am internal.c keys.c ocsp.c pk.c pk_ec.c pk_rsa.c quic.c sniffer.c ssl.c ssl_api_cert.c ssl_api_crl_ocsp.c ssl_api_pk.c ssl_asn1.c ssl_bn.c ssl_certman.c ssl_crypto.c ssl_ech.c ssl_load.c ssl_misc.c ssl_p7p12.c ssl_sess.c ssl_sk.c tls.c tls13.c wolfio.c x509.c x509_str.ctests
api
api.h api_decl.h create_ocsp_test_blobs.py include.am test_aes.c test_aes.h test_arc4.c test_arc4.h test_ascon.c test_ascon.h test_ascon_kats.h test_asn.c test_asn.h test_blake2.c test_blake2.h test_camellia.c test_camellia.h test_certman.c test_certman.h test_chacha.c test_chacha.h test_chacha20_poly1305.c test_chacha20_poly1305.h test_cmac.c test_cmac.h test_curve25519.c test_curve25519.h test_curve448.c test_curve448.h test_des3.c test_des3.h test_dh.c test_dh.h test_digest.h test_dsa.c test_dsa.h test_dtls.c test_dtls.h test_ecc.c test_ecc.h test_ed25519.c test_ed25519.h test_ed448.c test_ed448.h test_evp.c test_evp.h test_evp_cipher.c test_evp_cipher.h test_evp_digest.c test_evp_digest.h test_evp_pkey.c test_evp_pkey.h test_hash.c test_hash.h test_hmac.c test_hmac.h test_md2.c test_md2.h test_md4.c test_md4.h test_md5.c test_md5.h test_mldsa.c test_mldsa.h test_mlkem.c test_mlkem.h test_ocsp.c test_ocsp.h test_ocsp_test_blobs.h test_ossl_asn1.c test_ossl_asn1.h test_ossl_bio.c test_ossl_bio.h test_ossl_bn.c test_ossl_bn.h test_ossl_cipher.c test_ossl_cipher.h test_ossl_dgst.c test_ossl_dgst.h test_ossl_dh.c test_ossl_dh.h test_ossl_dsa.c test_ossl_dsa.h test_ossl_ec.c test_ossl_ec.h test_ossl_ecx.c test_ossl_ecx.h test_ossl_mac.c test_ossl_mac.h test_ossl_obj.c test_ossl_obj.h test_ossl_p7p12.c test_ossl_p7p12.h test_ossl_pem.c test_ossl_pem.h test_ossl_rand.c test_ossl_rand.h test_ossl_rsa.c test_ossl_rsa.h test_ossl_sk.c test_ossl_sk.h test_ossl_x509.c test_ossl_x509.h test_ossl_x509_acert.c test_ossl_x509_acert.h test_ossl_x509_crypto.c test_ossl_x509_crypto.h test_ossl_x509_ext.c test_ossl_x509_ext.h test_ossl_x509_info.c test_ossl_x509_info.h test_ossl_x509_io.c test_ossl_x509_io.h test_ossl_x509_lu.c test_ossl_x509_lu.h test_ossl_x509_name.c test_ossl_x509_name.h test_ossl_x509_pk.c test_ossl_x509_pk.h test_ossl_x509_str.c test_ossl_x509_str.h test_ossl_x509_vp.c test_ossl_x509_vp.h test_pkcs12.c test_pkcs12.h test_pkcs7.c test_pkcs7.h test_poly1305.c test_poly1305.h test_random.c test_random.h test_rc2.c test_rc2.h test_ripemd.c test_ripemd.h test_rsa.c test_rsa.h test_sha.c test_sha.h test_sha256.c test_sha256.h test_sha3.c test_sha3.h test_sha512.c test_sha512.h test_she.c test_she.h test_signature.c test_signature.h test_slhdsa.c test_slhdsa.h test_sm2.c test_sm2.h test_sm3.c test_sm3.h test_sm4.c test_sm4.h test_tls.c test_tls.h test_tls13.c test_tls13.h test_tls_ext.c test_tls_ext.h test_wc_encrypt.c test_wc_encrypt.h test_wolfmath.c test_wolfmath.h test_x509.c test_x509.hwolfcrypt
benchmark
README.md benchmark-VS2022.sln benchmark-VS2022.vcxproj benchmark-VS2022.vcxproj.user benchmark.c benchmark.h benchmark.sln benchmark.vcproj benchmark.vcxproj include.amsrc
port
Espressif
esp_crt_bundle
README.md cacrt_all.pem cacrt_deprecated.pem cacrt_local.pem esp_crt_bundle.c gen_crt_bundle.py pio_install_cryptography.pyRenesas
README.md renesas_common.c renesas_fspsm_aes.c renesas_fspsm_rsa.c renesas_fspsm_sha.c renesas_fspsm_util.c renesas_rx64_hw_sha.c renesas_rx64_hw_util.c renesas_tsip_aes.c renesas_tsip_rsa.c renesas_tsip_sha.c renesas_tsip_util.carm
armv8-32-aes-asm.S armv8-32-aes-asm_c.c armv8-32-chacha-asm.S armv8-32-chacha-asm_c.c armv8-32-curve25519.S armv8-32-curve25519_c.c armv8-32-mlkem-asm.S armv8-32-mlkem-asm_c.c armv8-32-poly1305-asm.S armv8-32-poly1305-asm_c.c armv8-32-sha256-asm.S armv8-32-sha256-asm_c.c armv8-32-sha3-asm.S armv8-32-sha3-asm_c.c armv8-32-sha512-asm.S armv8-32-sha512-asm_c.c armv8-aes-asm.S armv8-aes-asm_c.c armv8-aes.c armv8-chacha-asm.S armv8-chacha-asm_c.c armv8-curve25519.S armv8-curve25519_c.c armv8-mlkem-asm.S armv8-mlkem-asm_c.c armv8-poly1305-asm.S armv8-poly1305-asm_c.c armv8-sha256-asm.S armv8-sha256-asm_c.c armv8-sha256.c armv8-sha3-asm.S armv8-sha3-asm_c.c armv8-sha512-asm.S armv8-sha512-asm_c.c armv8-sha512.c cryptoCell.c cryptoCellHash.c thumb2-aes-asm.S thumb2-aes-asm_c.c thumb2-chacha-asm.S thumb2-chacha-asm_c.c thumb2-curve25519.S thumb2-curve25519_c.c thumb2-mlkem-asm.S thumb2-mlkem-asm_c.c thumb2-poly1305-asm.S thumb2-poly1305-asm_c.c thumb2-sha256-asm.S thumb2-sha256-asm_c.c thumb2-sha3-asm.S thumb2-sha3-asm_c.c thumb2-sha512-asm.S thumb2-sha512-asm_c.ccaam
README.md caam_aes.c caam_doc.pdf caam_driver.c caam_error.c caam_integrity.c caam_qnx.c caam_sha.c wolfcaam_aes.c wolfcaam_cmac.c wolfcaam_ecdsa.c wolfcaam_fsl_nxp.c wolfcaam_hash.c wolfcaam_hmac.c wolfcaam_init.c wolfcaam_qnx.c wolfcaam_rsa.c wolfcaam_seco.c wolfcaam_x25519.cdevcrypto
README.md devcrypto_aes.c devcrypto_ecdsa.c devcrypto_hash.c devcrypto_hmac.c devcrypto_rsa.c devcrypto_x25519.c wc_devcrypto.criscv
riscv-64-aes.c riscv-64-chacha.c riscv-64-poly1305.c riscv-64-sha256.c riscv-64-sha3.c riscv-64-sha512.cwolfssl
openssl
aes.h asn1.h asn1t.h bio.h bn.h buffer.h camellia.h cmac.h cms.h compat_types.h conf.h crypto.h des.h dh.h dsa.h ec.h ec25519.h ec448.h ecdh.h ecdsa.h ed25519.h ed448.h engine.h err.h evp.h fips_rand.h hmac.h include.am kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h opensslconf.h opensslv.h ossl_typ.h pem.h pkcs12.h pkcs7.h rand.h rc4.h ripemd.h rsa.h safestack.h sha.h sha3.h srp.h ssl.h ssl23.h stack.h tls1.h txt_db.h ui.h x509.h x509_vfy.h x509v3.hwolfcrypt
port
Renesas
renesas-fspsm-crypt.h renesas-fspsm-types.h renesas-rx64-hw-crypt.h renesas-tsip-crypt.h renesas_cmn.h renesas_fspsm_internal.h renesas_sync.h renesas_tsip_internal.h renesas_tsip_types.hcaam
caam_driver.h caam_error.h caam_qnx.h wolfcaam.h wolfcaam_aes.h wolfcaam_cmac.h wolfcaam_ecdsa.h wolfcaam_fsl_nxp.h wolfcaam_hash.h wolfcaam_qnx.h wolfcaam_rsa.h wolfcaam_seco.h wolfcaam_sha.h wolfcaam_x25519.hwrapper
Ada
examples
src
aes_verify_main.adb rsa_verify_main.adb sha256_main.adb spark_sockets.adb spark_sockets.ads spark_terminal.adb spark_terminal.ads tls_client.adb tls_client.ads tls_client_main.adb tls_server.adb tls_server.ads tls_server_main.adbtests
src
aes_bindings_tests.adb aes_bindings_tests.ads rsa_verify_bindings_tests.adb rsa_verify_bindings_tests.ads sha256_bindings_tests.adb sha256_bindings_tests.ads tests.adbCSharp
wolfSSL-Example-IOCallbacks
App.config wolfSSL-Example-IOCallbacks.cs wolfSSL-Example-IOCallbacks.csprojwolfSSL-TLS-ServerThreaded
App.config wolfSSL-TLS-ServerThreaded.cs wolfSSL-TLS-ServerThreaded.csprojrust
wolfssl-wolfcrypt
src
aes.rs blake2.rs chacha20_poly1305.rs cmac.rs cmac_mac.rs curve25519.rs dh.rs dilithium.rs ecc.rs ecdsa.rs ed25519.rs ed448.rs fips.rs hkdf.rs hmac.rs hmac_mac.rs kdf.rs lib.rs lms.rs mlkem.rs mlkem_kem.rs pbkdf2_password_hash.rs prf.rs random.rs rsa.rs rsa_pkcs1v15.rs sha.rs sha_digest.rs sys.rstests
test_aes.rs test_blake2.rs test_chacha20_poly1305.rs test_cmac.rs test_cmac_mac.rs test_curve25519.rs test_dh.rs test_dilithium.rs test_ecc.rs test_ecdsa.rs test_ed25519.rs test_ed448.rs test_hkdf.rs test_hmac.rs test_hmac_mac.rs test_kdf.rs test_lms.rs test_mlkem.rs test_mlkem_kem.rs test_pbkdf2_password_hash.rs test_prf.rs test_random.rs test_rsa.rs test_rsa_pkcs1v15.rs test_sha.rs test_sha_digest.rs test_wolfcrypt.rszephyr
samples
wolfssl_benchmark
CMakeLists.txt README install_test.sh prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.confwolfssl_test
CMakeLists.txt README install_test.sh prj-no-malloc.conf prj.conf sample.yaml zephyr_legacy.conf zephyr_v4.1.conf
wolfssl/wolfcrypt/src/wc_pkcs11.c
raw
1/* wc_pkcs11.c
2 *
3 * Copyright (C) 2006-2026 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24#ifdef HAVE_PKCS11
25
26#ifndef HAVE_PKCS11_STATIC
27#include <dlfcn.h>
28#endif
29
30#include <wolfssl/wolfcrypt/wc_pkcs11.h>
31#include <wolfssl/wolfcrypt/asn.h>
32#ifndef NO_RSA
33 #include <wolfssl/wolfcrypt/rsa.h>
34#endif
35#ifdef NO_INLINE
36 #include <wolfssl/wolfcrypt/misc.h>
37#else
38 #define WOLFSSL_MISC_INCLUDED
39 #include <wolfcrypt/src/misc.c>
40#endif
41
42#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
43 /* FIPS build has replaced ecc.h. */
44 #define wc_ecc_key_get_priv(key) (&((key)->k))
45 #define WOLFSSL_HAVE_ECC_KEY_GET_PRIV
46#endif
47
48#if defined(NO_PKCS11_RSA) && !defined(NO_RSA)
49 #define NO_RSA
50#endif
51#if defined(NO_PKCS11_ECC) && defined(HAVE_ECC)
52 #undef HAVE_ECC
53#endif
54#if defined(NO_PKCS11_AES) && !defined(NO_AES)
55 #define NO_AES
56#endif
57#if defined(NO_PKCS11_AESGCM) && defined(HAVE_AESGCM)
58 #undef HAVE_AESGCM
59#endif
60#if defined(NO_PKCS11_AESCBC) && defined(HAVE_AES_CBC)
61 #undef HAVE_AES_CBC
62#endif
63#if defined(NO_PKCS11_HMAC) && !defined(NO_HMAC)
64 #define NO_HMAC
65#endif
66#if defined(NO_PKCS11_RNG) && !defined(WC_NO_RNG)
67 #define WC_NO_RNG
68#endif
69#if defined(NO_PKCS11_MLDSA) && defined(HAVE_DILITHIUM)
70 #undef HAVE_DILITHIUM
71#endif
72#if defined(NO_PKCS11_MLKEM) && defined(WOLFSSL_HAVE_MLKEM)
73 #undef WOLFSSL_HAVE_MLKEM
74#endif
75
76
77#if (defined(HAVE_ECC) && !defined(NO_PKCS11_ECDH)) || \
78 defined(WOLFSSL_HAVE_MLKEM)
79/* Pointer to false required for templates. */
80static CK_BBOOL ckFalse = CK_FALSE;
81#endif
82#if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \
83 (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || \
84 !defined(NO_HMAC) || defined(HAVE_DILITHIUM) || \
85 defined(WOLFSSL_HAVE_MLKEM)
86/* Pointer to true required for templates. */
87static CK_BBOOL ckTrue = CK_TRUE;
88#endif
89
90#ifndef NO_RSA
91/* Pointer to RSA key type required for templates. */
92static CK_KEY_TYPE rsaKeyType = CKK_RSA;
93#endif
94#ifdef HAVE_ECC
95/* Pointer to EC key type required for templates. */
96static CK_KEY_TYPE ecKeyType = CKK_EC;
97#endif
98#if defined(WOLFSSL_HAVE_MLKEM)
99/* Pointer to ML-KEM key type required for templates. */
100static CK_KEY_TYPE mlkemKeyType = CKK_ML_KEM;
101#endif
102#if defined(HAVE_DILITHIUM)
103/* Pointer to ML-DSA key type required for templates. */
104static CK_KEY_TYPE mldsaKeyType = CKK_ML_DSA;
105#endif
106#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_DILITHIUM) || \
107 defined(WOLFSSL_HAVE_MLKEM)
108/* Pointer to public key class required for templates. */
109static CK_OBJECT_CLASS pubKeyClass = CKO_PUBLIC_KEY;
110/* Pointer to private key class required for templates. */
111static CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY;
112#endif
113#if (!defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || \
114 !defined(NO_HMAC) || (defined(HAVE_ECC) && !defined(NO_PKCS11_ECDH)) || \
115 defined(WOLFSSL_HAVE_MLKEM)
116/* Pointer to secret key class required for templates. */
117static CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY;
118#endif
119
120#if (!defined(NO_AES) && (defined(WOLFSSL_AES_COUNTER)))
121/* AES CTR parameter structure for PKCS#11. */
122typedef struct CK_AES_CTR_PARAMS {
123 CK_ULONG ulCounterBits;
124 CK_BYTE cb[WC_AES_BLOCK_SIZE];
125} CK_AES_CTR_PARAMS;
126#endif
127
128#if !defined(NO_CERTS)
129static CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
130#endif
131
132#ifdef WOLFSSL_DEBUG_PKCS11
133/* Enable logging of PKCS#11 calls and return value. */
134#define PKCS11_RV(op, rv) pkcs11_rv(op, rv)
135/* Enable logging of PKCS#11 calls and value. */
136#define PKCS11_VAL(op, val) pkcs11_val(op, val)
137/* Enable logging of PKCS#11 template. */
138#define PKCS11_DUMP_TEMPLATE(name, templ, cnt) \
139 pkcs11_dump_template(name, templ, cnt)
140/* Enable logging of PKCS#11 mechanism info. */
141#define PKCS11_DUMP_MECHANSIM(name, mechanism) \
142 pkcs11_dump_mechanism(name, mechanism)
143
144/* Formats of template items - used to instruct how to log information. */
145enum PKCS11_TYPE_FORMATS {
146 PKCS11_FMT_BOOLEAN,
147 PKCS11_FMT_CLASS,
148 PKCS11_FMT_KEY_TYPE,
149 PKCS11_FMT_STRING,
150 PKCS11_FMT_NUMBER,
151 PKCS11_FMT_DATA,
152 PKCS11_FMT_POINTER
153};
154/* Information for logging a template item. */
155static struct PKCS11_TYPE_STR {
156 /** Attribute type in template. */
157 CK_ATTRIBUTE_TYPE type;
158 /** String to log corresponding to attribute type. */
159 const char* str;
160 /** Format of data associated with template item. */
161 int format;
162} typeStr[] = {
163 { CKA_CLASS, "CKA_CLASS", PKCS11_FMT_CLASS },
164 { CKA_TOKEN, "CKA_TOKEN", PKCS11_FMT_BOOLEAN },
165 { CKA_PRIVATE, "CKA_PRIVATE", PKCS11_FMT_BOOLEAN },
166 { CKA_LABEL, "CKA_LABEL", PKCS11_FMT_STRING },
167 { CKA_VALUE, "CKA_VALUE", PKCS11_FMT_DATA },
168 { CKA_OBJECT_ID, "CKA_OBJECT_ID", PKCS11_FMT_POINTER },
169 { CKA_KEY_TYPE, "CKA_KEY_TYPE", PKCS11_FMT_KEY_TYPE },
170 { CKA_ID, "CKA_ID", PKCS11_FMT_DATA },
171 { CKA_SENSITIVE, "CKA_SENSITIVE", PKCS11_FMT_BOOLEAN },
172 { CKA_ENCRYPT, "CKA_ENCRYPT", PKCS11_FMT_BOOLEAN },
173 { CKA_DECRYPT, "CKA_DECRYPT", PKCS11_FMT_BOOLEAN },
174 { CKA_SIGN, "CKA_SIGN", PKCS11_FMT_BOOLEAN },
175 { CKA_VERIFY, "CKA_VERIFY", PKCS11_FMT_BOOLEAN },
176 { CKA_DERIVE, "CKA_DERIVE", PKCS11_FMT_BOOLEAN },
177 { CKA_MODULUS_BITS, "CKA_MODULUS_BITS", PKCS11_FMT_NUMBER },
178 { CKA_MODULUS, "CKA_MODULUS", PKCS11_FMT_DATA },
179 { CKA_PUBLIC_EXPONENT, "CKA_PUBLIC_EXPONENT", PKCS11_FMT_DATA },
180 { CKA_PRIVATE_EXPONENT, "CKA_PRIVATE_EXPONENT", PKCS11_FMT_DATA },
181 { CKA_PRIME_1, "CKA_PRIME_1", PKCS11_FMT_DATA },
182 { CKA_PRIME_2, "CKA_PRIME_2", PKCS11_FMT_DATA },
183 { CKA_EXPONENT_1, "CKA_EXPONENT_1", PKCS11_FMT_DATA },
184 { CKA_EXPONENT_2, "CKA_EXPONENT_2", PKCS11_FMT_DATA },
185 { CKA_VALUE_LEN, "CKA_VALUE_LEN", PKCS11_FMT_NUMBER },
186 { CKA_COEFFICIENT, "CKA_COEFFICIENT", PKCS11_FMT_DATA },
187 { CKA_EXTRACTABLE, "CKA_EXTRACTABLE", PKCS11_FMT_BOOLEAN },
188 { CKA_EC_PARAMS, "CKA_EC_PARAMS", PKCS11_FMT_DATA },
189 { CKA_EC_POINT, "CKA_EC_POINT", PKCS11_FMT_DATA },
190 { CKA_ENCAPSULATE, "CKA_ENCAPSULATE", PKCS11_FMT_BOOLEAN },
191 { CKA_DECAPSULATE, "CKA_DECAPSULATE", PKCS11_FMT_BOOLEAN },
192 { CKA_PARAMETER_SET, "CKA_PARAMETER_SET", PKCS11_FMT_NUMBER },
193};
194/* Count of known attribute types for logging. */
195#define PKCS11_TYPE_STR_CNT ((int)(sizeof(typeStr) / sizeof(*typeStr)))
196
197/*
198 * Dump/log the PKCS #11 template.
199 *
200 * This is only for debugging purposes. Only the values needed are recognised.
201 *
202 * @param [in] name PKCS #11 template name.
203 * @param [in] templ PKCS #11 template to dump.
204 * @param [in] cnt Count of template entries.
205 */
206static void pkcs11_dump_template(const char* name, CK_ATTRIBUTE* templ,
207 CK_ULONG cnt)
208{
209 CK_ULONG i;
210 int j;
211 char line[80];
212 char type[25];
213 int format;
214 CK_KEY_TYPE keyType;
215 CK_OBJECT_CLASS keyClass;
216
217 WOLFSSL_MSG(name);
218
219 for (i = 0; i < cnt; i++) {
220 format = PKCS11_FMT_POINTER;
221
222 for (j = 0; j < PKCS11_TYPE_STR_CNT; j++) {
223 if (templ[i].type == typeStr[j].type) {
224 XSNPRINTF(type, sizeof(type), "%s", typeStr[j].str);
225 format = typeStr[j].format;
226 break;
227 }
228 }
229 if (j == PKCS11_TYPE_STR_CNT) {
230 XSNPRINTF(type, sizeof(type), "%08lxUL", templ[i].type);
231 }
232
233 switch (format) {
234 case PKCS11_FMT_BOOLEAN:
235#if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \
236 (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || !defined(NO_HMAC)
237 if (templ[i].pValue == &ckTrue) {
238 XSNPRINTF(line, sizeof(line), "%25s: TRUE", type);
239 WOLFSSL_MSG(line);
240 }
241 else
242#endif
243#if defined(HAVE_ECC) && !defined(NO_PKCS11_ECDH)
244 if (templ[i].pValue == &ckFalse) {
245 XSNPRINTF(line, sizeof(line), "%25s: FALSE", type);
246 WOLFSSL_MSG(line);
247 }
248 else
249#endif
250 {
251 XSNPRINTF(line, sizeof(line), "%25s: INVALID (%p)", type,
252 templ[i].pValue);
253 WOLFSSL_MSG(line);
254 }
255 break;
256 case PKCS11_FMT_CLASS:
257 keyClass = *(CK_OBJECT_CLASS*)templ[i].pValue;
258 if (keyClass == CKO_PUBLIC_KEY) {
259 XSNPRINTF(line, sizeof(line), "%25s: PUBLIC", type);
260 WOLFSSL_MSG(line);
261 }
262 else if (keyClass == CKO_PRIVATE_KEY) {
263 XSNPRINTF(line, sizeof(line), "%25s: PRIVATE", type);
264 WOLFSSL_MSG(line);
265 }
266 else if (keyClass == CKO_SECRET_KEY) {
267 XSNPRINTF(line, sizeof(line), "%25s: SECRET", type);
268 WOLFSSL_MSG(line);
269 }
270 else if (keyClass == CKO_CERTIFICATE) {
271 XSNPRINTF(line, sizeof(line), "%25s: CERTIFICATE", type);
272 WOLFSSL_MSG(line);
273 }
274 else
275 {
276 XSNPRINTF(line, sizeof(line), "%25s: UNKNOWN (%p)", type,
277 templ[i].pValue);
278 WOLFSSL_MSG(line);
279 }
280 break;
281 case PKCS11_FMT_KEY_TYPE:
282 keyType = *(CK_KEY_TYPE*)templ[i].pValue;
283 switch (keyType) {
284 case CKK_RSA:
285 XSNPRINTF(line, sizeof(line), "%25s: RSA", type);
286 break;
287 case CKK_DH:
288 XSNPRINTF(line, sizeof(line), "%25s: DH", type);
289 break;
290 case CKK_EC:
291 XSNPRINTF(line, sizeof(line), "%25s: EC", type);
292 break;
293 case CKK_GENERIC_SECRET:
294 XSNPRINTF(line, sizeof(line), "%25s: GENERIC_SECRET", type);
295 break;
296 case CKK_AES:
297 XSNPRINTF(line, sizeof(line), "%25s: AES", type);
298 break;
299 case CKK_MD5_HMAC:
300 XSNPRINTF(line, sizeof(line), "%25s: MD5_HMAC", type);
301 break;
302 case CKK_SHA_1_HMAC:
303 XSNPRINTF(line, sizeof(line), "%25s: SHA_1_HMAC", type);
304 break;
305 case CKK_SHA256_HMAC:
306 XSNPRINTF(line, sizeof(line), "%25s: SHA256_HMAC", type);
307 break;
308 case CKK_SHA384_HMAC:
309 XSNPRINTF(line, sizeof(line), "%25s: SHA384_HMAC", type);
310 break;
311 case CKK_SHA512_HMAC:
312 XSNPRINTF(line, sizeof(line), "%25s: SHA512_HMAC", type);
313 break;
314 case CKK_SHA224_HMAC:
315 XSNPRINTF(line, sizeof(line), "%25s: SHA224_HMAC", type);
316 break;
317 case CKK_ML_DSA:
318 XSNPRINTF(line, sizeof(line), "%25s: ML_DSA", type);
319 break;
320 case CKK_ML_KEM:
321 XSNPRINTF(line, sizeof(line), "%25s: ML_KEM", type);
322 break;
323 default:
324 XSNPRINTF(line, sizeof(line), "%25s: UNKNOWN (%08lx)", type,
325 keyType);
326 break;
327 }
328 WOLFSSL_MSG(line);
329 break;
330 case PKCS11_FMT_STRING:
331 XSNPRINTF(line, sizeof(line), "%25s: %s", type,
332 (char*)templ[i].pValue);
333 WOLFSSL_MSG(line);
334 break;
335 case PKCS11_FMT_NUMBER:
336 if (templ[i].ulValueLen <= 1) {
337 XSNPRINTF(line, sizeof(line), "%25s: 0x%02x (%d)", type,
338 *(byte*)templ[i].pValue, *(byte*)templ[i].pValue);
339 }
340 else if (templ[i].ulValueLen <= 2) {
341 XSNPRINTF(line, sizeof(line), "%25s: 0x%04x (%d)", type,
342 *(word16*)templ[i].pValue, *(word16*)templ[i].pValue);
343 }
344 else if (templ[i].ulValueLen <= 4) {
345 XSNPRINTF(line, sizeof(line), "%25s: 0x%08x (%d)", type,
346 *(word32*)templ[i].pValue, *(word32*)templ[i].pValue);
347 }
348 else if (templ[i].ulValueLen <= 8) {
349 XSNPRINTF(line, sizeof(line), "%25s: 0x%016lx (%ld)", type,
350 *(word64*)templ[i].pValue, *(word64*)templ[i].pValue);
351 }
352 else {
353 XSNPRINTF(line, sizeof(line), "%25s: INVALID (%ld)", type,
354 templ[i].ulValueLen);
355 }
356 WOLFSSL_MSG(line);
357 break;
358 case PKCS11_FMT_DATA:
359 if (templ[i].ulValueLen == CK_UNAVAILABLE_INFORMATION) {
360 XSNPRINTF(line, sizeof(line), "%25s: unavailable", type);
361 WOLFSSL_MSG(line);
362 break;
363 }
364 XSNPRINTF(line, sizeof(line), "%25s: %ld", type,
365 templ[i].ulValueLen);
366 WOLFSSL_MSG(line);
367 if (templ[i].pValue == NULL) {
368 XSNPRINTF(line, sizeof(line), "%27s(nil)", "");
369 WOLFSSL_MSG(line);
370 break;
371 }
372 XSNPRINTF(line, sizeof(line), "%27s", "");
373 for (j = 0; j < (int)templ[i].ulValueLen && j < 80; j++) {
374 char hex[6];
375 XSNPRINTF(hex, sizeof(hex), "0x%02x,",
376 ((byte*)templ[i].pValue)[j]);
377 XSTRNCAT(line, hex, sizeof(line) - XSTRLEN(line) - 1);
378 if ((j % 8) == 7) {
379 WOLFSSL_MSG(line);
380 XSNPRINTF(line, sizeof(line), "%27s", "");
381 }
382 }
383 if (j == (int)templ[i].ulValueLen) {
384 if ((j % 8) != 0) {
385 WOLFSSL_MSG(line);
386 }
387 }
388 else if (j < (int)templ[i].ulValueLen) {
389 XSNPRINTF(line, sizeof(line), "%27s...", "");
390 WOLFSSL_MSG(line);
391 }
392 break;
393 case PKCS11_FMT_POINTER:
394 XSNPRINTF(line, sizeof(line), "%25s: %p %ld", type, templ[i].pValue,
395 templ[i].ulValueLen);
396 WOLFSSL_MSG(line);
397 break;
398 }
399 }
400}
401
402/* Information for logging a mechanism */
403static struct PKCS11_MECHANISM_STR {
404 /** Mechanism. */
405 CK_MECHANISM_TYPE mech;
406 /** String to log corresponding mechanism. */
407 const char* str;
408} mechStr[] = {
409 { CKM_RSA_PKCS_KEY_PAIR_GEN, "CKM_RSA_PKCS_KEY_PAIR_GEN" },
410 { CKM_RSA_X_509, "CKM_RSA_X_509" },
411 { CKM_DH_PKCS_KEY_PAIR_GEN, "CKM_DH_PKCS_KEY_PAIR_GEN" },
412 { CKM_DH_PKCS_DERIVE, "CKM_DH_PKCS_DERIVE" },
413 { CKM_MD5_HMAC, "CKM_MD5_HMAC" },
414 { CKM_SHA_1_HMAC, "CKM_SHA_1_HMAC" },
415 { CKM_SHA256_HMAC, "CKM_SHA256_HMAC" },
416 { CKM_SHA224_HMAC, "CKM_SHA224_HMAC" },
417 { CKM_SHA384_HMAC, "CKM_SHA384_HMAC" },
418 { CKM_SHA512_HMAC, "CKM_SHA512_HMAC" },
419 { CKM_GENERIC_SECRET_KEY_GEN, "CKM_GENERIC_SECRET_KEY_GEN" },
420 { CKM_EC_KEY_PAIR_GEN, "CKM_EC_KEY_PAIR_GEN" },
421 { CKM_ECDSA, "CKM_ECDSA" },
422 { CKM_ECDH1_DERIVE, "CKM_ECDH1_DERIVE" },
423 { CKM_ECDH1_COFACTOR_DERIVE, "CKM_ECDH1_COFACTOR_DERIVE" },
424 { CKM_AES_KEY_GEN, "CKM_AES_KEY_GEN" },
425 { CKM_AES_CBC, "CKM_AES_CBC" },
426 { CKM_AES_GCM, "CKM_AES_GCM" },
427 { CKM_ML_KEM_KEY_PAIR_GEN, "CKM_ML_KEM_KEY_PAIR_GEN" },
428 { CKM_ML_KEM, "CKM_ML_KEM" },
429 { CKM_ML_DSA_KEY_PAIR_GEN, "CKM_ML_DSA_KEY_PAIR_GEN" },
430 { CKM_ML_DSA, "CKM_ML_DSA" },
431 { CKM_HASH_ML_DSA, "CKM_HASH_ML_DSA" },
432};
433/* Count of known mechanism for logging. */
434#define PKCS11_MECH_STR_CNT ((int)(sizeof(mechStr) / sizeof(*mechStr)))
435
436/*
437 * Dump/log the PKCS #11 mechanism.
438 *
439 * This is only for debugging purposes. Only the values needed are recognised.
440 *
441 * @param [in] op PKCS #11 operation that was attempted.
442 * @param [in] mech PKCS #11 mechanism to dump.
443 */
444static void pkcs11_dump_mechanism(const char* op, CK_MECHANISM_TYPE mech)
445{
446 char line[80];
447 const char *mechName = NULL;
448 int i;
449
450 for (i = 0; i < PKCS11_MECH_STR_CNT; i++) {
451 if (mech == mechStr[i].mech) {
452 mechName = mechStr[i].str;
453 break;
454 }
455 }
456 if (i == PKCS11_MECH_STR_CNT) {
457 mechName = "UNKNOWN";
458 }
459
460 XSNPRINTF(line, 80, "%s: %s", op, mechName);
461
462 WOLFSSL_MSG(line);
463}
464
465/*
466 * Log a PKCS #11 return value with the name of function called.
467 *
468 * This is only for debugging purposes. Only the values needed are recognized.
469 *
470 * @param [in] op PKCS #11 operation that was attempted.
471 * @param [in] rv PKCS #11 return value.
472 */
473static void pkcs11_rv(const char* op, CK_RV rv)
474{
475 char line[80];
476
477 if (rv == CKR_OK) {
478 XSNPRINTF(line, 80, "%s: OK", op);
479 }
480 else if (rv == CKR_MECHANISM_INVALID) {
481 XSNPRINTF(line, 80, "%s: MECHANISM_INVALID", op);
482 }
483 else if (rv == CKR_SIGNATURE_INVALID) {
484 XSNPRINTF(line, 80, "%s: SIGNATURE_INVALID", op);
485 }
486 else {
487 XSNPRINTF(line, 80, "%s: %08lxUL (FAILED)", op, rv);
488 }
489
490 WOLFSSL_MSG(line);
491}
492
493/*
494 * Log a value from a PKCS #11 operation.
495 *
496 * This is only for debugging purposes.
497 *
498 * @param [in] op PKCS #11 operation that was attempted.
499 * @param [in] val Value to log.
500 */
501static void pkcs11_val(const char* op, CK_ULONG val)
502{
503 char line[80];
504
505 XSNPRINTF(line, 80, "%s: %ld", op, val);
506
507 WOLFSSL_MSG(line);
508}
509#else
510/* Disable logging of PKCS#11 calls and return value. */
511#define PKCS11_RV(op, ev) WC_DO_NOTHING
512/* Disable logging of PKCS#11 calls and value. */
513#define PKCS11_VAL(op, val) WC_DO_NOTHING
514/* Disable logging of PKCS#11 template. */
515#define PKCS11_DUMP_TEMPLATE(name, templ, cnt) WC_DO_NOTHING
516/* Disable logging of PKCS#11 mechanism info. */
517#define PKCS11_DUMP_MECHANSIM(name, mechanism) WC_DO_NOTHING
518#endif
519
520/**
521 * Load library, get function list and initialize PKCS#11.
522 *
523 * @param [in] dev Device object.
524 * @param [in] library Library name including path.
525 * @param [in] heap Heap hint.
526 * @return BAD_FUNC_ARG when dev or library are NULL pointers.
527 * @return BAD_PATH_ERROR when dynamic library cannot be opened.
528 * @return WC_INIT_E when the initialization PKCS#11 fails.
529 * @return WC_HW_E when unable to get PKCS#11 function list.
530 * @return 0 on success.
531 */
532int wc_Pkcs11_Initialize(Pkcs11Dev* dev, const char* library, void* heap)
533{
534 return wc_Pkcs11_Initialize_v3(dev, library, heap, NULL, NULL, NULL);
535}
536
537/**
538 * Load library, get function list and initialize PKCS#11.
539 *
540 * @param [in] dev Device object.
541 * @param [in] library Library name including path.
542 * @param [in] heap Heap hint.
543 * @param [out] rvp PKCS#11 return value. Last return value seen.
544 * May be NULL.
545 * @return BAD_FUNC_ARG when dev or library are NULL pointers.
546 * @return BAD_PATH_ERROR when dynamic library cannot be opened.
547 * @return WC_INIT_E when the initialization PKCS#11 fails.
548 * @return WC_HW_E when unable to get PKCS#11 function list.
549 * @return 0 on success.
550 */
551int wc_Pkcs11_Initialize_ex(Pkcs11Dev* dev, const char* library, void* heap,
552 CK_RV* rvp)
553{
554 return wc_Pkcs11_Initialize_v3(dev, library, heap, NULL, NULL, rvp);
555}
556
557/**
558 * Load library, get function list and initialize PKCS#11.
559 *
560 * @param [in] dev Device object.
561 * @param [in] library Library name including path.
562 * @param [in] heap Heap hint.
563 * @param [in,out] version On in, desired version of interface.
564 * On out, actual obtained version of interface.
565 * @param [in] interfaceName Name of the interface to use.
566 * @param [out] rvp PKCS#11 return value. Last return value seen.
567 * May be NULL.
568 * @return BAD_FUNC_ARG when dev or library are NULL pointers.
569 * @return BAD_PATH_ERROR when dynamic library cannot be opened.
570 * @return WC_INIT_E when the initialization PKCS#11 fails.
571 * @return WC_HW_E when unable to get PKCS#11 function list.
572 * @return 0 on success.
573 */
574int wc_Pkcs11_Initialize_v3(Pkcs11Dev* dev, const char* library,
575 void* heap, int* version, const char* interfaceName, CK_RV* rvp)
576{
577 int ret = 0;
578 CK_RV rv = CKR_OK;
579#if !defined(HAVE_PKCS11_STATIC) && !defined(HAVE_PKCS11_V3_STATIC)
580 void* func;
581#endif
582 CK_C_INITIALIZE_ARGS args;
583 CK_VERSION_PTR version_ptr = NULL;
584
585 if (dev == NULL)
586 ret = BAD_FUNC_ARG;
587
588#if !defined(HAVE_PKCS11_STATIC) && !defined(HAVE_PKCS11_V3_STATIC)
589 if (library == NULL)
590 ret = BAD_FUNC_ARG;
591#endif
592
593 if (ret == 0) {
594 dev->heap = heap;
595#if defined(HAVE_PKCS11_V3_STATIC)
596 CK_INTERFACE_PTR interface = NULL;
597 CK_VERSION pkcs11_version = {0, 0};
598
599 if (version != NULL) {
600 if (*version == WC_PCKS11VERSION_2_20) {
601 pkcs11_version.major = 2;
602 pkcs11_version.minor = 20;
603 }
604 else if (*version == WC_PCKS11VERSION_2_40) {
605 pkcs11_version.major = 2;
606 pkcs11_version.minor = 40;
607 }
608 else if (*version == WC_PCKS11VERSION_3_0) {
609 pkcs11_version.major = 3;
610 pkcs11_version.minor = 0;
611 }
612 else if (*version == WC_PCKS11VERSION_3_1) {
613 pkcs11_version.major = 3;
614 pkcs11_version.minor = 1;
615 }
616 else if (*version == WC_PCKS11VERSION_3_2) {
617 pkcs11_version.major = 3;
618 pkcs11_version.minor = 2;
619 }
620 version_ptr = &pkcs11_version;
621 }
622 else {
623 version_ptr = NULL;
624 }
625
626 rv = C_GetInterface((CK_UTF8CHAR_PTR) interfaceName, version_ptr,
627 &interface, 0);
628
629 if (rv == CKR_OK) {
630 dev->func = interface->pFunctionList;
631 version_ptr = (CK_VERSION_PTR) interface->pFunctionList;
632 if (version_ptr->major == 2 && version_ptr->minor == 20) {
633 dev->version = WC_PCKS11VERSION_2_20;
634 }
635 else if (version_ptr->major == 2 &&
636 version_ptr->minor == 40) {
637 dev->version = WC_PCKS11VERSION_2_40;
638 }
639 else if (version_ptr->major == 3 &&
640 version_ptr->minor == 0) {
641 dev->version = WC_PCKS11VERSION_3_0;
642 }
643 else if (version_ptr->major == 3 &&
644 version_ptr->minor == 1) {
645 dev->version = WC_PCKS11VERSION_3_1;
646 }
647 else if (version_ptr->major == 3 &&
648 version_ptr->minor == 2) {
649 dev->version = WC_PCKS11VERSION_3_2;
650 }
651 else {
652 WOLFSSL_MSG_EX("Unsupported PKCS#11 version: %d.%d",
653 version_ptr->major, version_ptr->minor);
654 ret = WC_HW_E;
655 }
656 }
657 else {
658 PKCS11_RV("CK_C_GetInterface", rv);
659 ret = WC_HW_E;
660 }
661#elif defined(HAVE_PKCS11_STATIC)
662 rv = C_GetFunctionList(&dev->func);
663 if (rv == CKR_OK) {
664 version_ptr = (CK_VERSION_PTR) dev->func;
665 if (version_ptr->major == 2 &&
666 version_ptr->minor == 20) {
667 dev->version = WC_PCKS11VERSION_2_20;
668 }
669 else if (version_ptr->major == 2 &&
670 version_ptr->minor == 40) {
671 dev->version = WC_PCKS11VERSION_2_40;
672 }
673 else {
674 WOLFSSL_MSG_EX("Unsupported PKCS#11 version: %d.%d",
675 version_ptr->major,
676 version_ptr->minor);
677 ret = WC_HW_E;
678 }
679 }
680 else {
681 PKCS11_RV("CK_C_GetFunctionList", rv);
682 ret = WC_HW_E;
683 }
684#else
685 /* Load dynamic library */
686 dev->dlHandle = dlopen(library, RTLD_NOW | RTLD_LOCAL);
687 if (dev->dlHandle == NULL) {
688 WOLFSSL_MSG(dlerror());
689 ret = BAD_PATH_ERROR;
690 }
691
692 if (ret == 0) {
693 /* Check if the library supports PKCS#11 version 3.0 (or above) by
694 * looking for the C_GetInterface method (only present for >= V3.0).
695 */
696 func = dlsym(dev->dlHandle, "C_GetInterface");
697 if (func != NULL) {
698 /* Function is present, use it */
699 CK_INTERFACE_PTR interface = NULL;
700 CK_VERSION pkcs11_version = {0, 0};
701 if (version != NULL) {
702 if (*version == WC_PCKS11VERSION_2_20) {
703 pkcs11_version.major = 2;
704 pkcs11_version.minor = 20;
705 }
706 else if (*version == WC_PCKS11VERSION_2_40) {
707 pkcs11_version.major = 2;
708 pkcs11_version.minor = 40;
709 }
710 else if (*version == WC_PCKS11VERSION_3_0) {
711 pkcs11_version.major = 3;
712 pkcs11_version.minor = 0;
713 }
714 else if (*version == WC_PCKS11VERSION_3_1) {
715 pkcs11_version.major = 3;
716 pkcs11_version.minor = 1;
717 }
718 else if (*version == WC_PCKS11VERSION_3_2) {
719 pkcs11_version.major = 3;
720 pkcs11_version.minor = 2;
721 }
722 version_ptr = &pkcs11_version;
723 }
724 else {
725 version_ptr = NULL;
726 }
727
728 rv = ((CK_C_GetInterface)func)((CK_UTF8CHAR_PTR) interfaceName,
729 version_ptr, &interface, 0);
730 if (rv == CKR_OK) {
731 dev->func = interface->pFunctionList;
732 version_ptr = (CK_VERSION_PTR) interface->pFunctionList;
733 if (version_ptr->major == 2 && version_ptr->minor == 20) {
734 dev->version = WC_PCKS11VERSION_2_20;
735 }
736 else if (version_ptr->major == 2 &&
737 version_ptr->minor == 40) {
738 dev->version = WC_PCKS11VERSION_2_40;
739 }
740 else if (version_ptr->major == 3 &&
741 version_ptr->minor == 0) {
742 dev->version = WC_PCKS11VERSION_3_0;
743 }
744 else if (version_ptr->major == 3 &&
745 version_ptr->minor == 1) {
746 dev->version = WC_PCKS11VERSION_3_1;
747 }
748 else if (version_ptr->major == 3 &&
749 version_ptr->minor == 2) {
750 dev->version = WC_PCKS11VERSION_3_2;
751 }
752 else {
753 WOLFSSL_MSG_EX("Unsupported PKCS#11 version: %d.%d",
754 version_ptr->major, version_ptr->minor);
755 ret = WC_HW_E;
756 }
757 }
758 else {
759 PKCS11_RV("CK_C_GetInterface", rv);
760 ret = WC_HW_E;
761 }
762 }
763 else {
764 /* Function not present, try a 2.x library by looking for
765 * C_GetFunctionList. */
766 func = dlsym(dev->dlHandle, "C_GetFunctionList");
767 if (func == NULL) {
768 #if defined(_WIN32)
769 WOLFSSL_MSG_EX("GetProcAddress(): %d", GetLastError());
770 #else
771 WOLFSSL_MSG(dlerror());
772 #endif
773 ret = WC_HW_E;
774 }
775 if (ret == 0) {
776 rv = ((CK_C_GetFunctionList)func)(&dev->func);
777 if (rv == CKR_OK) {
778 version_ptr = (CK_VERSION_PTR) dev->func;
779 if (version_ptr->major == 2 &&
780 version_ptr->minor == 20) {
781 dev->version = WC_PCKS11VERSION_2_20;
782 }
783 else if (version_ptr->major == 2 &&
784 version_ptr->minor == 40) {
785 dev->version = WC_PCKS11VERSION_2_40;
786 }
787 else {
788 WOLFSSL_MSG_EX("Unsupported PKCS#11 version: %d.%d",
789 version_ptr->major,
790 version_ptr->minor);
791 ret = WC_HW_E;
792 }
793 }
794 else {
795 PKCS11_RV("CK_C_GetFunctionList", rv);
796 ret = WC_HW_E;
797 }
798 }
799 }
800 }
801#endif
802 }
803
804 if (ret == 0 && version != NULL)
805 *version = dev->version;
806
807 if (ret == 0) {
808 XMEMSET(&args, 0x00, sizeof(args));
809 args.flags = CKF_OS_LOCKING_OK;
810 rv = dev->func->C_Initialize(&args);
811 if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
812 WOLFSSL_MSG("PKCS#11 already initialized");
813 rv = CKR_OK;
814 }
815 else if (rv != CKR_OK) {
816 PKCS11_RV("C_Initialize", rv);
817 ret = WC_INIT_E;
818 }
819 }
820
821 if (rvp != NULL) {
822 *rvp = rv;
823 }
824
825 if (ret != 0) {
826 wc_Pkcs11_Finalize(dev);
827 }
828
829 return ret;
830}
831
832/**
833 * Close the Pkcs#11 library.
834 *
835 * @param [in] dev Device object.
836 */
837void wc_Pkcs11_Finalize(Pkcs11Dev* dev)
838{
839 if (dev != NULL
840#if !defined(HAVE_PKCS11_STATIC) && !defined(HAVE_PKCS11_V3_STATIC)
841 && dev->dlHandle != NULL
842#endif
843 ) {
844 if (dev->func != NULL) {
845 dev->func->C_Finalize(NULL);
846 dev->func = NULL;
847 }
848#if !defined(HAVE_PKCS11_STATIC) && !defined(HAVE_PKCS11_V3_STATIC)
849 dlclose(dev->dlHandle);
850 dev->dlHandle = NULL;
851#endif
852 }
853}
854
855/* lookup by token name and return slotId or (-1) if not found */
856static int Pkcs11Slot_FindByTokenName(Pkcs11Dev* dev,
857 const char* tokenName, size_t tokenNameSz)
858{
859 int ret = -1;
860 CK_RV rv;
861 CK_ULONG slotCnt = 0;
862 CK_TOKEN_INFO tinfo;
863 int idx = -1;
864 CK_SLOT_ID* slot = NULL;
865
866 rv = dev->func->C_GetSlotList(CK_TRUE, NULL, &slotCnt);
867 if (rv == CKR_OK) {
868 slot = (CK_SLOT_ID*)XMALLOC(slotCnt * sizeof(*slot), dev->heap,
869 DYNAMIC_TYPE_TMP_BUFFER);
870 if (slot == NULL)
871 goto out;
872 rv = dev->func->C_GetSlotList(CK_TRUE, slot, &slotCnt);
873 if (rv != CKR_OK)
874 goto out;
875 for (idx = 0; idx < (int)slotCnt; idx++) {
876 rv = dev->func->C_GetTokenInfo(slot[idx], &tinfo);
877 PKCS11_RV("C_GetTokenInfo", rv);
878 if (rv == CKR_OK &&
879 XMEMCMP(tinfo.label, tokenName, tokenNameSz) == 0) {
880 ret = (int)slot[idx];
881 break;
882 }
883 }
884 }
885
886out:
887 XFREE(slot, dev->heap, DYNAMIC_TYPE_TMP_BUFFER);
888 return ret;
889}
890
891/* lookup by slotId or tokenName */
892static int Pkcs11Token_Init(Pkcs11Token* token, Pkcs11Dev* dev, int slotId,
893 const char* tokenName, size_t tokenNameSz)
894{
895 int ret = 0;
896 CK_RV rv;
897 CK_SLOT_ID* slot = NULL;
898 CK_ULONG slotCnt = 0;
899
900 if (token == NULL || dev == NULL) {
901 ret = BAD_FUNC_ARG;
902 }
903
904 if (ret == 0) {
905 if (slotId < 0) {
906 rv = dev->func->C_GetSlotList(CK_TRUE, NULL, &slotCnt);
907 PKCS11_RV("C_GetSlotList", rv);
908 if (rv != CKR_OK) {
909 ret = WC_HW_E;
910 }
911 if (ret == 0) {
912 slot = (CK_SLOT_ID*)XMALLOC(slotCnt * sizeof(*slot), dev->heap,
913 DYNAMIC_TYPE_TMP_BUFFER);
914 if (slot == NULL)
915 ret = MEMORY_E;
916 }
917 if (ret == 0) {
918 rv = dev->func->C_GetSlotList(CK_TRUE, slot, &slotCnt);
919 PKCS11_RV("C_GetSlotList", rv);
920 if (rv != CKR_OK) {
921 ret = WC_HW_E;
922 }
923 }
924 if (ret == 0) {
925 if (tokenName != NULL && tokenNameSz > 0) {
926 /* find based on token name */
927 slotId = Pkcs11Slot_FindByTokenName(dev,
928 tokenName, tokenNameSz);
929 }
930 else {
931 /* Use first available slot with a token. */
932 slotId = (int)slot[0];
933 }
934 }
935 }
936 else {
937 /* verify slotId is valid */
938 CK_SLOT_INFO sinfo;
939 rv = dev->func->C_GetSlotInfo(slotId, &sinfo);
940 PKCS11_RV("C_GetSlotInfo", rv);
941 if (rv != CKR_OK) {
942 ret = WC_INIT_E;
943 }
944 }
945 }
946 if (ret == 0) {
947 token->func = dev->func;
948 token->slotId = (CK_SLOT_ID)slotId;
949 token->handle = NULL_PTR;
950 token->userPin = NULL_PTR;
951 token->userPinSz = 0;
952 token->userPinLogin = 0;
953 token->version = dev->version;
954 }
955
956 XFREE(slot, dev->heap, DYNAMIC_TYPE_TMP_BUFFER);
957
958 return ret;
959}
960
961/**
962 * Set up a token for use. Lookup by slotId or tokenName. Set User PIN.
963 *
964 * @param [in] token Token object.
965 * @param [in] dev PKCS#11 device object.
966 * @param [in] slotId Slot number of the token.<br>
967 * Passing -1 uses the first available slot.
968 * @param [in] tokenName Name of token to initialize (optional)
969 * @param [in] userPin PIN to use to login as user.
970 * @param [in] userPinSz Number of bytes in PIN.
971 * @return BAD_FUNC_ARG when token, dev and/or tokenName is NULL.
972 * @return WC_INIT_E when initializing token fails.
973 * @return WC_HW_E when another PKCS#11 library call fails.
974 * @return 0 on success.
975 */
976int wc_Pkcs11Token_Init(Pkcs11Token* token, Pkcs11Dev* dev, int slotId,
977 const char* tokenName, const unsigned char* userPin, int userPinSz)
978{
979 int ret;
980 size_t tokenNameSz = 0;
981
982 if (tokenName != NULL) {
983 tokenNameSz = XSTRLEN(tokenName);
984 }
985 ret = Pkcs11Token_Init(token, dev, slotId, tokenName, tokenNameSz);
986 if (ret == 0 && userPin != NULL) {
987 token->userPin = (CK_UTF8CHAR_PTR)userPin;
988 token->userPinSz = (CK_ULONG)userPinSz;
989 token->userPinLogin = 1;
990 }
991
992 return ret;
993}
994
995/**
996 * Set up a token for use. Lookup by slotId or tokenName.
997 *
998 * @param [in] token Token object.
999 * @param [in] dev PKCS#11 device object.
1000 * @param [in] slotId Slot number of the token.<br>
1001 * Passing -1 uses the first available slot.
1002 * @param [in] tokenName Name of token to initialize (optional)
1003 * @return BAD_FUNC_ARG when token, dev and/or tokenName is NULL.
1004 * @return WC_INIT_E when initializing token fails.
1005 * @return WC_HW_E when another PKCS#11 library call fails.
1006 * @return 0 on success.
1007 */
1008int wc_Pkcs11Token_Init_NoLogin(Pkcs11Token* token, Pkcs11Dev* dev, int slotId,
1009 const char* tokenName)
1010{
1011 size_t tokenNameSz = 0;
1012 if (tokenName != NULL) {
1013 tokenNameSz = XSTRLEN(tokenName);
1014 }
1015 return Pkcs11Token_Init(token, dev, slotId, tokenName, tokenNameSz);
1016}
1017
1018/**
1019 * Set up a token for use. Lookup by slotId or tokenName/size. Set User PIN.
1020 *
1021 * @param [in] token Token object.
1022 * @param [in] dev PKCS#11 device object.
1023 * @param [in] tokenName Name of token to initialize.
1024 * @param [in] tokenNameSz Name size for token
1025 * @param [in] userPin PIN to use to login as user.
1026 * @param [in] userPinSz Number of bytes in PIN.
1027 * @return BAD_FUNC_ARG when token, dev and/or tokenName is NULL.
1028 * @return WC_INIT_E when initializing token fails.
1029 * @return WC_HW_E when another PKCS#11 library call fails.
1030 * @return 0 on success.
1031 */
1032int wc_Pkcs11Token_InitName(Pkcs11Token* token, Pkcs11Dev* dev,
1033 const char* tokenName, int tokenNameSz,
1034 const unsigned char* userPin, int userPinSz)
1035{
1036 int ret = Pkcs11Token_Init(token, dev, -1, tokenName, (size_t)tokenNameSz);
1037 if (ret == 0 && userPin != NULL) {
1038 token->userPin = (CK_UTF8CHAR_PTR)userPin;
1039 token->userPinSz = (CK_ULONG)userPinSz;
1040 token->userPinLogin = 1;
1041 }
1042
1043 return ret;
1044}
1045
1046/**
1047 * Set up a token for use. Lookup by slotId or tokenName/size.
1048 *
1049 * @param [in] token Token object.
1050 * @param [in] dev PKCS#11 device object.
1051 * @param [in] tokenName Name of token to initialize.
1052 * @param [in] tokenNameSz Name size for token
1053 * @param [in] userPin PIN to use to login as user.
1054 * @param [in] userPinSz Number of bytes in PIN.
1055 * @return BAD_FUNC_ARG when token, dev and/or tokenName is NULL.
1056 * @return WC_INIT_E when initializing token fails.
1057 * @return WC_HW_E when another PKCS#11 library call fails.
1058 * @return 0 on success.
1059 */
1060int wc_Pkcs11Token_InitName_NoLogin(Pkcs11Token* token, Pkcs11Dev* dev,
1061 const char* tokenName, int tokenNameSz)
1062{
1063 return Pkcs11Token_Init(token, dev, -1, tokenName, (size_t)tokenNameSz);
1064}
1065
1066/**
1067 * Finalize token.
1068 * Closes all sessions on token.
1069 *
1070 * @param [in] token Token object.
1071 */
1072void wc_Pkcs11Token_Final(Pkcs11Token* token)
1073{
1074 if (token != NULL && token->func != NULL) {
1075 token->func->C_CloseAllSessions(token->slotId);
1076 token->handle = NULL_PTR;
1077 ForceZero(token->userPin, (word32)token->userPinSz);
1078 }
1079}
1080
1081/**
1082 * Open a session on a token.
1083 *
1084 * @param [in] token Token object.
1085 * @param [in] session Session object.
1086 * @param [in] readWrite Boolean indicating to open session for Read/Write.
1087 * @return BAD_FUNC_ARG when token or session is NULL.
1088 * @return WC_HW_E when opening the session fails.
1089 * @return 0 on success.
1090 */
1091static int Pkcs11OpenSession(Pkcs11Token* token, Pkcs11Session* session,
1092 int readWrite)
1093{
1094 int ret = 0;
1095 CK_RV rv;
1096
1097 if (token == NULL || session == NULL)
1098 ret = BAD_FUNC_ARG;
1099
1100 if (ret == 0) {
1101 if (token->handle != NULL_PTR)
1102 session->handle = token->handle;
1103 else {
1104 /* Create a new session. */
1105 CK_FLAGS flags = CKF_SERIAL_SESSION;
1106
1107 if (readWrite)
1108 flags |= CKF_RW_SESSION;
1109
1110 rv = token->func->C_OpenSession(token->slotId, flags,
1111 (CK_VOID_PTR)NULL, (CK_NOTIFY)NULL,
1112 &session->handle);
1113 PKCS11_RV("C_OpenSession", rv);
1114 if (rv != CKR_OK) {
1115 ret = WC_HW_E;
1116 }
1117 if (ret == 0 && token->userPinLogin) {
1118 rv = token->func->C_Login(session->handle, CKU_USER,
1119 token->userPin, token->userPinSz);
1120 PKCS11_RV("C_Login", rv);
1121 if (rv != CKR_OK) {
1122 ret = WC_HW_E;
1123 }
1124 }
1125 }
1126 }
1127 if (ret == 0) {
1128 session->func = token->func;
1129 session->slotId = token->slotId;
1130 session->version = token->version;
1131 }
1132
1133 return ret;
1134}
1135
1136/**
1137 * Close a session on a token.
1138 * Won't close a session created externally.
1139 *
1140 * @param [in] token Token object.
1141 * @param [in] session Session object.
1142 */
1143static void Pkcs11CloseSession(Pkcs11Token* token, Pkcs11Session* session)
1144{
1145 if (token != NULL && session != NULL && token->handle != session->handle) {
1146 if (token->userPin != NULL)
1147 session->func->C_Logout(session->handle);
1148 session->func->C_CloseSession(session->handle);
1149 }
1150}
1151
1152/**
1153 * Open a session on the token to be used for all operations.
1154 *
1155 * @param [in] token Token object.
1156 * @param [in] readWrite Boolean indicating to open session for Read/Write.
1157 * @return BAD_FUNC_ARG when token is NULL.
1158 * @return WC_HW_E when opening the session fails.
1159 * @return 0 on success.
1160 */
1161int wc_Pkcs11Token_Open(Pkcs11Token* token, int readWrite)
1162{
1163 int ret = 0;
1164 Pkcs11Session session;
1165
1166 if (token == NULL)
1167 ret = BAD_FUNC_ARG;
1168
1169 if (ret == 0) {
1170 ret = Pkcs11OpenSession(token, &session, readWrite);
1171 token->handle = session.handle;
1172 }
1173
1174 return ret;
1175}
1176
1177/**
1178 * Close the token's session.
1179 * All object, like keys, will be destroyed.
1180 *
1181 * @param [in] token Token object.
1182 */
1183void wc_Pkcs11Token_Close(Pkcs11Token* token)
1184{
1185 Pkcs11Session session;
1186
1187 if (token != NULL) {
1188 session.func = token->func;
1189 session.handle = token->handle;
1190 token->handle = NULL_PTR;
1191 Pkcs11CloseSession(token, &session);
1192 }
1193}
1194
1195
1196#if (!defined(NO_AES) && (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || \
1197 !defined(NO_HMAC)
1198/*
1199 * Create a secret key.
1200 *
1201 * @param [out] key Handle to key object.
1202 * @param [in] session Session object.
1203 * @param [in] keyType Type of secret key to create.
1204 * @param [in] data Data of the secret key.
1205 * @param [in] len Length of data in bytes.
1206 * @param [in] id Identifier to set against key.
1207 * @param [in] idLen Length of identifier.
1208 * @param [in] label Label to set against key.
1209 * @param [in] labelLen Length of label.
1210 * @param [in] op Operation to support with key.
1211 * @return WC_HW_E when another PKCS#11 library call fails.
1212 * @return 0 on success.
1213 */
1214static int Pkcs11CreateSecretKey(CK_OBJECT_HANDLE* key, Pkcs11Session* session,
1215 CK_KEY_TYPE keyType, unsigned char* data,
1216 int len, unsigned char* id, int idLen,
1217 char* label, int labelLen, int op)
1218{
1219 int ret = 0;
1220 CK_RV rv;
1221 /* Empty entries for optional label/ID. */
1222 CK_ATTRIBUTE keyTemplateEncDec[] = {
1223 { CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass) },
1224 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
1225 { CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) },
1226 { CKA_DECRYPT, &ckTrue, sizeof(ckTrue) },
1227 { CKA_VALUE, NULL, 0 },
1228 { 0, NULL, 0 },
1229 { 0, NULL, 0 }
1230 };
1231 /* Empty entries for optional label/ID. */
1232 CK_ATTRIBUTE keyTemplateSignVfy[] = {
1233 { CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass) },
1234 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
1235 { CKA_SIGN, &ckTrue, sizeof(ckTrue) },
1236 { CKA_VERIFY, &ckTrue, sizeof(ckTrue) },
1237 { CKA_VALUE, NULL, 0 },
1238 { 0, NULL, 0 },
1239 { 0, NULL, 0 }
1240 };
1241 CK_ATTRIBUTE* keyTemplate = NULL;
1242 /* 5 mandatory entries + 2 optional. */
1243 int keyTmplCnt = 5;
1244
1245 WOLFSSL_MSG("PKCS#11: Create Secret Key");
1246
1247 if (op == CKA_ENCRYPT || op == CKA_DECRYPT) {
1248 keyTemplate = keyTemplateEncDec;
1249 }
1250 else if (op == CKA_SIGN) {
1251 keyTemplate = keyTemplateSignVfy;
1252 }
1253 else {
1254 WOLFSSL_MSG("PKCS#11: Invalid operation type");
1255 ret = WC_HW_E;
1256 }
1257 if (ret == 0) {
1258 /* Set the secret to store. */
1259 keyTemplate[keyTmplCnt-1].pValue = data;
1260 keyTemplate[keyTmplCnt-1].ulValueLen = (CK_ULONG)len;
1261
1262 if (labelLen > 0) {
1263 keyTemplate[keyTmplCnt].type = CKA_LABEL;
1264 keyTemplate[keyTmplCnt].pValue = label;
1265 keyTemplate[keyTmplCnt].ulValueLen = labelLen;
1266 keyTmplCnt++;
1267 }
1268 if (idLen > 0) {
1269 keyTemplate[keyTmplCnt].type = CKA_ID;
1270 keyTemplate[keyTmplCnt].pValue = id;
1271 keyTemplate[keyTmplCnt].ulValueLen = idLen;
1272 keyTmplCnt++;
1273 }
1274
1275 PKCS11_DUMP_TEMPLATE("Secret Key", keyTemplate, keyTmplCnt);
1276 /* Create an object containing key data for device to use. */
1277 rv = session->func->C_CreateObject(session->handle, keyTemplate,
1278 keyTmplCnt, key);
1279 PKCS11_RV("C_CreateObject", rv);
1280 if (rv != CKR_OK) {
1281 ret = WC_HW_E;
1282 }
1283 }
1284
1285 return ret;
1286}
1287#endif
1288
1289#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
1290/**
1291 * Create a PKCS#11 object containing the RSA private key data.
1292 *
1293 * @param [out] privateKey Handle to private key object.
1294 * @param [in] session Session object.
1295 * @param [in] rsaKey RSA key with private key data.
1296 * @return WC_HW_E when a PKCS#11 library call fails.
1297 * @return 0 on success.
1298 */
1299static int Pkcs11CreateRsaPrivateKey(CK_OBJECT_HANDLE* privateKey,
1300 Pkcs11Session* session,
1301 RsaKey* rsaKey, int permanent)
1302{
1303 int ret = 0;
1304 CK_RV rv;
1305 /* Empty entries for optional label/ID. */
1306 CK_ATTRIBUTE keyTemplate[] = {
1307 { CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
1308 { CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) },
1309 { CKA_DECRYPT, &ckTrue, sizeof(ckTrue) },
1310 { CKA_SIGN, &ckTrue, sizeof(ckTrue) },
1311 { CKA_MODULUS, NULL, 0 },
1312 { CKA_PRIVATE_EXPONENT, NULL, 0 },
1313 { CKA_PRIME_1, NULL, 0 },
1314 { CKA_PRIME_2, NULL, 0 },
1315 { CKA_EXPONENT_1, NULL, 0 },
1316 { CKA_EXPONENT_2, NULL, 0 },
1317 { CKA_COEFFICIENT, NULL, 0 },
1318 { CKA_PUBLIC_EXPONENT, NULL, 0 },
1319 { 0, NULL, 0 },
1320 { 0, NULL, 0 }
1321 };
1322 /* Mandatory entries + 2 optional. */
1323 CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate) - 2;
1324
1325 /* Set the modulus and private key data. */
1326 keyTemplate[ 4].pValue = rsaKey->n.raw.buf;
1327 keyTemplate[ 4].ulValueLen = rsaKey->n.raw.len;
1328 keyTemplate[ 5].pValue = rsaKey->d.raw.buf;
1329 keyTemplate[ 5].ulValueLen = rsaKey->d.raw.len;
1330 keyTemplate[ 6].pValue = rsaKey->p.raw.buf;
1331 keyTemplate[ 6].ulValueLen = rsaKey->p.raw.len;
1332 keyTemplate[ 7].pValue = rsaKey->q.raw.buf;
1333 keyTemplate[ 7].ulValueLen = rsaKey->q.raw.len;
1334 keyTemplate[ 8].pValue = rsaKey->dP.raw.buf;
1335 keyTemplate[ 8].ulValueLen = rsaKey->dP.raw.len;
1336 keyTemplate[ 9].pValue = rsaKey->dQ.raw.buf;
1337 keyTemplate[ 9].ulValueLen = rsaKey->dQ.raw.len;
1338 keyTemplate[10].pValue = rsaKey->u.raw.buf;
1339 keyTemplate[10].ulValueLen = rsaKey->u.raw.len;
1340 keyTemplate[11].pValue = rsaKey->e.raw.buf;
1341 keyTemplate[11].ulValueLen = rsaKey->e.raw.len;
1342
1343 if (permanent && rsaKey->labelLen > 0) {
1344 keyTemplate[keyTmplCnt].type = CKA_LABEL;
1345 keyTemplate[keyTmplCnt].pValue = rsaKey->label;
1346 keyTemplate[keyTmplCnt].ulValueLen = rsaKey->labelLen;
1347 keyTmplCnt++;
1348 }
1349 if (permanent && rsaKey->idLen > 0) {
1350 keyTemplate[keyTmplCnt].type = CKA_ID;
1351 keyTemplate[keyTmplCnt].pValue = rsaKey->id;
1352 keyTemplate[keyTmplCnt].ulValueLen = rsaKey->idLen;
1353 keyTmplCnt++;
1354 }
1355
1356 PKCS11_DUMP_TEMPLATE("RSA Private Key", keyTemplate, keyTmplCnt);
1357 rv = session->func->C_CreateObject(session->handle, keyTemplate, keyTmplCnt,
1358 privateKey);
1359 PKCS11_RV("C_CreateObject", rv);
1360 if (rv != CKR_OK) {
1361 ret = WC_HW_E;
1362 }
1363
1364 return ret;
1365}
1366#endif /* !NO_RSA && WOLFSSL_KEY_GEN */
1367
1368#ifdef HAVE_ECC
1369/**
1370 * Set the ECC parameters into the template.
1371 *
1372 * @param [in] key ECC key.
1373 * @param [in] tmpl PKCS#11 template.
1374 * @param [in] idx Index of template to put parameters into.
1375 * @return NOT_COMPILED_IN when the EC parameters are not known.
1376 * @return 0 on success.
1377 */
1378static int Pkcs11EccSetParams(ecc_key* key, CK_ATTRIBUTE* tmpl, int idx)
1379{
1380 int ret = 0;
1381
1382 if (key != NULL && key->dp != NULL && key->dp->oid != NULL) {
1383 unsigned char* derParams = tmpl[idx].pValue;
1384 #if defined(HAVE_OID_ENCODING)
1385 word32 oidSz = ECC_MAX_OID_LEN - 2;
1386 ret = wc_EncodeObjectId(key->dp->oid, key->dp->oidSz, derParams+2, &oidSz);
1387 if (ret != 0) {
1388 return ret;
1389 }
1390 tmpl[idx].ulValueLen = oidSz + 2;
1391 derParams[0] = ASN_OBJECT_ID;
1392 derParams[1] = oidSz;
1393 #else
1394 /* ASN.1 encoding: OBJ + ecc parameters OID */
1395 tmpl[idx].ulValueLen = key->dp->oidSz + 2;
1396 derParams[0] = ASN_OBJECT_ID;
1397 derParams[1] = key->dp->oidSz;
1398 XMEMCPY(derParams + 2, key->dp->oid, key->dp->oidSz);
1399 #endif
1400 }
1401 else
1402 ret = NOT_COMPILED_IN;
1403
1404 return ret;
1405}
1406
1407/**
1408 * Create a PKCS#11 object containing the ECC public key data.
1409 * Encode the public key as an OCTET_STRING of the encoded point.
1410 *
1411 * @param [out] publicKey Handle to public key object.
1412 * @param [in] session Session object.
1413 * @param [in] public_key ECC public key.
1414 * @param [in] operation Cryptographic operation key is to be used for.
1415 * @return WC_HW_E when a PKCS#11 library call fails.
1416 * @return MEMORY_E when a memory allocation fails.
1417 * @return 0 on success.
1418 */
1419static int Pkcs11CreateEccPublicKey(CK_OBJECT_HANDLE* publicKey,
1420 Pkcs11Session* session,
1421 ecc_key* public_key,
1422 CK_ATTRIBUTE_TYPE operation)
1423{
1424 int ret = 0;
1425 int i;
1426 unsigned char* ecPoint = NULL;
1427 word32 len;
1428 CK_RV rv;
1429 CK_UTF8CHAR params[ECC_MAX_OID_LEN];
1430 /* Empty entries for optional label/ID. */
1431 CK_ATTRIBUTE keyTemplate[] = {
1432 { CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) },
1433 { CKA_KEY_TYPE, &ecKeyType, sizeof(ecKeyType) },
1434 { operation, &ckTrue, sizeof(ckTrue) },
1435 { CKA_EC_PARAMS, params, 0 },
1436 { CKA_EC_POINT, NULL, 0 },
1437 { 0, NULL, 0 },
1438 { 0, NULL, 0 }
1439 };
1440 /* Mandatory entries + 2 optional. */
1441 CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate) - 2;
1442
1443 if (public_key->labelLen > 0) {
1444 keyTemplate[keyTmplCnt].type = CKA_LABEL;
1445 keyTemplate[keyTmplCnt].pValue = public_key->label;
1446 keyTemplate[keyTmplCnt].ulValueLen = public_key->labelLen;
1447 keyTmplCnt++;
1448 }
1449 if (public_key->idLen > 0) {
1450 keyTemplate[keyTmplCnt].type = CKA_ID;
1451 keyTemplate[keyTmplCnt].pValue = public_key->id;
1452 keyTemplate[keyTmplCnt].ulValueLen = public_key->idLen;
1453 keyTmplCnt++;
1454 }
1455
1456 ret = Pkcs11EccSetParams(public_key, keyTemplate, 3);
1457 if (ret == 0) {
1458 /* ASN1 encoded: OCT + uncompressed point */
1459 len = 3 + 1 + 2 * public_key->dp->size;
1460 ecPoint = (unsigned char*)XMALLOC(len, public_key->heap,
1461 DYNAMIC_TYPE_ECC);
1462 if (ecPoint == NULL)
1463 ret = MEMORY_E;
1464 }
1465 if (ret == 0) {
1466 len -= 3;
1467 i = 0;
1468 ecPoint[i++] = ASN_OCTET_STRING;
1469 if (len >= ASN_LONG_LENGTH)
1470 ecPoint[i++] = ASN_LONG_LENGTH | 1;
1471 ecPoint[i++] = len;
1472 if (public_key->type == 0)
1473 public_key->type = ECC_PUBLICKEY;
1474 PRIVATE_KEY_UNLOCK();
1475 ret = wc_ecc_export_x963(public_key, ecPoint + i, &len);
1476 PRIVATE_KEY_LOCK();
1477 }
1478 if (ret == 0) {
1479 keyTemplate[4].pValue = ecPoint;
1480 keyTemplate[4].ulValueLen = len + i;
1481
1482 PKCS11_DUMP_TEMPLATE("Ec Public Key", keyTemplate, keyTmplCnt);
1483 rv = session->func->C_CreateObject(session->handle, keyTemplate,
1484 keyTmplCnt, publicKey);
1485 PKCS11_RV("C_CreateObject", rv);
1486 if (rv != CKR_OK) {
1487 ret = WC_HW_E;
1488 }
1489 }
1490
1491 XFREE(ecPoint, public_key->heap, DYNAMIC_TYPE_ECC);
1492
1493 return ret;
1494}
1495
1496/**
1497 * Create a PKCS#11 object containing the ECC private key data.
1498 *
1499 * @param privateKey [out] Handle to private key object.
1500 * @param session [in] Session object.
1501 * @param private_key [in] ECC private key.
1502 * @param operation [in] Cryptographic operation key is to be used for.
1503 * @return WC_HW_E when a PKCS#11 library call fails.
1504 * @return 0 on success.
1505 */
1506static int Pkcs11CreateEccPrivateKey(CK_OBJECT_HANDLE* privateKey,
1507 Pkcs11Session* session,
1508 ecc_key* private_key,
1509 CK_ATTRIBUTE_TYPE operation)
1510{
1511 int ret = 0;
1512 CK_RV rv;
1513 CK_UTF8CHAR params[ECC_MAX_OID_LEN];
1514 /* Empty entries for optional label/ID. */
1515 CK_ATTRIBUTE keyTemplate[] = {
1516 { CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
1517 { CKA_KEY_TYPE, &ecKeyType, sizeof(ecKeyType) },
1518 { operation, &ckTrue, sizeof(ckTrue) },
1519 { CKA_EC_PARAMS, params, 0 },
1520 { CKA_VALUE, NULL, 0 },
1521 { 0, NULL, 0 },
1522 { 0, NULL, 0 }
1523 };
1524 /* Mandatory entries + 2 optional. */
1525 CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate) - 2;
1526
1527 if (private_key->labelLen > 0) {
1528 keyTemplate[keyTmplCnt].type = CKA_LABEL;
1529 keyTemplate[keyTmplCnt].pValue = private_key->label;
1530 keyTemplate[keyTmplCnt].ulValueLen = private_key->labelLen;
1531 keyTmplCnt++;
1532 }
1533 if (private_key->idLen > 0) {
1534 keyTemplate[keyTmplCnt].type = CKA_ID;
1535 keyTemplate[keyTmplCnt].pValue = private_key->id;
1536 keyTemplate[keyTmplCnt].ulValueLen = private_key->idLen;
1537 keyTmplCnt++;
1538 }
1539
1540 ret = Pkcs11EccSetParams(private_key, keyTemplate, 3);
1541 if (ret == 0) {
1542 word32 privLen = private_key->dp->size;
1543 byte* priv = (byte*)XMALLOC(privLen, private_key->heap,
1544 DYNAMIC_TYPE_TMP_BUFFER);
1545 if (priv == NULL) {
1546 ret = MEMORY_E;
1547 }
1548 if (ret == 0) {
1549 PRIVATE_KEY_LOCK();
1550 ret = wc_ecc_export_private_only(private_key, priv, &privLen);
1551 PRIVATE_KEY_UNLOCK();
1552 }
1553 if (ret == 0) {
1554 keyTemplate[4].pValue = priv;
1555 keyTemplate[4].ulValueLen = privLen;
1556
1557 PKCS11_DUMP_TEMPLATE("Ec Private Key", keyTemplate, keyTmplCnt);
1558 rv = session->func->C_CreateObject(session->handle, keyTemplate,
1559 keyTmplCnt, privateKey);
1560 PKCS11_RV("C_CreateObject", rv);
1561 if (rv != CKR_OK) {
1562 ret = WC_HW_E;
1563 }
1564 }
1565 if (priv != NULL)
1566 ForceZero(priv, privLen);
1567 XFREE(priv, private_key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1568 }
1569
1570 return ret;
1571}
1572#endif
1573
1574#ifdef WOLFSSL_HAVE_MLKEM
1575/**
1576 * Create a PKCS#11 object containing the ML-KEM public key data.
1577 */
1578static int Pkcs11CreateMlKemPublicKey(CK_OBJECT_HANDLE* handle,
1579 Pkcs11Session* session,
1580 MlKemKey* key,
1581 CK_MECHANISM_INFO_PTR mechInfo)
1582{
1583 int ret = 0;
1584 CK_RV rv;
1585 CK_ULONG publicKeyLen = 0;
1586 CK_ML_KEM_PARAMETER_SET_TYPE param_set = 0;
1587 unsigned char* publicKey = NULL;
1588 CK_ATTRIBUTE keyTemplate[] = {
1589 { CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) },
1590 { CKA_KEY_TYPE, &mlkemKeyType, sizeof(mlkemKeyType) },
1591 { CKA_ENCAPSULATE, &ckTrue, sizeof(ckTrue) },
1592 { CKA_VALUE, NULL, 0 },
1593 { CKA_PARAMETER_SET, ¶m_set, sizeof(param_set) },
1594 { 0, NULL, 0 },
1595 { 0, NULL, 0 },
1596 };
1597 CK_ULONG keyTmplCnt =
1598 sizeof(keyTemplate) / sizeof(*keyTemplate) - 2;
1599
1600 if (mechInfo == NULL || (key->flags & MLKEM_FLAG_PUB_SET) == 0) {
1601 ret = BAD_FUNC_ARG;
1602 }
1603 if (ret == 0 && key->labelLen > 0) {
1604 keyTemplate[keyTmplCnt].type = CKA_LABEL;
1605 keyTemplate[keyTmplCnt].pValue = key->label;
1606 keyTemplate[keyTmplCnt].ulValueLen = key->labelLen;
1607 keyTmplCnt++;
1608 }
1609 if (ret == 0 && key->idLen > 0) {
1610 keyTemplate[keyTmplCnt].type = CKA_ID;
1611 keyTemplate[keyTmplCnt].pValue = key->id;
1612 keyTemplate[keyTmplCnt].ulValueLen = key->idLen;
1613 keyTmplCnt++;
1614 }
1615 if (ret == 0) {
1616 switch (key->type) {
1617 #ifndef WOLFSSL_NO_ML_KEM
1618 case WC_ML_KEM_512:
1619 param_set = CKP_ML_KEM_512;
1620 publicKeyLen = WC_ML_KEM_512_PUBLIC_KEY_SIZE;
1621 break;
1622 case WC_ML_KEM_768:
1623 param_set = CKP_ML_KEM_768;
1624 publicKeyLen = WC_ML_KEM_768_PUBLIC_KEY_SIZE;
1625 break;
1626 case WC_ML_KEM_1024:
1627 param_set = CKP_ML_KEM_1024;
1628 publicKeyLen = WC_ML_KEM_1024_PUBLIC_KEY_SIZE;
1629 break;
1630 default:
1631 ret = NOT_COMPILED_IN;
1632 break;
1633 #else
1634 default:
1635 ret = NOT_COMPILED_IN;
1636 break;
1637 #endif
1638 }
1639 }
1640 if ((ret == 0) &&
1641 ((mechInfo->ulMinKeySize > publicKeyLen) ||
1642 (mechInfo->ulMaxKeySize < publicKeyLen))) {
1643 ret = WC_KEY_SIZE_E;
1644 }
1645 if (ret == 0) {
1646 publicKey = (unsigned char*)XMALLOC(publicKeyLen, key->heap,
1647 DYNAMIC_TYPE_TMP_BUFFER);
1648 if (publicKey == NULL) {
1649 ret = MEMORY_E;
1650 }
1651 }
1652 if (ret == 0) {
1653 ret = wc_MlKemKey_EncodePublicKey(key, publicKey, (word32)publicKeyLen);
1654 }
1655 if (ret == 0) {
1656 keyTemplate[3].pValue = publicKey;
1657 keyTemplate[3].ulValueLen = publicKeyLen;
1658
1659 PKCS11_DUMP_TEMPLATE("ML-KEM Public Key", keyTemplate, keyTmplCnt);
1660 rv = session->func->C_CreateObject(session->handle, keyTemplate,
1661 keyTmplCnt, handle);
1662 PKCS11_RV("C_CreateObject", rv);
1663 if (rv != CKR_OK) {
1664 ret = WC_HW_E;
1665 }
1666 }
1667
1668 XFREE(publicKey, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1669
1670 return ret;
1671}
1672
1673/**
1674 * Create a PKCS#11 object containing the ML-KEM private key data.
1675 */
1676static int Pkcs11CreateMlKemPrivateKey(CK_OBJECT_HANDLE* privateKey,
1677 Pkcs11Session* session,
1678 MlKemKey* key,
1679 CK_MECHANISM_INFO_PTR mechInfo)
1680{
1681 int ret = 0;
1682 CK_RV rv;
1683 CK_ULONG privateKeyLen = 0;
1684 CK_ML_KEM_PARAMETER_SET_TYPE param_set = 0;
1685 unsigned char* privateData = NULL;
1686 CK_ATTRIBUTE keyTemplate[] = {
1687 { CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
1688 { CKA_KEY_TYPE, &mlkemKeyType, sizeof(mlkemKeyType) },
1689 { CKA_DECAPSULATE, &ckTrue, sizeof(ckTrue) },
1690 { CKA_VALUE, NULL, 0 },
1691 { CKA_PARAMETER_SET, ¶m_set, sizeof(param_set) },
1692 { 0, NULL, 0 },
1693 { 0, NULL, 0 },
1694 };
1695 CK_ULONG keyTmplCnt =
1696 sizeof(keyTemplate) / sizeof(*keyTemplate) - 2;
1697
1698 if (mechInfo == NULL || (key->flags & MLKEM_FLAG_PRIV_SET) == 0) {
1699 ret = BAD_FUNC_ARG;
1700 }
1701 if (ret == 0 && key->labelLen > 0) {
1702 keyTemplate[keyTmplCnt].type = CKA_LABEL;
1703 keyTemplate[keyTmplCnt].pValue = key->label;
1704 keyTemplate[keyTmplCnt].ulValueLen = key->labelLen;
1705 keyTmplCnt++;
1706 }
1707 if (ret == 0 && key->idLen > 0) {
1708 keyTemplate[keyTmplCnt].type = CKA_ID;
1709 keyTemplate[keyTmplCnt].pValue = key->id;
1710 keyTemplate[keyTmplCnt].ulValueLen = key->idLen;
1711 keyTmplCnt++;
1712 }
1713 if (ret == 0) {
1714 switch (key->type) {
1715 #ifndef WOLFSSL_NO_ML_KEM
1716 case WC_ML_KEM_512:
1717 param_set = CKP_ML_KEM_512;
1718 privateKeyLen = WC_ML_KEM_512_PRIVATE_KEY_SIZE;
1719 break;
1720 case WC_ML_KEM_768:
1721 param_set = CKP_ML_KEM_768;
1722 privateKeyLen = WC_ML_KEM_768_PRIVATE_KEY_SIZE;
1723 break;
1724 case WC_ML_KEM_1024:
1725 param_set = CKP_ML_KEM_1024;
1726 privateKeyLen = WC_ML_KEM_1024_PRIVATE_KEY_SIZE;
1727 break;
1728 default:
1729 ret = NOT_COMPILED_IN;
1730 break;
1731 #else
1732 default:
1733 ret = NOT_COMPILED_IN;
1734 break;
1735 #endif
1736 }
1737 }
1738 if ((ret == 0) &&
1739 ((mechInfo->ulMinKeySize > privateKeyLen) ||
1740 (mechInfo->ulMaxKeySize < privateKeyLen))) {
1741 ret = WC_KEY_SIZE_E;
1742 }
1743 if (ret == 0) {
1744 privateData = (unsigned char*)XMALLOC(privateKeyLen, key->heap,
1745 DYNAMIC_TYPE_TMP_BUFFER);
1746 if (privateData == NULL) {
1747 ret = MEMORY_E;
1748 }
1749 }
1750 if (ret == 0) {
1751 ret = wc_MlKemKey_EncodePrivateKey(key, privateData,
1752 (word32)privateKeyLen);
1753 }
1754 if (ret == 0) {
1755 keyTemplate[3].pValue = privateData;
1756 keyTemplate[3].ulValueLen = privateKeyLen;
1757
1758 PKCS11_DUMP_TEMPLATE("ML-KEM Private Key", keyTemplate, keyTmplCnt);
1759 rv = session->func->C_CreateObject(session->handle, keyTemplate,
1760 keyTmplCnt, privateKey);
1761 PKCS11_RV("C_CreateObject", rv);
1762 if (rv != CKR_OK) {
1763 ret = WC_HW_E;
1764 }
1765 }
1766
1767 if (privateData != NULL) {
1768 ForceZero(privateData, privateKeyLen);
1769 }
1770 XFREE(privateData, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1771
1772 return ret;
1773}
1774#endif /* WOLFSSL_HAVE_MLKEM */
1775
1776#ifdef HAVE_DILITHIUM
1777/**
1778 * Create a PKCS#11 object containing the ML-DSA public key data.
1779 * @param handle [out] Handle to public key object.
1780 * @param session [in] Session object.
1781 * @param key [in] ML-DSA key.
1782 * @param mechInfo [in] Pointer to a filled MECHANISM_INFO object.
1783 * @return WC_HW_E when a PKCS#11 library call fails.
1784 * @return MEMORY_E when a memory allocation fails.
1785 * @return 0 on success.
1786 */
1787static int Pkcs11CreateMldsaPublicKey(CK_OBJECT_HANDLE* handle,
1788 Pkcs11Session* session,
1789 MlDsaKey* key,
1790 CK_MECHANISM_INFO_PTR mechInfo)
1791{
1792 int ret = 0;
1793 CK_RV rv;
1794 CK_ULONG publicKeyLen = 0;
1795 CK_ML_DSA_PARAMETER_SET_TYPE param_set = 0;
1796 /* Empty entries for optional label/ID. */
1797 CK_ATTRIBUTE keyTemplate[] = {
1798 { CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) },
1799 { CKA_KEY_TYPE, &mldsaKeyType, sizeof(mldsaKeyType) },
1800 { CKA_VERIFY, &ckTrue, sizeof(ckTrue) },
1801 { CKA_VALUE, NULL, 0 },
1802 { CKA_PARAMETER_SET, ¶m_set, sizeof(param_set) },
1803 { 0, NULL, 0 },
1804 { 0, NULL, 0 },
1805 };
1806 /* Mandatory entries + 2 optional. */
1807 CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate) - 2;
1808
1809 if (!key->pubKeySet) {
1810 ret = BAD_FUNC_ARG;
1811 }
1812
1813 if (key->labelLen > 0) {
1814 keyTemplate[keyTmplCnt].type = CKA_LABEL;
1815 keyTemplate[keyTmplCnt].pValue = key->label;
1816 keyTemplate[keyTmplCnt].ulValueLen = key->labelLen;
1817 keyTmplCnt++;
1818 }
1819 if (key->idLen > 0) {
1820 keyTemplate[keyTmplCnt].type = CKA_ID;
1821 keyTemplate[keyTmplCnt].pValue = key->id;
1822 keyTemplate[keyTmplCnt].ulValueLen = key->idLen;
1823 keyTmplCnt++;
1824 }
1825
1826 if ((key->level == WC_ML_DSA_44) &&
1827 (mechInfo->ulMinKeySize <= ML_DSA_LEVEL2_PUB_KEY_SIZE) &&
1828 (mechInfo->ulMaxKeySize >= ML_DSA_LEVEL2_PUB_KEY_SIZE)) {
1829 publicKeyLen = ML_DSA_LEVEL2_PUB_KEY_SIZE;
1830 param_set = CKP_ML_DSA_44;
1831 }
1832 else if ((key->level == WC_ML_DSA_65) &&
1833 (mechInfo->ulMinKeySize <= ML_DSA_LEVEL3_PUB_KEY_SIZE) &&
1834 (mechInfo->ulMaxKeySize >= ML_DSA_LEVEL3_PUB_KEY_SIZE)) {
1835 publicKeyLen = ML_DSA_LEVEL3_PUB_KEY_SIZE;
1836 param_set = CKP_ML_DSA_65;
1837 }
1838 else if ((key->level == WC_ML_DSA_87) &&
1839 (mechInfo->ulMinKeySize <= ML_DSA_LEVEL5_PUB_KEY_SIZE) &&
1840 (mechInfo->ulMaxKeySize >= ML_DSA_LEVEL5_PUB_KEY_SIZE)) {
1841 publicKeyLen = ML_DSA_LEVEL5_PUB_KEY_SIZE;
1842 param_set = CKP_ML_DSA_87;
1843 }
1844 else {
1845 ret = WC_KEY_SIZE_E;
1846 }
1847
1848 if (ret == 0) {
1849 keyTemplate[3].pValue = (byte*) key->p;
1850 keyTemplate[3].ulValueLen = publicKeyLen;
1851
1852 PKCS11_DUMP_TEMPLATE("ML-DSA Public Key", keyTemplate, keyTmplCnt);
1853 rv = session->func->C_CreateObject(session->handle, keyTemplate,
1854 keyTmplCnt, handle);
1855 PKCS11_RV("C_CreateObject", rv);
1856 if (rv != CKR_OK) {
1857 ret = WC_HW_E;
1858 }
1859 }
1860
1861 return ret;
1862}
1863
1864/**
1865 * Create a PKCS#11 object containing the ML-DSA private key data.
1866 *
1867 * @param handle [out] Handle to private key object.
1868 * @param session [in] Session object.
1869 * @param key [in] ML-DSA key.
1870 * @param mechInfo [in] Pointer to a filled MECHANISM_INFO object.
1871 * @return WC_HW_E when a PKCS#11 library call fails.
1872 * @return 0 on success.
1873 */
1874static int Pkcs11CreateMldsaPrivateKey(CK_OBJECT_HANDLE* privateKey,
1875 Pkcs11Session* session,
1876 MlDsaKey* key,
1877 CK_MECHANISM_INFO_PTR mechInfo)
1878{
1879 int ret = 0;
1880 CK_RV rv;
1881 CK_ULONG privateKeyLen = 0;
1882 CK_ML_DSA_PARAMETER_SET_TYPE param_set = 0;
1883 /* Empty entries for optional label/ID. */
1884 CK_ATTRIBUTE keyTemplate[] = {
1885 { CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
1886 { CKA_KEY_TYPE, &mldsaKeyType, sizeof(mldsaKeyType) },
1887 { CKA_SIGN, &ckTrue, sizeof(ckTrue) },
1888 { CKA_VALUE, NULL, 0 },
1889 { CKA_PARAMETER_SET, ¶m_set, sizeof(param_set) },
1890 { 0, NULL, 0 },
1891 { 0, NULL, 0 }
1892 };
1893 /* Mandatory entries + 2 optional. */
1894 CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate) - 2;
1895
1896 if (key->labelLen > 0) {
1897 keyTemplate[keyTmplCnt].type = CKA_LABEL;
1898 keyTemplate[keyTmplCnt].pValue = key->label;
1899 keyTemplate[keyTmplCnt].ulValueLen = key->labelLen;
1900 keyTmplCnt++;
1901 }
1902 if (key->idLen > 0) {
1903 keyTemplate[keyTmplCnt].type = CKA_ID;
1904 keyTemplate[keyTmplCnt].pValue = key->id;
1905 keyTemplate[keyTmplCnt].ulValueLen = key->idLen;
1906 keyTmplCnt++;
1907 }
1908
1909 if ((key->level == WC_ML_DSA_44) &&
1910 (mechInfo->ulMinKeySize <= ML_DSA_LEVEL2_PUB_KEY_SIZE) &&
1911 (mechInfo->ulMaxKeySize >= ML_DSA_LEVEL2_PUB_KEY_SIZE)) {
1912 privateKeyLen = ML_DSA_LEVEL2_KEY_SIZE;
1913 param_set = CKP_ML_DSA_44;
1914 }
1915 else if ((key->level == WC_ML_DSA_65) &&
1916 (mechInfo->ulMinKeySize <= ML_DSA_LEVEL3_PUB_KEY_SIZE) &&
1917 (mechInfo->ulMaxKeySize >= ML_DSA_LEVEL3_PUB_KEY_SIZE)) {
1918 privateKeyLen = ML_DSA_LEVEL3_KEY_SIZE;
1919 param_set = CKP_ML_DSA_65;
1920 }
1921 else if ((key->level == WC_ML_DSA_87) &&
1922 (mechInfo->ulMinKeySize <= ML_DSA_LEVEL5_PUB_KEY_SIZE) &&
1923 (mechInfo->ulMaxKeySize >= ML_DSA_LEVEL5_PUB_KEY_SIZE)) {
1924 privateKeyLen = ML_DSA_LEVEL5_KEY_SIZE;
1925 param_set = CKP_ML_DSA_87;
1926 }
1927 else {
1928 ret = WC_KEY_SIZE_E;
1929 }
1930
1931 if (ret == 0) {
1932 keyTemplate[3].pValue = (byte*) key->k;
1933 keyTemplate[3].ulValueLen = privateKeyLen;
1934
1935 PKCS11_DUMP_TEMPLATE("ML-DSA Private Key", keyTemplate, keyTmplCnt);
1936 rv = session->func->C_CreateObject(session->handle, keyTemplate,
1937 keyTmplCnt, privateKey);
1938 PKCS11_RV("C_CreateObject", rv);
1939 if (rv != CKR_OK) {
1940 ret = WC_HW_E;
1941 }
1942 }
1943
1944 return ret;
1945}
1946#endif /* HAVE_DILITHIUM */
1947
1948#if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \
1949 (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || \
1950 !defined(NO_HMAC) || defined(HAVE_DILITHIUM) || \
1951 defined(WOLFSSL_HAVE_MLKEM)
1952/**
1953 * Check if mechanism is available in session on token.
1954 *
1955 * @param [in] session Session object.
1956 * @param [in] mech Mechanism to look for.
1957 * @param [out] mechInfoPtr Mechanism info return data (optional).
1958 * @return NOT_COMPILED_IN when mechanism not available.
1959 * @return 0 when mechanism is available.
1960 */
1961static int Pkcs11MechAvail(Pkcs11Session* session, CK_MECHANISM_TYPE mech,
1962 CK_MECHANISM_INFO_PTR mechInfoPtr)
1963{
1964 int ret = 0;
1965 CK_RV rv;
1966 CK_MECHANISM_INFO mechInfo;
1967
1968 PKCS11_DUMP_MECHANSIM("PKCS#11: Check if mechanism is available", mech);
1969 rv = session->func->C_GetMechanismInfo(session->slotId, mech, &mechInfo);
1970 PKCS11_RV("C_GetMechanismInfo", rv);
1971 if (rv != CKR_OK) {
1972 ret = NOT_COMPILED_IN;
1973 }
1974 if (mechInfoPtr != NULL) {
1975 *mechInfoPtr = mechInfo;
1976 }
1977
1978 return ret;
1979}
1980#endif
1981
1982#ifndef NO_HMAC
1983/**
1984 * Return the mechanism type and key type for the digest type when using HMAC.
1985 *
1986 * @param [in] macType Digest type - e.g. WC_SHA256.
1987 * @param [in] mechType Mechanism type - e.g. CKM_SHA256_HMAC.
1988 * @param [in] keyType Key type - e.g. CKK_SHA256_HMAC.
1989 * @return NOT_COMPILED_IN if the digest algorithm isn't recognised.
1990 * @return 0 otherwise.
1991 */
1992static int Pkcs11HmacTypes(int macType, int* mechType, int* keyType)
1993{
1994 int ret = 0;
1995
1996 switch (macType)
1997 {
1998 #ifndef NO_MD5
1999 case WC_MD5:
2000 *mechType = CKM_MD5_HMAC;
2001 *keyType = CKK_MD5_HMAC;
2002 break;
2003 #endif
2004 #ifndef NO_SHA
2005 case WC_SHA:
2006 *mechType = CKM_SHA_1_HMAC;
2007 *keyType = CKK_SHA_1_HMAC;
2008 break;
2009 #endif
2010 #ifdef WOLFSSL_SHA224
2011 case WC_SHA224:
2012 *mechType = CKM_SHA224_HMAC;
2013 *keyType = CKK_SHA224_HMAC;
2014 break;
2015 #endif
2016 #ifndef NO_SHA256
2017 case WC_SHA256:
2018 *mechType = CKM_SHA256_HMAC;
2019 *keyType = CKK_SHA256_HMAC;
2020 break;
2021 #endif
2022 #ifdef WOLFSSL_SHA384
2023 case WC_SHA384:
2024 *mechType = CKM_SHA384_HMAC;
2025 *keyType = CKK_SHA384_HMAC;
2026 break;
2027 #endif
2028 #ifdef WOLFSSL_SHA512
2029 case WC_SHA512:
2030 *mechType = CKM_SHA512_HMAC;
2031 *keyType = CKK_SHA512_HMAC;
2032 break;
2033 #endif
2034 default:
2035 ret = NOT_COMPILED_IN;
2036 break;
2037 }
2038
2039 return ret;
2040}
2041#endif
2042
2043/**
2044 * Store the private key on the token in the session.
2045 *
2046 * @param [in] token Token to store private key on.
2047 * @param [in] type Key type.
2048 * @param [in] clear Clear out the private data from software key.
2049 * @param [in] key Key type specific object.
2050 * @return NOT_COMPILED_IN when mechanism not available.
2051 * @return 0 on success.
2052 */
2053int wc_Pkcs11StoreKey(Pkcs11Token* token, int type, int clear, void* key)
2054{
2055 int ret = 0;
2056 Pkcs11Session session;
2057 CK_OBJECT_HANDLE privKey = NULL_PTR;
2058
2059 ret = Pkcs11OpenSession(token, &session, 1);
2060 if (ret == 0) {
2061 switch (type) {
2062 #if !defined(NO_AES) && defined(HAVE_AESGCM)
2063 case PKCS11_KEY_TYPE_AES_GCM: {
2064 Aes* aes = (Aes*)key;
2065
2066 ret = Pkcs11MechAvail(&session, CKM_AES_GCM, NULL);
2067 if (ret == 0) {
2068 ret = Pkcs11CreateSecretKey(&privKey, &session, CKK_AES,
2069 (unsigned char*)aes->devKey,
2070 aes->keylen,
2071 (unsigned char*)aes->id,
2072 aes->idLen, aes->label,
2073 aes->labelLen, CKA_ENCRYPT);
2074 }
2075 if (ret == 0 && clear)
2076 ForceZero(aes->devKey, aes->keylen);
2077 break;
2078 }
2079 #endif
2080 #if !defined(NO_AES) && defined(HAVE_AES_CBC)
2081 case PKCS11_KEY_TYPE_AES_CBC: {
2082 Aes* aes = (Aes*)key;
2083
2084 ret = Pkcs11MechAvail(&session, CKM_AES_CBC, NULL);
2085 if (ret == 0) {
2086 ret = Pkcs11CreateSecretKey(&privKey, &session, CKK_AES,
2087 (unsigned char*)aes->devKey,
2088 aes->keylen,
2089 (unsigned char*)aes->id,
2090 aes->idLen, aes->label,
2091 aes->labelLen, CKA_ENCRYPT);
2092 }
2093 if (ret == 0 && clear)
2094 ForceZero(aes->devKey, aes->keylen);
2095 break;
2096 }
2097 #endif
2098 #ifndef NO_HMAC
2099 case PKCS11_KEY_TYPE_HMAC: {
2100 Hmac* hmac = (Hmac*)key;
2101 int mechType;
2102 int keyType;
2103
2104 ret = Pkcs11HmacTypes(hmac->macType, &mechType, &keyType);
2105 if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN))
2106 break;
2107
2108 if (ret == 0)
2109 ret = Pkcs11MechAvail(&session, mechType, NULL);
2110 if (ret == 0) {
2111 ret = Pkcs11CreateSecretKey(&privKey, &session, keyType,
2112 (unsigned char*)hmac->keyRaw,
2113 hmac->keyLen,
2114 (unsigned char*)hmac->id,
2115 hmac->idLen, hmac->label,
2116 hmac->labelLen, CKA_SIGN);
2117 if (ret == WC_NO_ERR_TRACE(WC_HW_E)) {
2118 ret = Pkcs11CreateSecretKey(&privKey, &session,
2119 CKK_GENERIC_SECRET,
2120 (unsigned char*)hmac->keyRaw,
2121 hmac->keyLen,
2122 (unsigned char*)hmac->id,
2123 hmac->idLen, hmac->label,
2124 hmac->labelLen, CKA_SIGN);
2125 }
2126 }
2127 break;
2128 }
2129 #endif
2130 #if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
2131 case PKCS11_KEY_TYPE_RSA: {
2132 RsaKey* rsaKey = (RsaKey*)key;
2133
2134 ret = Pkcs11MechAvail(&session, CKM_RSA_X_509, NULL);
2135 if (ret == 0)
2136 ret = Pkcs11CreateRsaPrivateKey(&privKey, &session, rsaKey,
2137 1);
2138 if (ret == 0 && clear) {
2139 mp_forcezero(&rsaKey->u);
2140 mp_forcezero(&rsaKey->dQ);
2141 mp_forcezero(&rsaKey->dP);
2142 mp_forcezero(&rsaKey->q);
2143 mp_forcezero(&rsaKey->p);
2144 mp_forcezero(&rsaKey->d);
2145 }
2146 break;
2147 }
2148 #endif
2149 #ifdef HAVE_ECC
2150 case PKCS11_KEY_TYPE_EC: {
2151 ecc_key* eccKey = (ecc_key*)key;
2152 int ret2 = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
2153
2154 #ifndef NO_PKCS11_ECDH
2155 if ((eccKey->flags & WC_ECC_FLAG_DEC_SIGN) == 0) {
2156 /* Try ECDH mechanism first. */
2157 ret = Pkcs11MechAvail(&session, CKM_ECDH1_DERIVE, NULL);
2158 if (ret == 0) {
2159 ret = Pkcs11CreateEccPrivateKey(&privKey, &session,
2160 eccKey, CKA_DERIVE);
2161 }
2162 }
2163 #endif
2164 if (ret == 0 || ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) {
2165 /* Try ECDSA mechanism next. */
2166 ret2 = Pkcs11MechAvail(&session, CKM_ECDSA, NULL);
2167 if (ret2 == 0) {
2168 ret2 = Pkcs11CreateEccPrivateKey(&privKey, &session,
2169 eccKey, CKA_SIGN);
2170 if (ret2 == 0) {
2171 CK_OBJECT_HANDLE pubKey = NULL_PTR;
2172 /* Store public key for validation with cert. */
2173 ret2 = Pkcs11CreateEccPublicKey(&pubKey, &session,
2174 eccKey, CKA_VERIFY);
2175 if (ret2 != 0) {
2176 /* Delete the private key if the public key
2177 * creation failed to avoid leaving an orphaned
2178 * private key on the token. */
2179 session.func->C_DestroyObject(session.handle,
2180 privKey);
2181 }
2182 }
2183 }
2184 /* OK for this to fail if set for ECDH. */
2185 if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN))
2186 ret = ret2;
2187 }
2188 if (ret == 0 && clear)
2189 mp_forcezero(wc_ecc_key_get_priv(eccKey));
2190 break;
2191 }
2192 #endif
2193 #ifdef WOLFSSL_HAVE_MLKEM
2194 case PKCS11_KEY_TYPE_MLKEM: {
2195 MlKemKey* mlkemKey = (MlKemKey*)key;
2196 CK_MECHANISM_INFO mechInfo;
2197
2198 ret = Pkcs11MechAvail(&session, CKM_ML_KEM, &mechInfo);
2199 if (ret == 0 && ((mlkemKey->flags & MLKEM_FLAG_PRIV_SET) != 0)) {
2200 ret = Pkcs11CreateMlKemPrivateKey(&privKey, &session,
2201 mlkemKey, &mechInfo);
2202 }
2203 if (ret == 0 && ((mlkemKey->flags & MLKEM_FLAG_PUB_SET) != 0)) {
2204 CK_OBJECT_HANDLE pubKey = NULL_PTR;
2205 /* Store public key for validation with private key. */
2206 ret = Pkcs11CreateMlKemPublicKey(&pubKey, &session,
2207 mlkemKey, &mechInfo);
2208 if (ret != 0 && privKey != NULL_PTR) {
2209 /* Delete the private key if the public key
2210 * creation failed to avoid leaving an orphaned
2211 * private key on the token. */
2212 session.func->C_DestroyObject(session.handle, privKey);
2213 }
2214 }
2215 if (ret == 0 && clear &&
2216 ((mlkemKey->flags & MLKEM_FLAG_PRIV_SET) != 0)) {
2217 ForceZero(mlkemKey->priv, sizeof(mlkemKey->priv));
2218 ForceZero(mlkemKey->z, sizeof(mlkemKey->z));
2219 }
2220 break;
2221 }
2222 #endif /* WOLFSSL_HAVE_MLKEM */
2223 #if defined(HAVE_DILITHIUM)
2224 case PKCS11_KEY_TYPE_MLDSA: {
2225 MlDsaKey* mldsaKey = (MlDsaKey*) key;
2226 CK_MECHANISM_INFO mechInfo;
2227
2228 ret = Pkcs11MechAvail(&session, CKM_ML_DSA, &mechInfo);
2229 if (ret == 0 && mldsaKey->prvKeySet) {
2230 ret = Pkcs11CreateMldsaPrivateKey(&privKey,
2231 &session,
2232 mldsaKey,
2233 &mechInfo);
2234 }
2235 if (ret == 0 && mldsaKey->pubKeySet) {
2236 CK_OBJECT_HANDLE pubKey = NULL_PTR;
2237 /* Store public key for validation with cert. */
2238 ret = Pkcs11CreateMldsaPublicKey(&pubKey,
2239 &session,
2240 mldsaKey,
2241 &mechInfo);
2242 if (ret != 0) {
2243 /* Delete the private key if the public key creation
2244 * failed to avoid leaving an orphaned private key
2245 * on the token. */
2246 session.func->C_DestroyObject(session.handle, privKey);
2247 }
2248 }
2249 #if !defined(WOLFSSL_DILITHIUM_ASSIGN_KEY) && \
2250 !defined(WOLFSSL_DILITHIUM_DYNAMIC_KEYS)
2251 if (ret == 0 && clear) {
2252 ForceZero(mldsaKey->k, sizeof(mldsaKey->k));
2253 }
2254 #elif defined(WOLFSSL_DILITHIUM_DYNAMIC_KEYS)
2255 if (ret == 0 && clear && mldsaKey->k != NULL) {
2256 ForceZero(mldsaKey->k, mldsaKey->kSz);
2257 }
2258 #endif
2259 break;
2260 }
2261 #endif /* HAVE_DILITHIUM*/
2262 default:
2263 ret = NOT_COMPILED_IN;
2264 break;
2265 }
2266
2267 Pkcs11CloseSession(token, &session);
2268 }
2269
2270 (void)privKey;
2271 (void)clear;
2272 (void)key;
2273
2274 return ret;
2275}
2276
2277#if !defined(NO_RSA) || defined(HAVE_ECC) || (!defined(NO_AES) && \
2278 (defined(HAVE_AESGCM) || defined(HAVE_AES_CBC))) || \
2279 !defined(NO_HMAC) || !defined(NO_CERTS)
2280
2281/**
2282 * Find the PKCS#11 object containing key data using template.
2283 *
2284 * @param [out] key Handle to key object.
2285 * @param [in] session Session object.
2286 * @param [in] keyTemplate PKCS #11 template to use in search.
2287 * @param [in] keyTmplCnt Count of entries in PKCS #11 template.
2288 * @param [out] count Number of keys matching template.
2289 * @return WC_HW_E when a PKCS#11 library call fails.
2290 * @return 0 on success.
2291 */
2292static int Pkcs11FindKeyByTemplate(CK_OBJECT_HANDLE* key,
2293 Pkcs11Session* session,
2294 CK_ATTRIBUTE *keyTemplate,
2295 CK_ULONG keyTmplCnt,
2296 CK_ULONG *count)
2297{
2298 int ret = 0;
2299 CK_RV rv;
2300
2301 WOLFSSL_MSG("PKCS#11: Find Key By Template");
2302
2303 PKCS11_DUMP_TEMPLATE("Find Key", keyTemplate, keyTmplCnt);
2304 rv = session->func->C_FindObjectsInit(session->handle, keyTemplate,
2305 keyTmplCnt);
2306 PKCS11_RV("C_FindObjectsInit", rv);
2307 if (rv != CKR_OK) {
2308 ret = WC_HW_E;
2309 }
2310 if (ret == 0) {
2311 rv = session->func->C_FindObjects(session->handle, key, 1, count);
2312 PKCS11_RV("C_FindObjects", rv);
2313 PKCS11_VAL("C_FindObjects Count", *count);
2314 if (rv != CKR_OK) {
2315 ret = WC_HW_E;
2316 }
2317 rv = session->func->C_FindObjectsFinal(session->handle);
2318 PKCS11_RV("C_FindObjectsFinal", rv);
2319 if (rv != CKR_OK) {
2320 ret = WC_HW_E;
2321 }
2322 }
2323 return ret;
2324}
2325
2326/**
2327 * Find the PKCS#11 object containing the private key data by label.
2328 *
2329 * @param [out] key Handle to key object.
2330 * @param [in] keyClass Public or private key class.
2331 * @param [in] keyType Type of key.
2332 * @param [in] session Session object.
2333 * @param [in] id Identifier set against a key.
2334 * @param [in] idLen Length of identifier.
2335 * @return WC_HW_E when a PKCS#11 library call fails.
2336 * @return 0 on success.
2337 */
2338static int Pkcs11FindKeyByLabel(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass,
2339 CK_KEY_TYPE keyType, Pkcs11Session* session,
2340 char* label, int labelLen)
2341{
2342 int ret = 0;
2343 CK_ULONG count;
2344 CK_ATTRIBUTE keyTemplate[] = {
2345 { CKA_CLASS, &keyClass, sizeof(keyClass) },
2346 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2347 { CKA_LABEL, label, (CK_ULONG)labelLen }
2348 };
2349 CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);
2350
2351 WOLFSSL_MSG("PKCS#11: Find Key By Label");
2352
2353 ret = Pkcs11FindKeyByTemplate(key, session, keyTemplate, keyTmplCnt,
2354 &count);
2355 if (ret == 0 && count == 0)
2356 ret = WC_HW_E;
2357
2358 return ret;
2359}
2360
2361/**
2362 * Find the PKCS#11 object containing the private key data by ID.
2363 *
2364 * @param [out] key Handle to key object.
2365 * @param [in] keyClass Public or private key class.
2366 * @param [in] keyType Type of key.
2367 * @param [in] session Session object.
2368 * @param [in] id Identifier set against a key.
2369 * @param [in] idLen Length of identifier.
2370 * @return WC_HW_E when a PKCS#11 library call fails.
2371 * @return 0 on success.
2372 */
2373static int Pkcs11FindKeyById(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass,
2374 CK_KEY_TYPE keyType, Pkcs11Session* session,
2375 byte* id, int idLen)
2376{
2377 int ret = 0;
2378 CK_ULONG count;
2379 CK_ATTRIBUTE keyTemplate[] = {
2380#ifndef WC_PKCS11_FIND_WITH_ID_ONLY
2381 { CKA_CLASS, &keyClass, sizeof(keyClass) },
2382 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
2383#endif
2384 { CKA_ID, id, (CK_ULONG)idLen }
2385 };
2386 CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);
2387
2388 WOLFSSL_MSG("PKCS#11: Find Key By Id");
2389
2390 ret = Pkcs11FindKeyByTemplate(key, session, keyTemplate, keyTmplCnt,
2391 &count);
2392 if (ret == 0 && count == 0)
2393 ret = WC_HW_E;
2394
2395 return ret;
2396}
2397#endif
2398
2399#ifndef NO_RSA
2400/**
2401 * Find the PKCS#11 object containing the RSA public or private key data with
2402 * the modulus specified.
2403 *
2404 * @param [out] key Handle to key object.
2405 * @param [in] keyClass Public or private key class.
2406 * @param [in] session Session object.
2407 * @param [in] rsaKey RSA key with modulus to search on.
2408 * @return WC_HW_E when a PKCS#11 library call fails.
2409 * @return 0 on success.
2410 */
2411static int Pkcs11FindRsaKey(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass,
2412 Pkcs11Session* session, RsaKey* rsaKey)
2413{
2414 CK_ULONG count;
2415 CK_ATTRIBUTE keyTemplate[] = {
2416 { CKA_CLASS, &keyClass, sizeof(keyClass) },
2417 { CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) },
2418 { CKA_MODULUS, NULL, 0 },
2419 };
2420 CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);
2421
2422 /* Set the modulus. */
2423 keyTemplate[2].pValue = rsaKey->n.raw.buf;
2424 keyTemplate[2].ulValueLen = rsaKey->n.raw.len;
2425
2426 return Pkcs11FindKeyByTemplate(key, session, keyTemplate, keyTmplCnt,
2427 &count);
2428}
2429
2430/**
2431 * Make a handle to a public RSA key.
2432 *
2433 * @param [in] session Session object.
2434 * @param [in] rsaKey RSA key with modulus to search on.
2435 * @param [in] sessionKey Whether to create a session key.
2436 * @param [out] publicKey Handle to public key object.
2437 */
2438static int Pkcs11RsaPublicKey(Pkcs11Session* session, RsaKey* rsaKey,
2439 int sessionKey, CK_OBJECT_HANDLE* publicKey)
2440{
2441 int ret = 0;
2442 CK_RV rv;
2443 CK_ATTRIBUTE keyTemplate[] = {
2444 { CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) },
2445 { CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) },
2446 { CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) },
2447 { CKA_MODULUS, NULL, 0 },
2448 { CKA_PUBLIC_EXPONENT, NULL, 0 }
2449 };
2450 CK_ULONG keyTmplCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);
2451
2452 if (sessionKey) {
2453 /* Set the modulus and public exponent data. */
2454 keyTemplate[3].pValue = rsaKey->n.raw.buf;
2455 keyTemplate[3].ulValueLen = rsaKey->n.raw.len;
2456 keyTemplate[4].pValue = rsaKey->e.raw.buf;
2457 keyTemplate[4].ulValueLen = rsaKey->e.raw.len;
2458
2459 PKCS11_DUMP_TEMPLATE("RSA Public Key", keyTemplate, keyTmplCnt);
2460 /* Create an object containing public key data for device to use. */
2461 rv = session->func->C_CreateObject(session->handle, keyTemplate,
2462 keyTmplCnt, publicKey);
2463 PKCS11_RV("C_CreateObject", rv);
2464 if (rv != CKR_OK) {
2465 ret = WC_HW_E;
2466 }
2467 }
2468 else if (rsaKey->labelLen > 0) {
2469 ret = Pkcs11FindKeyByLabel(publicKey, CKO_PUBLIC_KEY, CKK_RSA,
2470 session, rsaKey->label, rsaKey->labelLen);
2471 }
2472 else {
2473 ret = Pkcs11FindKeyById(publicKey, CKO_PUBLIC_KEY, CKK_RSA,
2474 session, rsaKey->id, rsaKey->idLen);
2475 }
2476
2477 return ret;
2478}
2479
2480/**
2481 * Get the RSA public key data from the PKCS#11 object.
2482 *
2483 * @param [in] key RSA key to put the data into.
2484 * @param [in] session Session object.
2485 * @param [in] pubkey Public key object.
2486 * @return WC_HW_E when a PKCS#11 library call fails.
2487 * @return MEMORY_E when a memory allocation fails.
2488 * @return 0 on success.
2489 */
2490static int Pkcs11GetRsaPublicKey(RsaKey* key, Pkcs11Session* session,
2491 CK_OBJECT_HANDLE pubKey)
2492{
2493 int ret = 0;
2494 unsigned char* mod = NULL;
2495 unsigned char* exp = NULL;
2496 int modSz, expSz;
2497 CK_ATTRIBUTE tmpl[] = {
2498 { CKA_MODULUS, NULL_PTR, 0 },
2499 { CKA_PUBLIC_EXPONENT, NULL_PTR, 0 }
2500 };
2501 CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
2502 CK_RV rv;
2503
2504 PKCS11_DUMP_TEMPLATE("Get RSA Public Key Length", tmpl, tmplCnt);
2505 rv = session->func->C_GetAttributeValue(session->handle, pubKey, tmpl,
2506 tmplCnt);
2507 PKCS11_RV("C_GetAttributeValue", rv);
2508 if (rv != CKR_OK) {
2509 ret = WC_HW_E;
2510 }
2511 PKCS11_DUMP_TEMPLATE("RSA Public Key Length", tmpl, tmplCnt);
2512
2513 if (ret == 0) {
2514 modSz = (int)tmpl[0].ulValueLen;
2515 expSz = (int)tmpl[1].ulValueLen;
2516 mod = (unsigned char*)XMALLOC(modSz, key->heap,
2517 DYNAMIC_TYPE_TMP_BUFFER);
2518 if (mod == NULL)
2519 ret = MEMORY_E;
2520 }
2521 if (ret == 0) {
2522 exp = (unsigned char*)XMALLOC(expSz, key->heap,
2523 DYNAMIC_TYPE_TMP_BUFFER);
2524 if (exp == NULL)
2525 ret = MEMORY_E;
2526 }
2527 if (ret == 0) {
2528 tmpl[0].pValue = mod;
2529 tmpl[1].pValue = exp;
2530
2531 PKCS11_DUMP_TEMPLATE("Get RSA Public Key", tmpl, tmplCnt);
2532 rv = session->func->C_GetAttributeValue(session->handle, pubKey,
2533 tmpl, tmplCnt);
2534 PKCS11_RV("C_GetAttributeValue", rv);
2535 if (rv != CKR_OK) {
2536 ret = WC_HW_E;
2537 }
2538 PKCS11_DUMP_TEMPLATE("RSA Public Key", tmpl, tmplCnt);
2539 }
2540 if (ret == 0)
2541 ret = wc_RsaPublicKeyDecodeRaw(mod, modSz, exp, expSz, key);
2542
2543 XFREE(exp, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
2544 XFREE(mod, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
2545
2546 return ret;
2547}
2548
2549/**
2550 * Get the RSA modulus size in bytes from the PKCS#11 object.
2551 *
2552 * @param [in] session Session object.
2553 * @param [in] pubkey Public key object.
2554 * @param [out] modSize Size of the modulus in bytes.
2555 * @return WC_HW_E when a PKCS#11 library call fails.
2556 * @return MEMORY_E when a memory allocation fails.
2557 * @return 0 on success.
2558 */
2559static int Pkcs11GetRsaModulusSize(Pkcs11Session* session,
2560 CK_OBJECT_HANDLE pubKey, int* modSize)
2561{
2562 int ret = 0;
2563 CK_ATTRIBUTE tmpl[] = {
2564 { CKA_MODULUS, NULL_PTR, 0 }
2565 };
2566 CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
2567 CK_RV rv;
2568
2569 PKCS11_DUMP_TEMPLATE("Get RSA Modulus Length", tmpl, tmplCnt);
2570 rv = session->func->C_GetAttributeValue(session->handle, pubKey, tmpl,
2571 tmplCnt);
2572 PKCS11_RV("C_GetAttributeValue", rv);
2573 if (rv != CKR_OK) {
2574 ret = WC_HW_E;
2575 }
2576 PKCS11_DUMP_TEMPLATE("RSA Modulus Length", tmpl, tmplCnt);
2577
2578 if (ret == 0) {
2579 *modSize = (int)tmpl[0].ulValueLen;
2580 }
2581
2582 return ret;
2583}
2584
2585/**
2586 * Make a handle to a private RSA key.
2587 *
2588 * @param [in] session Session object.
2589 * @param [in] rsaKey RSA key with modulus to search on.
2590 * @param [in] sessionKey Whether to create a session key.
2591 * @param [out] publicKey Handle to private key object.
2592 */
2593static int Pkcs11RsaPrivateKey(Pkcs11Session* session, RsaKey* rsaKey,
2594 int sessionKey, CK_OBJECT_HANDLE* privateKey)
2595{
2596 int ret;
2597
2598 if (sessionKey) {
2599 #ifdef WOLFSSL_KEY_GEN
2600 ret = Pkcs11CreateRsaPrivateKey(privateKey, session, rsaKey, 0);
2601 #else
2602 /* RSA Key Generation support not compiled in */
2603 ret = NOT_COMPILED_IN;
2604 #endif
2605 }
2606 else if (rsaKey->labelLen > 0) {
2607 ret = Pkcs11FindKeyByLabel(privateKey, CKO_PRIVATE_KEY, CKK_RSA,
2608 session, rsaKey->label, rsaKey->labelLen);
2609 }
2610 else if (rsaKey->idLen > 0) {
2611 ret = Pkcs11FindKeyById(privateKey, CKO_PRIVATE_KEY, CKK_RSA, session,
2612 rsaKey->id, rsaKey->idLen);
2613 }
2614 else {
2615 ret = Pkcs11FindRsaKey(privateKey, CKO_PRIVATE_KEY, session, rsaKey);
2616 }
2617
2618 if ((ret == 0) && (!sessionKey)) {
2619 ret = Pkcs11GetRsaPublicKey(rsaKey, session, *privateKey);
2620 }
2621
2622 return ret;
2623}
2624
2625/**
2626 * Get the hash length associated with the WolfCrypt hash type.
2627 *
2628 * @param [in] hType Hash Type.
2629 * @return -1 if hash type not recognized.
2630 * @return hash length on success.
2631 */
2632int wc_hash2sz(int hType)
2633{
2634 switch(hType) {
2635 case WC_HASH_TYPE_SHA:
2636 return 20;
2637 case WC_HASH_TYPE_SHA224:
2638 return 28;
2639 case WC_HASH_TYPE_SHA256:
2640 return 32;
2641 case WC_HASH_TYPE_SHA384:
2642 return 48;
2643 case WC_HASH_TYPE_SHA512:
2644 return 64;
2645 default:
2646 /* unsupported WC_HASH_TYPE_XXXX */
2647 return -1;
2648 }
2649}
2650
2651/**
2652 * Get PKCS11 hash mechanism associated with the WolfCrypt hash type.
2653 *
2654 * @param [in] hType Hash Type.
2655 * @return 0 if hash type not recognized.
2656 * @return PKCS11 mechanism on success.
2657 */
2658CK_MECHANISM_TYPE wc_hash2ckm(int hType)
2659{
2660 switch(hType) {
2661 case WC_HASH_TYPE_SHA:
2662 return CKM_SHA_1;
2663 case WC_HASH_TYPE_SHA224:
2664 return CKM_SHA224;
2665 case WC_HASH_TYPE_SHA256:
2666 return CKM_SHA256;
2667 case WC_HASH_TYPE_SHA384:
2668 return CKM_SHA384;
2669 case WC_HASH_TYPE_SHA512:
2670 return CKM_SHA512;
2671 default:
2672 /* unsupported WC_HASH_TYPE_XXXX */
2673 return 0UL;
2674 }
2675}
2676
2677/**
2678 * Get PKCS11 MGF hash mechanism associated with the WolfCrypt MGF hash type.
2679 *
2680 * @param [in] mgf MGF Type.
2681 * @return 0 if MGF type not recognized.
2682 * @return PKCS11 MGF hash mechanism on success.
2683 */
2684CK_MECHANISM_TYPE wc_mgf2ckm(int mgf)
2685{
2686 switch(mgf) {
2687 case WC_MGF1SHA1:
2688 return CKG_MGF1_SHA1;
2689 case WC_MGF1SHA224:
2690 return CKG_MGF1_SHA224;
2691 case WC_MGF1SHA256:
2692 return CKG_MGF1_SHA256;
2693 case WC_MGF1SHA384:
2694 return CKG_MGF1_SHA384;
2695 case WC_MGF1SHA512:
2696 return CKG_MGF1_SHA512;
2697 default:
2698 /* unsupported WC_MGF1XXXX */
2699 return 0x0UL;
2700 }
2701}
2702
2703/**
2704 * Exponentiate the input with the public part of the RSA key.
2705 * Used in public encrypt and decrypt.
2706 *
2707 * @param [in] session Session object.
2708 * @param [in] info Cryptographic operation data.
2709 * @return WC_HW_E when a PKCS#11 library call fails.
2710 * 0 on success.
2711 */
2712static int Pkcs11RsaEncrypt(Pkcs11Session* session, wc_CryptoInfo* info,
2713 CK_OBJECT_HANDLE key)
2714{
2715 int ret = 0;
2716 CK_MECHANISM_TYPE mechanism = 0x0UL;
2717 CK_RV rv;
2718 CK_MECHANISM mech;
2719 CK_ULONG outLen;
2720#ifdef WOLF_CRYPTO_CB_RSA_PAD
2721 CK_RSA_PKCS_OAEP_PARAMS oaepParams;
2722#endif
2723
2724 WOLFSSL_MSG("PKCS#11: RSA Public Key Operation");
2725
2726 if (info->pk.rsa.outLen == NULL) {
2727 ret = BAD_FUNC_ARG;
2728 }
2729
2730 switch(info->pk.type) {
2731#ifdef WOLF_CRYPTO_CB_RSA_PAD
2732 case WC_PK_TYPE_RSA_PKCS:
2733 mechanism = CKM_RSA_PKCS;
2734 break;
2735 case WC_PK_TYPE_RSA_OAEP:
2736 mechanism = CKM_RSA_PKCS_OAEP;
2737 break;
2738#endif
2739 case WC_PK_TYPE_RSA:
2740 mechanism = CKM_RSA_X_509;
2741 break;
2742 }
2743
2744 if (ret == 0) {
2745 /* Raw RSA encrypt/decrypt operation. */
2746 mech.mechanism = mechanism;
2747 mech.ulParameterLen = 0;
2748 mech.pParameter = NULL;
2749
2750#ifdef WOLF_CRYPTO_CB_RSA_PAD
2751 if (mechanism == CKM_RSA_PKCS_OAEP) {
2752 XMEMSET(&oaepParams, 0, sizeof(oaepParams));
2753 mech.ulParameterLen = sizeof(CK_RSA_PKCS_OAEP_PARAMS);
2754 mech.pParameter = &oaepParams;
2755 oaepParams.source = CKZ_DATA_SPECIFIED;
2756 oaepParams.hashAlg = wc_hash2ckm(info->pk.rsa.padding->hash);
2757 oaepParams.mgf = wc_mgf2ckm(info->pk.rsa.padding->mgf);
2758 }
2759#endif
2760
2761 rv = session->func->C_EncryptInit(session->handle, &mech, key);
2762 PKCS11_RV("C_EncryptInit", rv);
2763 if (rv != CKR_OK) {
2764 ret = WC_HW_E;
2765 }
2766 }
2767 if (ret == 0) {
2768 outLen = (CK_ULONG)*info->pk.rsa.outLen;
2769 rv = session->func->C_Encrypt(session->handle,
2770 (CK_BYTE_PTR)info->pk.rsa.in, info->pk.rsa.inLen,
2771 info->pk.rsa.out, &outLen);
2772 PKCS11_RV("C_Encrypt", rv);
2773 if (rv != CKR_OK) {
2774 ret = WC_HW_E;
2775 }
2776 }
2777 if (ret == 0) {
2778 *info->pk.rsa.outLen = (word32)outLen;
2779 }
2780
2781 return ret;
2782}
2783
2784/**
2785 * Exponentiate the input with the private part of the RSA key.
2786 * Used in private encrypt and decrypt.
2787 *
2788 * @param [in] session Session object.
2789 * @param [in] info Cryptographic operation data.
2790 * @param [in] func Function to perform - decrypt or sign.
2791 * @return WC_HW_E when a PKCS#11 library call fails.
2792 * @return 0 on success.
2793 */
2794static int Pkcs11RsaDecrypt(Pkcs11Session* session, wc_CryptoInfo* info,
2795 CK_OBJECT_HANDLE key)
2796{
2797 int ret = 0;
2798 CK_MECHANISM_TYPE mechanism = 0x0UL;
2799 CK_RV rv;
2800 CK_MECHANISM mech;
2801 CK_ULONG outLen;
2802#ifdef WOLF_CRYPTO_CB_RSA_PAD
2803 CK_RSA_PKCS_OAEP_PARAMS oaepParams;
2804#endif
2805
2806 WOLFSSL_MSG("PKCS#11: RSA Private Key Operation");
2807
2808 if (info->pk.rsa.outLen == NULL) {
2809 ret = BAD_FUNC_ARG;
2810 }
2811
2812 switch(info->pk.type) {
2813#ifdef WOLF_CRYPTO_CB_RSA_PAD
2814 case WC_PK_TYPE_RSA_PKCS:
2815 mechanism = CKM_RSA_PKCS;
2816 break;
2817 case WC_PK_TYPE_RSA_OAEP:
2818 mechanism = CKM_RSA_PKCS_OAEP;
2819 break;
2820#endif
2821 case WC_PK_TYPE_RSA:
2822 mechanism = CKM_RSA_X_509;
2823 break;
2824 }
2825
2826 if (ret == 0) {
2827 /* Raw RSA encrypt/decrypt operation. */
2828 mech.mechanism = mechanism;
2829 mech.ulParameterLen = 0;
2830 mech.pParameter = NULL;
2831
2832#ifdef WOLF_CRYPTO_CB_RSA_PAD
2833 if (mechanism == CKM_RSA_PKCS_OAEP) {
2834 XMEMSET(&oaepParams, 0, sizeof(oaepParams));
2835 mech.ulParameterLen = sizeof(CK_RSA_PKCS_OAEP_PARAMS);
2836 mech.pParameter = &oaepParams;
2837 oaepParams.source = CKZ_DATA_SPECIFIED;
2838 oaepParams.hashAlg = wc_hash2ckm(info->pk.rsa.padding->hash);
2839 oaepParams.mgf = wc_mgf2ckm(info->pk.rsa.padding->mgf);
2840 }
2841#endif
2842
2843 rv = session->func->C_DecryptInit(session->handle, &mech, key);
2844 PKCS11_RV("C_DecryptInit", rv);
2845 if (rv != CKR_OK) {
2846 ret = WC_HW_E;
2847 }
2848 }
2849 if (ret == 0) {
2850 PKCS11_VAL("C_Decrypt inLen", info->pk.rsa.inLen);
2851 PKCS11_VAL("C_Decrypt outLen", *info->pk.rsa.outLen);
2852 outLen = (CK_ULONG)*info->pk.rsa.outLen;
2853 rv = session->func->C_Decrypt(session->handle,
2854 (CK_BYTE_PTR)info->pk.rsa.in, info->pk.rsa.inLen,
2855 info->pk.rsa.out, &outLen);
2856 PKCS11_RV("C_Decrypt", rv);
2857 if (rv != CKR_OK) {
2858 ret = WC_HW_E;
2859 }
2860 }
2861 if (ret == 0) {
2862 *info->pk.rsa.outLen = (word32)outLen;
2863 }
2864
2865 return ret;
2866}
2867
2868/**
2869 * Exponentiate the input with the private part of the RSA key.
2870 * Used in private encrypt and decrypt.
2871 *
2872 * @param [in] session Session object.
2873 * @param [in] info Cryptographic operation data.
2874 * @param [in] func Function to perform - decrypt or sign.
2875 * @return WC_HW_E when a PKCS#11 library call fails.
2876 * @return 0 on success.
2877 */
2878static int Pkcs11RsaSign(Pkcs11Session* session, wc_CryptoInfo* info,
2879 CK_OBJECT_HANDLE key)
2880{
2881 int ret = 0;
2882 CK_RV rv;
2883 CK_MECHANISM mech;
2884 CK_ULONG outLen;
2885 CK_MECHANISM_TYPE mechanism;
2886#ifdef WOLF_CRYPTO_CB_RSA_PAD
2887 CK_RSA_PKCS_PSS_PARAMS pssParams;
2888 int hLen;
2889 int saltLen;
2890#endif
2891
2892 WOLFSSL_MSG("PKCS#11: RSA Private Key Operation");
2893
2894 if (info->pk.rsa.outLen == NULL) {
2895 ret = BAD_FUNC_ARG;
2896 }
2897
2898 switch(info->pk.type) {
2899#ifdef WOLF_CRYPTO_CB_RSA_PAD
2900 case WC_PK_TYPE_RSA_PKCS:
2901 mechanism = CKM_RSA_PKCS;
2902 break;
2903 case WC_PK_TYPE_RSA_PSS:
2904 mechanism = CKM_RSA_PKCS_PSS;
2905 break;
2906#endif /* WOLF_CRYPTO_CB_RSA_PAD */
2907 default:
2908 mechanism = CKM_RSA_X_509;
2909 break;
2910 }
2911
2912 if (ret == 0) {
2913 /* Raw RSA encrypt/decrypt operation. */
2914 mech.mechanism = mechanism;
2915 mech.ulParameterLen = 0;
2916 mech.pParameter = NULL;
2917
2918#ifdef WOLF_CRYPTO_CB_RSA_PAD
2919 if (mechanism == CKM_RSA_PKCS_PSS) {
2920 mech.ulParameterLen = sizeof(CK_RSA_PKCS_PSS_PARAMS);
2921 mech.pParameter = &pssParams;
2922 pssParams.hashAlg = wc_hash2ckm(info->pk.rsa.padding->hash);
2923 pssParams.mgf = wc_mgf2ckm(info->pk.rsa.padding->mgf);
2924
2925 saltLen = info->pk.rsa.padding->saltLen;
2926 hLen = wc_hash2sz(info->pk.rsa.padding->hash);
2927
2928 /* Same salt length code as rsa.c */
2929 if (saltLen == RSA_PSS_SALT_LEN_DEFAULT)
2930 saltLen = hLen;
2931#ifndef WOLFSSL_PSS_LONG_SALT
2932 else if (saltLen > hLen) {
2933 return PSS_SALTLEN_E;
2934 }
2935#endif
2936#ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER
2937 else if (saltLen < RSA_PSS_SALT_LEN_DEFAULT) {
2938 return PSS_SALTLEN_E;
2939 }
2940#else
2941 else if (saltLen == RSA_PSS_SALT_LEN_DISCOVER) {
2942 saltLen = *(info->pk.rsa.outLen) - hLen - 2;
2943 if (saltLen < 0) {
2944 return PSS_SALTLEN_E;
2945 }
2946 }
2947 else if (saltLen < RSA_PSS_SALT_LEN_DISCOVER) {
2948 return PSS_SALTLEN_E;
2949 }
2950#endif
2951 if (*(info->pk.rsa.outLen) - hLen < (word32)(saltLen + 2)) {
2952 return PSS_SALTLEN_E;
2953 }
2954
2955 pssParams.sLen = saltLen;
2956 }
2957#endif /* WOLF_CRYPTO_CB_RSA_PAD */
2958
2959 rv = session->func->C_SignInit(session->handle, &mech, key);
2960 PKCS11_RV("C_SignInit", rv);
2961 if (rv != CKR_OK) {
2962 ret = WC_HW_E;
2963 }
2964 }
2965 if (ret == 0) {
2966 PKCS11_VAL("C_Sign inLen", info->pk.rsa.inLen);
2967 PKCS11_VAL("C_Sign outLen", *info->pk.rsa.outLen);
2968 outLen = (CK_ULONG)*info->pk.rsa.outLen;
2969 rv = session->func->C_Sign(session->handle,
2970 (CK_BYTE_PTR)info->pk.rsa.in, info->pk.rsa.inLen,
2971 info->pk.rsa.out, &outLen);
2972 PKCS11_RV("C_Sign", rv);
2973 if (rv != CKR_OK) {
2974 ret = WC_HW_E;
2975 }
2976 }
2977 if (ret == 0)
2978 *info->pk.rsa.outLen = (word32)outLen;
2979
2980
2981 return ret;
2982}
2983
2984/**
2985 * Perform an RSA operation.
2986 *
2987 * @param [in] session Session object.
2988 * @param [in] info Cryptographic operation data.
2989 * @return WC_HW_E when a PKCS#11 library call fails.
2990 * @return 0 on success.
2991 */
2992static int Pkcs11Rsa(Pkcs11Session* session, wc_CryptoInfo* info)
2993{
2994 int ret = 0;
2995 CK_MECHANISM_INFO mechInfo;
2996 CK_MECHANISM_TYPE mechanism = 0x0UL;
2997 int sessionKey = 0;
2998 CK_OBJECT_HANDLE key;
2999 RsaKey* rsaKey = info->pk.rsa.key;
3000 int type = info->pk.rsa.type;
3001
3002 switch(info->pk.type) {
3003#ifndef NO_PKCS11_RSA_PKCS
3004 case WC_PK_TYPE_RSA_PKCS:
3005 mechanism = CKM_RSA_PKCS;
3006 break;
3007 case WC_PK_TYPE_RSA_PSS:
3008 mechanism = CKM_RSA_PKCS_PSS;
3009 break;
3010 case WC_PK_TYPE_RSA_OAEP:
3011 mechanism = CKM_RSA_PKCS_OAEP;
3012 break;
3013#endif /* !NO_PKCS11_RSA_PKCS */
3014 case WC_PK_TYPE_RSA:
3015 mechanism = CKM_RSA_X_509;
3016 break;
3017 }
3018
3019 /* Check operation is supported. */
3020 ret = Pkcs11MechAvail(session, mechanism, &mechInfo);
3021
3022 if (ret == 0) {
3023 if ((type == RSA_PUBLIC_ENCRYPT) || (type == RSA_PUBLIC_DECRYPT)) {
3024 sessionKey = !mp_iszero(&rsaKey->e);
3025
3026 /* Make a handle to a public key. */
3027 ret = Pkcs11RsaPublicKey(session, rsaKey, sessionKey, &key);
3028 }
3029 else {
3030 sessionKey = !mp_iszero(&rsaKey->d);
3031
3032 /* Make a handle to a private key. */
3033 ret = Pkcs11RsaPrivateKey(session, rsaKey, sessionKey, &key);
3034 }
3035 }
3036 if (ret == 0) {
3037 if (type == RSA_PUBLIC_ENCRYPT) {
3038 WOLFSSL_MSG("PKCS#11: Public Encrypt");
3039 if ((mechInfo.flags & CKF_ENCRYPT) != 0) {
3040 ret = Pkcs11RsaEncrypt(session, info, key);
3041 }
3042 else {
3043 ret = NOT_COMPILED_IN;
3044 }
3045 }
3046 else if (type == RSA_PUBLIC_DECRYPT) {
3047 WOLFSSL_MSG("PKCS#11: Public Decrypt");
3048 if ((mechInfo.flags & CKF_ENCRYPT) != 0) {
3049 ret = Pkcs11RsaEncrypt(session, info, key);
3050 }
3051 else {
3052 ret = NOT_COMPILED_IN;
3053 }
3054 }
3055 else if (type == RSA_PRIVATE_DECRYPT) {
3056 WOLFSSL_MSG("PKCS#11: Private Decrypt");
3057 if ((mechInfo.flags & CKF_DECRYPT) != 0) {
3058 ret = Pkcs11RsaDecrypt(session, info, key);
3059 }
3060 else {
3061 ret = Pkcs11RsaSign(session, info, key);
3062 }
3063 }
3064 else if (type == RSA_PRIVATE_ENCRYPT) {
3065 WOLFSSL_MSG("PKCS#11: Private Encrypt");
3066 if ((mechInfo.flags & CKF_SIGN) != 0) {
3067 ret = Pkcs11RsaSign(session, info, key);
3068 }
3069 else {
3070 ret = Pkcs11RsaDecrypt(session, info, key);
3071 }
3072 }
3073 }
3074
3075 if (sessionKey) {
3076 session->func->C_DestroyObject(session->handle, key);
3077 }
3078
3079 return ret;
3080}
3081
3082#ifdef WOLFSSL_KEY_GEN
3083/**
3084 * Perform an RSA key generation operation.
3085 * The private key data stays on the device.
3086 *
3087 * @param [in] session Session object.
3088 * @param [in] info Cryptographic operation data.
3089 * @return WC_HW_E when a PKCS#11 library call fails.
3090 * @return 0 on success.
3091 */
3092static int Pkcs11RsaKeyGen(Pkcs11Session* session, wc_CryptoInfo* info)
3093{
3094 int ret = 0;
3095 RsaKey* key = info->pk.rsakg.key;
3096 CK_RV rv;
3097 CK_ULONG bits = info->pk.rsakg.size;
3098 CK_OBJECT_HANDLE pubKey = NULL_PTR, privKey = NULL_PTR;
3099 CK_MECHANISM mech;
3100 static CK_BYTE pub_exp[] = { 0x01, 0x00, 0x01, 0x00 };
3101 CK_ATTRIBUTE pubKeyTmpl[] = {
3102 { CKA_MODULUS_BITS, &bits, sizeof(bits) },
3103 { CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) },
3104 { CKA_VERIFY, &ckTrue, sizeof(ckTrue) },
3105 { CKA_PUBLIC_EXPONENT, &pub_exp, sizeof(pub_exp) }
3106 };
3107 CK_ULONG pubTmplCnt = sizeof(pubKeyTmpl)/sizeof(*pubKeyTmpl);
3108 /* Empty entries for optional label/ID. */
3109 CK_ATTRIBUTE privKeyTmpl[] = {
3110 { CKA_DECRYPT, &ckTrue, sizeof(ckTrue) },
3111 { CKA_SIGN, &ckTrue, sizeof(ckTrue) },
3112 { 0, NULL, 0 },
3113 { 0, NULL, 0 }
3114 };
3115 /* 2 mandatory entries + 2 optional. */
3116 int privTmplCnt = 2;
3117 int i;
3118
3119 ret = Pkcs11MechAvail(session, CKM_RSA_PKCS_KEY_PAIR_GEN, NULL);
3120 if (ret == 0) {
3121 WOLFSSL_MSG("PKCS#11: RSA Key Generation Operation");
3122
3123 /* Most commonly used public exponent value (array initialized). */
3124 if (info->pk.rsakg.e != WC_RSA_EXPONENT) {
3125 for (i = 0; i < (int)sizeof(pub_exp); i++)
3126 pub_exp[i] = (info->pk.rsakg.e >> (8 * i)) & 0xff;
3127 }
3128 for (i = (int)sizeof(pub_exp) - 1; pub_exp[i] == 0; i--) {
3129 }
3130 pubKeyTmpl[3].ulValueLen = i + 1;
3131
3132 if (key->labelLen != 0) {
3133 privKeyTmpl[privTmplCnt].type = CKA_LABEL;
3134 privKeyTmpl[privTmplCnt].pValue = key->label;
3135 privKeyTmpl[privTmplCnt].ulValueLen = key->labelLen;
3136 privTmplCnt++;
3137 }
3138 if (key->idLen != 0) {
3139 privKeyTmpl[privTmplCnt].type = CKA_ID;
3140 privKeyTmpl[privTmplCnt].pValue = key->id;
3141 privKeyTmpl[privTmplCnt].ulValueLen = key->idLen;
3142 privTmplCnt++;
3143 }
3144
3145 mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
3146 mech.ulParameterLen = 0;
3147 mech.pParameter = NULL;
3148
3149 PKCS11_DUMP_TEMPLATE("Public Key", pubKeyTmpl, pubTmplCnt);
3150 PKCS11_DUMP_TEMPLATE("Private Key", privKeyTmpl, privTmplCnt);
3151 rv = session->func->C_GenerateKeyPair(session->handle, &mech,
3152 pubKeyTmpl, pubTmplCnt,
3153 privKeyTmpl, privTmplCnt,
3154 &pubKey, &privKey);
3155 PKCS11_RV("C_GenerateKeyPair", rv);
3156 if (rv != CKR_OK) {
3157 ret = -1;
3158 }
3159 }
3160
3161 if (ret == 0)
3162 ret = Pkcs11GetRsaPublicKey(key, session, pubKey);
3163
3164 if (pubKey != NULL_PTR)
3165 ret = (int)session->func->C_DestroyObject(session->handle, pubKey);
3166 if (ret != 0 && privKey != NULL_PTR)
3167 ret = (int)session->func->C_DestroyObject(session->handle, privKey);
3168
3169 return ret;
3170}
3171#endif /* WOLFSSL_KEY_GEN */
3172#endif /* !NO_RSA */
3173
3174#ifdef HAVE_ECC
3175/**
3176 * Find the PKCS#11 object containing the ECC public or private key data.
3177 * Search for public key by public point.
3178 *
3179 * @param [out] key Handle to key object.
3180 * @param [in] keyClass Public or private key class.
3181 * @param [in] session Session object.
3182 * @param [in] eccKey ECC key with parameters.
3183 * @return WC_HW_E when a PKCS#11 library call fails.
3184 * @return MEMORY_E when a memory allocation fails.
3185 * @return 0 on success.
3186 */
3187static int Pkcs11FindEccKey(CK_OBJECT_HANDLE* key, CK_OBJECT_CLASS keyClass,
3188 Pkcs11Session* session, ecc_key* eccKey,
3189 int op)
3190{
3191 int ret = 0;
3192 int i;
3193 unsigned char* ecPoint = NULL;
3194 word32 len = 0;
3195 CK_ULONG count;
3196 CK_UTF8CHAR params[ECC_MAX_OID_LEN];
3197 CK_ATTRIBUTE keyTemplate[] = {
3198 { CKA_CLASS, &keyClass, sizeof(keyClass) },
3199 { CKA_KEY_TYPE, &ecKeyType, sizeof(ecKeyType) },
3200 { CKA_EC_PARAMS, params, 0 },
3201 { op, &ckTrue, sizeof(ckTrue) },
3202 { CKA_EC_POINT, NULL, 0 },
3203 };
3204 CK_ULONG attrCnt = 4;
3205
3206 ret = Pkcs11EccSetParams(eccKey, keyTemplate, 2);
3207 if (ret == 0 && keyClass == CKO_PUBLIC_KEY) {
3208 /* ASN1 encoded: OCT + uncompressed point */
3209 len = 3 + 1 + 2 * eccKey->dp->size;
3210 ecPoint = (unsigned char*)XMALLOC(len, eccKey->heap, DYNAMIC_TYPE_ECC);
3211 if (ecPoint == NULL)
3212 ret = MEMORY_E;
3213 }
3214 if (ret == 0 && keyClass == CKO_PUBLIC_KEY) {
3215 len -= 3;
3216 i = 0;
3217 ecPoint[i++] = ASN_OCTET_STRING;
3218 if (len >= ASN_LONG_LENGTH)
3219 ecPoint[i++] = (ASN_LONG_LENGTH | 1);
3220 ecPoint[i++] = len;
3221 if (eccKey->type == 0)
3222 eccKey->type = ECC_PUBLICKEY;
3223 PRIVATE_KEY_UNLOCK();
3224 ret = wc_ecc_export_x963(eccKey, ecPoint + i, &len);
3225 PRIVATE_KEY_LOCK();
3226 }
3227 if (ret == 0 && keyClass == CKO_PUBLIC_KEY) {
3228 keyTemplate[attrCnt].pValue = ecPoint;
3229 keyTemplate[attrCnt].ulValueLen = len + i;
3230 attrCnt++;
3231 }
3232 if (ret == 0) {
3233 ret = Pkcs11FindKeyByTemplate(key, session, keyTemplate, attrCnt, &count);
3234 }
3235
3236 XFREE(ecPoint, eccKey->heap, DYNAMIC_TYPE_ECC);
3237
3238 return ret;
3239}
3240
3241/**
3242 * Gets the public key data from the PKCS#11 object and puts into the ECC key.
3243 *
3244 * @param [in] key ECC public key.
3245 * @param [in] session Session object.
3246 * @param [in] pubKey ECC public key PKCS#11 object.
3247 * @return WC_HW_E when a PKCS#11 library call fails.
3248 * @return MEMORY_E when a memory allocation fails.
3249 * @return 0 on success.
3250 */
3251static int Pkcs11GetEccPublicKey(ecc_key* key, Pkcs11Session* session,
3252 CK_OBJECT_HANDLE pubKey)
3253{
3254 int ret = 0;
3255 word32 i = 0;
3256 int curveIdx;
3257 unsigned char* point = NULL;
3258 int pointSz = 0;
3259 byte tag;
3260 CK_RV rv;
3261 CK_ATTRIBUTE tmpl[] = {
3262 { CKA_EC_POINT, NULL_PTR, 0 },
3263 };
3264 CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
3265
3266 rv = session->func->C_GetAttributeValue(session->handle, pubKey, tmpl,
3267 tmplCnt);
3268 PKCS11_RV("C_GetAttributeValue", rv);
3269 if (rv != CKR_OK) {
3270 ret = WC_HW_E;
3271 }
3272
3273 if (ret == 0) {
3274 pointSz = (int)tmpl[0].ulValueLen;
3275 point = (unsigned char*)XMALLOC(pointSz, key->heap, DYNAMIC_TYPE_ECC);
3276 if (point == NULL)
3277 ret = MEMORY_E;
3278 }
3279 if (ret == 0) {
3280 tmpl[0].pValue = point;
3281
3282 PKCS11_DUMP_TEMPLATE("Get Ec Public Key", tmpl, tmplCnt);
3283 rv = session->func->C_GetAttributeValue(session->handle, pubKey,
3284 tmpl, tmplCnt);
3285 PKCS11_RV("C_GetAttributeValue", rv);
3286 if (rv != CKR_OK) {
3287 ret = WC_HW_E;
3288 }
3289 PKCS11_DUMP_TEMPLATE("Ec Public Key", tmpl, tmplCnt);
3290 }
3291
3292 /* Make sure the data is big enough for ASN.1: OCT + uncompressed point */
3293 if (ret == 0 && pointSz < key->dp->size * 2 + 1 + 2)
3294 ret = ASN_PARSE_E;
3295 /* Step over the OCTET_STRING wrapper. */
3296 if (ret == 0 && GetASNTag(point, &i, &tag, pointSz) != 0)
3297 ret = ASN_PARSE_E;
3298 if (ret == 0 && tag != ASN_OCTET_STRING)
3299 ret = ASN_PARSE_E;
3300 if (ret == 0 && point[i] >= ASN_LONG_LENGTH) {
3301 if (point[i++] != (ASN_LONG_LENGTH | 1))
3302 ret = ASN_PARSE_E;
3303 else if (pointSz < key->dp->size * 2 + 1 + 3)
3304 ret = ASN_PARSE_E;
3305 }
3306 if (ret == 0 && point[i++] != key->dp->size * 2 + 1)
3307 ret = ASN_PARSE_E;
3308
3309 if (ret == 0) {
3310 curveIdx = wc_ecc_get_curve_idx(key->dp->id);
3311 ret = wc_ecc_import_point_der(point + i, pointSz - i, curveIdx,
3312 &key->pubkey);
3313 }
3314 /* make sure the ecc_key type has been set */
3315 if (ret == 0 && key->type == 0) {
3316 key->type = ECC_PUBLICKEY;
3317 }
3318
3319 XFREE(point, key->heap, DYNAMIC_TYPE_ECC);
3320
3321 return ret;
3322}
3323
3324#ifndef NO_PKCS11_EC_KEYGEN
3325/**
3326 * Perform an ECC key generation operation.
3327 * The private key data stays on the device.
3328 *
3329 * @param [in] session Session object.
3330 * @param [in] info Cryptographic operation data.
3331 * @return WC_HW_E when a PKCS#11 library call fails.
3332 * @return 0 on success.
3333 */
3334static int Pkcs11EcKeyGen(Pkcs11Session* session, wc_CryptoInfo* info)
3335{
3336 int ret = 0;
3337 ecc_key* key = info->pk.eckg.key;
3338 CK_RV rv;
3339 CK_OBJECT_HANDLE pubKey = NULL_PTR, privKey = NULL_PTR;
3340 CK_MECHANISM mech;
3341 CK_UTF8CHAR params[ECC_MAX_OID_LEN];
3342 CK_ATTRIBUTE pubKeyTmpl[] = {
3343 { CKA_EC_PARAMS, params, 0 },
3344 { CKA_VERIFY, &ckTrue, sizeof(ckTrue) },
3345 { CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) },
3346 };
3347 int pubTmplCnt = 1;
3348 /* Empty entries for optional label/ID. */
3349 CK_ATTRIBUTE privKeyTmplDerive[] = {
3350 { CKA_DERIVE, &ckTrue, sizeof(ckTrue) },
3351 { 0, NULL, 0 },
3352 { 0, NULL, 0 },
3353 };
3354 /* Empty entries for optional label/ID. */
3355 CK_ATTRIBUTE privKeyTmplEncSign[] = {
3356 { CKA_SIGN, &ckTrue, sizeof(ckTrue) },
3357 { CKA_DECRYPT, &ckTrue, sizeof(ckTrue) },
3358 { 0, NULL, 0 },
3359 { 0, NULL, 0 },
3360 };
3361 CK_ATTRIBUTE* privKeyTmpl = privKeyTmplDerive;
3362 /* Mandatory entries + 2 optional. */
3363 int privTmplCnt = 1;
3364
3365 ret = Pkcs11MechAvail(session, CKM_EC_KEY_PAIR_GEN, NULL);
3366 if (ret == 0) {
3367 WOLFSSL_MSG("PKCS#11: EC Key Generation Operation");
3368
3369 ret = Pkcs11EccSetParams(key, pubKeyTmpl, 0);
3370 }
3371 if (ret == 0) {
3372 /* Default is to use for derivation. */
3373 if ((key->flags & WC_ECC_FLAG_DEC_SIGN) == WC_ECC_FLAG_DEC_SIGN) {
3374 privKeyTmpl = privKeyTmplEncSign;
3375 privTmplCnt = 2;
3376 pubTmplCnt = 2;
3377 }
3378 if (key->labelLen != 0) {
3379 privKeyTmpl[privTmplCnt].type = CKA_LABEL;
3380 privKeyTmpl[privTmplCnt].pValue = key->label;
3381 privKeyTmpl[privTmplCnt].ulValueLen = key->labelLen;
3382 privTmplCnt++;
3383 }
3384 if (key->idLen != 0) {
3385 privKeyTmpl[privTmplCnt].type = CKA_ID;
3386 privKeyTmpl[privTmplCnt].pValue = key->id;
3387 privKeyTmpl[privTmplCnt].ulValueLen = key->idLen;
3388 privTmplCnt++;
3389 }
3390
3391 mech.mechanism = CKM_EC_KEY_PAIR_GEN;
3392 mech.ulParameterLen = 0;
3393 mech.pParameter = NULL;
3394
3395 PKCS11_DUMP_TEMPLATE("Ec Private", privKeyTmpl, privTmplCnt);
3396 PKCS11_DUMP_TEMPLATE("Ec Public", pubKeyTmpl, pubTmplCnt);
3397
3398 rv = session->func->C_GenerateKeyPair(session->handle, &mech,
3399 pubKeyTmpl, pubTmplCnt,
3400 privKeyTmpl, privTmplCnt,
3401 &pubKey, &privKey);
3402 PKCS11_RV("C_GenerateKeyPair", rv);
3403 if (rv != CKR_OK) {
3404 ret = -1;
3405 }
3406 }
3407
3408 if (ret == 0)
3409 ret = Pkcs11GetEccPublicKey(key, session, pubKey);
3410
3411 if (pubKey != NULL_PTR)
3412 session->func->C_DestroyObject(session->handle, pubKey);
3413 if (ret == 0 && privKey != NULL_PTR) {
3414 key->devCtx = (void*)(wc_ptr_t)privKey;
3415 }
3416 else if (ret != 0 && privKey != NULL_PTR) {
3417 session->func->C_DestroyObject(session->handle, privKey);
3418 }
3419
3420 return ret;
3421}
3422#endif
3423
3424#ifndef NO_PKCS11_ECDH
3425/**
3426 * Extracts the secret key data from the PKCS#11 object.
3427 *
3428 * @param [in] session Session object.
3429 * @param [in] secret PKCS#11 object with the secret key data.
3430 * @param [in] out Buffer to hold secret data.
3431 * @param [in,out] outLen On in, length of buffer.
3432 * On out, the length of data in buffer.
3433 * @return WC_HW_E when a PKCS#11 library call fails.
3434 * @return 0 on success.
3435 */
3436static int Pkcs11ExtractSecret(Pkcs11Session* session, CK_OBJECT_HANDLE secret,
3437 byte* out, word32* outLen)
3438{
3439 int ret = 0;
3440 CK_ATTRIBUTE tmpl[] = {
3441 {CKA_VALUE, NULL_PTR, 0}
3442 };
3443 CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
3444 CK_RV rv;
3445
3446 PKCS11_DUMP_TEMPLATE("Get Secret Length", tmpl, tmplCnt);
3447 rv = session->func->C_GetAttributeValue(session->handle, secret, tmpl,
3448 tmplCnt);
3449 PKCS11_RV("C_GetAttributeValue", rv);
3450 if (rv != CKR_OK) {
3451 ret = WC_HW_E;
3452 }
3453 PKCS11_DUMP_TEMPLATE("Secret Length", tmpl, tmplCnt);
3454 if (ret == 0) {
3455 if (tmpl[0].ulValueLen == CK_UNAVAILABLE_INFORMATION)
3456 ret = WC_HW_E;
3457 else if (tmpl[0].ulValueLen > *outLen)
3458 ret = BUFFER_E;
3459 }
3460 if (ret == 0) {
3461 tmpl[0].pValue = out;
3462 PKCS11_DUMP_TEMPLATE("Get Secret", tmpl, tmplCnt);
3463 rv = session->func->C_GetAttributeValue(session->handle, secret,
3464 tmpl, tmplCnt);
3465 PKCS11_RV("C_GetAttributeValue", rv);
3466 if (rv != CKR_OK) {
3467 ret = WC_HW_E;
3468 }
3469 PKCS11_DUMP_TEMPLATE("Secret", tmpl, tmplCnt);
3470 *outLen = (word32)tmpl[0].ulValueLen;
3471 }
3472
3473 return ret;
3474}
3475
3476/**
3477 * Performs the ECDH secret generation operation.
3478 *
3479 * @param [in] session Session object.
3480 * @param [in] info Cryptographic operation data.
3481 * @return WC_HW_E when a PKCS#11 library call fails.
3482 * 0 on success.
3483 */
3484static int Pkcs11ECDH(Pkcs11Session* session, wc_CryptoInfo* info)
3485{
3486 int ret = 0;
3487 int sessionKey = 0;
3488 unsigned char* point = NULL;
3489 word32 pointLen;
3490 CK_RV rv;
3491 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
3492 CK_MECHANISM mech;
3493 CK_ECDH1_DERIVE_PARAMS params;
3494 CK_OBJECT_HANDLE privateKey = NULL_PTR;
3495 CK_OBJECT_HANDLE secret = CK_INVALID_HANDLE;
3496 CK_ULONG secSz;
3497 CK_ATTRIBUTE tmpl[] = {
3498 { CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass) },
3499 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
3500 { CKA_PRIVATE, &ckFalse, sizeof(ckFalse) },
3501 { CKA_SENSITIVE, &ckFalse, sizeof(ckFalse) },
3502 { CKA_EXTRACTABLE, &ckTrue, sizeof(ckTrue) },
3503 { CKA_VALUE_LEN, &secSz, sizeof(secSz) }
3504 };
3505 CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
3506
3507 ret = Pkcs11MechAvail(session, CKM_ECDH1_DERIVE, NULL);
3508 if (ret == 0 && info->pk.ecdh.outlen == NULL) {
3509 ret = BAD_FUNC_ARG;
3510 }
3511 if (ret == 0) {
3512 WOLFSSL_MSG("PKCS#11: EC Key Derivation Operation");
3513
3514 if (info->pk.ecdh.private_key->devCtx != NULL) {
3515 privateKey = (CK_OBJECT_HANDLE)(wc_ptr_t)
3516 info->pk.ecdh.private_key->devCtx;
3517 }
3518 else if ((sessionKey = !mp_iszero(
3519 wc_ecc_key_get_priv(info->pk.ecdh.private_key))))
3520 ret = Pkcs11CreateEccPrivateKey(&privateKey, session,
3521 info->pk.ecdh.private_key, CKA_DERIVE);
3522 else if (info->pk.ecdh.private_key->labelLen > 0) {
3523 ret = Pkcs11FindKeyByLabel(&privateKey, CKO_PRIVATE_KEY, CKK_EC,
3524 session,
3525 info->pk.ecdh.private_key->label,
3526 info->pk.ecdh.private_key->labelLen);
3527 }
3528 else if (info->pk.ecdh.private_key->idLen > 0) {
3529 ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_EC,
3530 session, info->pk.ecdh.private_key->id,
3531 info->pk.ecdh.private_key->idLen);
3532 }
3533 else {
3534 ret = Pkcs11FindEccKey(&privateKey, CKO_PRIVATE_KEY, session,
3535 info->pk.ecdh.public_key, CKA_DERIVE);
3536 }
3537 }
3538 if (ret == 0) {
3539 PRIVATE_KEY_UNLOCK();
3540 ret = wc_ecc_export_x963(info->pk.ecdh.public_key, NULL, &pointLen);
3541 PRIVATE_KEY_LOCK();
3542 if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
3543 point = (unsigned char*)XMALLOC(pointLen,
3544 info->pk.ecdh.public_key->heap,
3545 DYNAMIC_TYPE_ECC_BUFFER);
3546 PRIVATE_KEY_UNLOCK();
3547 ret = wc_ecc_export_x963(info->pk.ecdh.public_key, point,
3548 &pointLen);
3549 PRIVATE_KEY_LOCK();
3550 }
3551 }
3552
3553 if (ret == 0) {
3554 secSz = *info->pk.ecdh.outlen;
3555 if (info->pk.ecdh.private_key->dp != NULL &&
3556 secSz > (CK_ULONG)info->pk.ecdh.private_key->dp->size)
3557 secSz = info->pk.ecdh.private_key->dp->size;
3558
3559 params.kdf = CKD_NULL;
3560 params.pSharedData = NULL;
3561 params.ulSharedDataLen = 0;
3562 params.pPublicData = point;
3563 params.ulPublicDataLen = pointLen;
3564
3565 mech.mechanism = CKM_ECDH1_DERIVE;
3566 mech.ulParameterLen = sizeof(params);
3567 mech.pParameter = ¶ms;
3568
3569 PKCS11_DUMP_TEMPLATE("ECDH key", tmpl, tmplCnt);
3570 rv = session->func->C_DeriveKey(session->handle, &mech, privateKey,
3571 tmpl, tmplCnt, &secret);
3572 PKCS11_RV("C_DeriveKey", rv);
3573 if (rv != CKR_OK) {
3574 ret = WC_HW_E;
3575 }
3576 }
3577
3578 if (ret == 0) {
3579 ret = Pkcs11ExtractSecret(session, secret, info->pk.ecdh.out,
3580 info->pk.ecdh.outlen);
3581 }
3582
3583 if (secret != CK_INVALID_HANDLE)
3584 session->func->C_DestroyObject(session->handle, secret);
3585
3586 if (sessionKey && privateKey != NULL_PTR)
3587 session->func->C_DestroyObject(session->handle, privateKey);
3588
3589 if (point != NULL)
3590 XFREE(point, info->pk.ecdh.public_key->heap, DYNAMIC_TYPE_ECC_BUFFER);
3591
3592 return ret;
3593}
3594#endif
3595
3596/**
3597 * Encode, in place, the ECDSA signature.
3598 * Two fixed width values into ASN.1 DER encoded SEQ { INT, INT }
3599 *
3600 * @param [in,out] sig Signature data.
3601 * @param [in] sz Size of original signature data.
3602 * @return Length of the ASN.1 DER encoded signature.
3603 */
3604static word32 Pkcs11ECDSASig_Encode(byte* sig, word32 sz)
3605{
3606 word32 rHigh, sHigh, seqLen;
3607 word32 rStart = 0, sStart = 0;
3608 word32 sigSz, rSz, rLen, sSz, sLen;
3609 word32 i;
3610
3611 /* Find first byte of data in r and s. */
3612 while (rStart < sz - 1 && sig[rStart] == 0x00)
3613 rStart++;
3614 while (sStart < sz - 1 && sig[sz + sStart] == 0x00)
3615 sStart++;
3616 /* Check if 0 needs to be prepended to make integer a positive number. */
3617 rHigh = sig[rStart] >> 7;
3618 sHigh = sig[sz + sStart] >> 7;
3619 /* Calculate length of integer to put into ASN.1 encoding. */
3620 rLen = sz - rStart;
3621 sLen = sz - sStart;
3622 /* r and s: INT (2 bytes) + [ 0x00 ] + integer */
3623 rSz = 2 + rHigh + rLen;
3624 sSz = 2 + sHigh + sLen;
3625 /* Calculate the complete ASN.1 DER encoded size. */
3626 sigSz = rSz + sSz;
3627 if (sigSz >= ASN_LONG_LENGTH)
3628 seqLen = 3;
3629 else
3630 seqLen = 2;
3631
3632 /* Move s and then r integers into their final places. */
3633 XMEMMOVE(sig + seqLen + rSz + (sSz - sLen), sig + sz + sStart, sLen);
3634 XMEMMOVE(sig + seqLen + (rSz - rLen), sig + rStart, rLen);
3635
3636 /* Put the ASN.1 DER encoding around data. */
3637 i = 0;
3638 sig[i++] = ASN_CONSTRUCTED | ASN_SEQUENCE;
3639 if (seqLen == 3)
3640 sig[i++] = ASN_LONG_LENGTH | 0x01;
3641 sig[i++] = sigSz;
3642 sig[i++] = ASN_INTEGER;
3643 sig[i++] = rHigh + (sz - rStart);
3644 if (rHigh)
3645 sig[i++] = 0x00;
3646 i += sz - rStart;
3647 sig[i++] = ASN_INTEGER;
3648 sig[i++] = sHigh + (sz - sStart);
3649 if (sHigh)
3650 sig[i] = 0x00;
3651
3652 return seqLen + sigSz;
3653}
3654
3655/**
3656 * Decode the ECDSA signature.
3657 * ASN.1 DER encode SEQ { INT, INT } converted to two fixed with values.
3658 *
3659 * @param [in] in ASN.1 DER encoded signature.
3660 * @param [in] inSz Size of ASN.1 signature.
3661 * @param [in] sig Output buffer.
3662 * @param [in] sz Size of output buffer.
3663 * @return ASN_PARSE_E when the ASN.1 encoding is invalid.
3664 * @return 0 on success.
3665 */
3666static int Pkcs11ECDSASig_Decode(const byte* in, word32 inSz, byte* sig,
3667 word32 sz)
3668{
3669 int ret = 0;
3670 word32 i = 0;
3671 byte tag;
3672 int len, seqLen = 2;
3673
3674 /* Make sure zeros in place when decoding short integers. */
3675 XMEMSET(sig, 0, sz * 2);
3676
3677 /* Check min data for: SEQ + INT. */
3678 if (inSz < 5)
3679 ret = ASN_PARSE_E;
3680 /* Check SEQ */
3681 if (ret == 0 && in[i++] != (ASN_CONSTRUCTED | ASN_SEQUENCE))
3682 ret = ASN_PARSE_E;
3683 if (ret == 0 && in[i] >= ASN_LONG_LENGTH) {
3684 if (in[i] != (ASN_LONG_LENGTH | 0x01))
3685 ret = ASN_PARSE_E;
3686 else {
3687 i++;
3688 seqLen++;
3689 }
3690 }
3691 if (ret == 0 && in[i++] != inSz - seqLen)
3692 ret = ASN_PARSE_E;
3693
3694 /* Check INT */
3695 if (ret == 0 && GetASNTag(in, &i, &tag, inSz) != 0)
3696 ret = ASN_PARSE_E;
3697 if (ret == 0 && tag != ASN_INTEGER)
3698 ret = ASN_PARSE_E;
3699 if (ret == 0 && (len = in[i++]) > sz + 1)
3700 ret = ASN_PARSE_E;
3701 /* Check there is space for INT data */
3702 if (ret == 0 && i + len > inSz)
3703 ret = ASN_PARSE_E;
3704 if (ret == 0) {
3705 /* Skip leading zero */
3706 if (in[i] == 0x00) {
3707 i++;
3708 len--;
3709 }
3710 /* Copy r into sig. */
3711 XMEMCPY(sig + sz - len, in + i, len);
3712 i += len;
3713 }
3714
3715 /* Check min data for: INT. */
3716 if (ret == 0 && i + 2 > inSz)
3717 ret = ASN_PARSE_E;
3718 /* Check INT */
3719 if (ret == 0 && GetASNTag(in, &i, &tag, inSz) != 0)
3720 ret = ASN_PARSE_E;
3721 if (ret == 0 && tag != ASN_INTEGER)
3722 ret = ASN_PARSE_E;
3723 if (ret == 0 && (len = in[i++]) > sz + 1)
3724 ret = ASN_PARSE_E;
3725 /* Check there is space for INT data */
3726 if (ret == 0 && i + len > inSz)
3727 ret = ASN_PARSE_E;
3728 if (ret == 0) {
3729 /* Skip leading zero */
3730 if (in[i] == 0x00) {
3731 i++;
3732 len--;
3733 }
3734 /* Copy s into sig. */
3735 XMEMCPY(sig + sz + sz - len, in + i, len);
3736 }
3737
3738 return ret;
3739}
3740
3741/**
3742 * Get the parameters from the private key on the device.
3743 *
3744 * @param [in] session Session object.
3745 * @param [in] privKey PKCS #11 object handle of private key..
3746 * @param [in] key Ecc key to set parameters against.
3747 * @return WC_HW_E when a PKCS#11 library call fails.
3748 * @return 0 on success.
3749 */
3750static int Pkcs11GetEccParams(Pkcs11Session* session, CK_OBJECT_HANDLE privKey,
3751 ecc_key* key)
3752{
3753 int ret = 0;
3754 int curveId;
3755 CK_RV rv;
3756 byte oid[16];
3757 CK_ATTRIBUTE template[] = {
3758 { CKA_EC_PARAMS, (CK_VOID_PTR)oid, sizeof(oid) }
3759 };
3760
3761 PKCS11_DUMP_TEMPLATE("Get Ec Params", template, 1);
3762 rv = session->func->C_GetAttributeValue(session->handle, privKey, template,
3763 1);
3764 PKCS11_RV("C_GetAttributeValue", rv);
3765 if (rv != CKR_OK) {
3766 ret = WC_HW_E;
3767 }
3768 PKCS11_DUMP_TEMPLATE("Ec Params", template, 1);
3769 if (ret == 0) {
3770 /* PKCS #11 wraps the OID in ASN.1 */
3771 curveId = wc_ecc_get_curve_id_from_oid(oid + 2,
3772 (word32)template[0].ulValueLen - 2);
3773 if (curveId == ECC_CURVE_INVALID)
3774 ret = WC_HW_E;
3775 }
3776 if (ret == 0)
3777 ret = wc_ecc_set_curve(key, 0, curveId);
3778
3779 return ret;
3780}
3781
3782/**
3783 * Performs the ECDSA signing operation.
3784 *
3785 * @param session [in] Session object.
3786 * @param info [in] Cryptographic operation data.
3787 * @return WC_HW_E when a PKCS#11 library call fails.
3788 * @return 0 on success.
3789 */
3790static int Pkcs11ECDSA_Sign(Pkcs11Session* session, wc_CryptoInfo* info)
3791{
3792 int ret = 0;
3793 int sessionKey = 0;
3794 word32 sz;
3795 CK_RV rv;
3796 CK_ULONG outLen;
3797 CK_MECHANISM mech;
3798 CK_MECHANISM_INFO mechInfo;
3799 CK_OBJECT_HANDLE privateKey = NULL_PTR;
3800
3801 /* Check operation is supported. */
3802 ret = Pkcs11MechAvail(session, CKM_ECDSA, &mechInfo);
3803 if (ret == 0 && (mechInfo.flags & CKF_SIGN) == 0) {
3804 ret = NOT_COMPILED_IN;
3805 }
3806 if (ret == 0 && info->pk.eccsign.outlen == NULL) {
3807 ret = BAD_FUNC_ARG;
3808 }
3809 if (ret == 0 && info->pk.eccsign.out == NULL) {
3810 ret = BAD_FUNC_ARG;
3811 }
3812 if (ret == 0) {
3813 WOLFSSL_MSG("PKCS#11: EC Signing Operation");
3814
3815 if (info->pk.eccsign.key->devCtx != NULL) {
3816 privateKey = (CK_OBJECT_HANDLE)(wc_ptr_t)
3817 info->pk.eccsign.key->devCtx;
3818 }
3819 else if ((sessionKey = !mp_iszero(
3820 wc_ecc_key_get_priv(info->pk.eccsign.key))))
3821 ret = Pkcs11CreateEccPrivateKey(&privateKey, session,
3822 info->pk.eccsign.key, CKA_SIGN);
3823 else if (info->pk.eccsign.key->labelLen > 0) {
3824 ret = Pkcs11FindKeyByLabel(&privateKey, CKO_PRIVATE_KEY, CKK_EC,
3825 session, info->pk.eccsign.key->label,
3826 info->pk.eccsign.key->labelLen);
3827 if (ret == 0 && info->pk.eccsign.key->dp == NULL) {
3828 ret = Pkcs11GetEccParams(session, privateKey,
3829 info->pk.eccsign.key);
3830 }
3831 }
3832 else if (info->pk.eccsign.key->idLen > 0) {
3833 ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_EC,
3834 session, info->pk.eccsign.key->id,
3835 info->pk.eccsign.key->idLen);
3836 if (ret == 0 && info->pk.eccsign.key->dp == NULL) {
3837 ret = Pkcs11GetEccParams(session, privateKey,
3838 info->pk.eccsign.key);
3839 }
3840 }
3841 else {
3842 ret = Pkcs11FindEccKey(&privateKey, CKO_PRIVATE_KEY, session,
3843 info->pk.eccsign.key, CKA_SIGN);
3844 }
3845 }
3846
3847 if (ret == 0) {
3848 sz = info->pk.eccsign.key->dp->size;
3849 /* Maximum encoded size is two ordinates + 8 bytes of ASN.1. */
3850 if (*info->pk.eccsign.outlen < (word32)wc_ecc_sig_size_calc(sz))
3851 ret = BUFFER_E;
3852 }
3853
3854 if (ret == 0) {
3855 mech.mechanism = CKM_ECDSA;
3856 mech.ulParameterLen = 0;
3857 mech.pParameter = NULL;
3858
3859 rv = session->func->C_SignInit(session->handle, &mech, privateKey);
3860 PKCS11_RV("C_SignInit", rv);
3861 if (rv != CKR_OK) {
3862 ret = WC_HW_E;
3863 }
3864 }
3865
3866 if (ret == 0) {
3867 outLen = *info->pk.eccsign.outlen;
3868 rv = session->func->C_Sign(session->handle,
3869 (CK_BYTE_PTR)info->pk.eccsign.in,
3870 info->pk.eccsign.inlen, info->pk.eccsign.out,
3871 &outLen);
3872 PKCS11_RV("C_Sign", rv);
3873 if (rv != CKR_OK) {
3874 ret = WC_HW_E;
3875 }
3876 }
3877
3878 if (ret == 0) {
3879 *info->pk.eccsign.outlen = Pkcs11ECDSASig_Encode(info->pk.eccsign.out,
3880 sz);
3881 }
3882
3883 if (sessionKey && privateKey != NULL_PTR)
3884 session->func->C_DestroyObject(session->handle, privateKey);
3885
3886 return ret;
3887}
3888
3889/**
3890 * Performs the ECDSA verification operation.
3891 *
3892 * @param [in] session Session object.
3893 * @param [in] info Cryptographic operation data.
3894 * @return WC_HW_E when a PKCS#11 library call fails.
3895 * @return MEMORY_E when a memory allocation fails.
3896 * @return 0 on success.
3897 */
3898static int Pkcs11ECDSA_Verify(Pkcs11Session* session, wc_CryptoInfo* info)
3899{
3900 int ret = 0;
3901 int sessionKey = 0;
3902 CK_RV rv;
3903 CK_MECHANISM mech;
3904 CK_MECHANISM_INFO mechInfo;
3905 CK_OBJECT_HANDLE publicKey = NULL_PTR;
3906 unsigned char* sig = NULL;
3907 ecc_key* key = info->pk.eccverify.key;
3908 word32 sz = key->dp->size;
3909
3910 /* Check operation is supported. */
3911 ret = Pkcs11MechAvail(session, CKM_ECDSA, &mechInfo);
3912 if (ret == 0 && (mechInfo.flags & CKF_VERIFY) == 0) {
3913 ret = NOT_COMPILED_IN;
3914 }
3915 if (ret == 0 && info->pk.eccverify.res == NULL) {
3916 ret = BAD_FUNC_ARG;
3917 }
3918
3919 if (ret == 0) {
3920 WOLFSSL_MSG("PKCS#11: EC Verification Operation");
3921
3922 if (key->labelLen > 0) {
3923 ret = Pkcs11FindKeyByLabel(&publicKey, CKO_PUBLIC_KEY, CKK_EC,
3924 session, key->label, key->labelLen);
3925 if (ret == 0 && key->dp == NULL) {
3926 ret = Pkcs11GetEccParams(session, publicKey, key);
3927 }
3928 }
3929 else if (key->idLen > 0) {
3930 ret = Pkcs11FindKeyById(&publicKey, CKO_PUBLIC_KEY, CKK_EC,
3931 session, key->id, key->idLen);
3932 if (ret == 0 && key->dp == NULL) {
3933 ret = Pkcs11GetEccParams(session, publicKey, key);
3934 }
3935 }
3936 else if (!mp_iszero(key->pubkey.x)) {
3937 ret = Pkcs11CreateEccPublicKey(&publicKey, session, key,
3938 CKA_VERIFY);
3939 sessionKey = 1;
3940 }
3941 else
3942 ret = Pkcs11FindEccKey(&publicKey, CKO_PUBLIC_KEY, session,
3943 info->pk.eccsign.key, CKA_VERIFY);
3944 }
3945
3946 if (ret == 0) {
3947 sig = (unsigned char *)XMALLOC(sz * 2, key->heap,
3948 DYNAMIC_TYPE_TMP_BUFFER);
3949 if (sig == NULL)
3950 ret = MEMORY_E;
3951 }
3952
3953 if (ret == 0) {
3954 ret = Pkcs11ECDSASig_Decode(info->pk.eccverify.sig,
3955 info->pk.eccverify.siglen, sig, sz);
3956 }
3957 if (ret == 0) {
3958 mech.mechanism = CKM_ECDSA;
3959 mech.ulParameterLen = 0;
3960 mech.pParameter = NULL;
3961
3962 rv = session->func->C_VerifyInit(session->handle, &mech, publicKey);
3963 PKCS11_RV("C_VerifyInit", rv);
3964 if (rv != CKR_OK) {
3965 ret = WC_HW_E;
3966 }
3967 }
3968
3969 if (ret == 0) {
3970 *info->pk.eccverify.res = 0;
3971 rv = session->func->C_Verify(session->handle,
3972 (CK_BYTE_PTR)info->pk.eccverify.hash,
3973 info->pk.eccverify.hashlen,
3974 (CK_BYTE_PTR)sig, sz * 2);
3975 PKCS11_RV("C_Verify", rv);
3976 if (rv == CKR_SIGNATURE_INVALID) {
3977 }
3978 else if (rv != CKR_OK)
3979 ret = WC_HW_E;
3980 else
3981 *info->pk.eccverify.res = 1;
3982 }
3983
3984 if (sessionKey && publicKey != NULL_PTR)
3985 session->func->C_DestroyObject(session->handle, publicKey);
3986
3987 if (sig != NULL)
3988 XFREE(sig, info->pk.eccverify.key->heap, DYNAMIC_TYPE_TMP_BUFFER);
3989
3990 return ret;
3991}
3992#endif
3993
3994#ifndef NO_RSA
3995/**
3996 * Check the private RSA key matches the public key.
3997 *
3998 * @param [in] priv RSA private key.
3999 * @param [in] publicKey Encoded RSA public key.
4000 * @param [in] pubKeySize Length of encoded RSA public key.
4001 * @return MEMORY_E when a memory allocation fails.
4002 * @return MP_CMP_E when the public parts are different.
4003 * @return 0 on success.
4004 */
4005static int wc_Pkcs11CheckPrivKey_Rsa(RsaKey* priv,
4006 const unsigned char* publicKey, word32 pubKeySize)
4007{
4008 int ret = 0;
4009 WC_DECLARE_VAR(pub, RsaKey, 1, 0);
4010 word32 keyIdx = 0;
4011
4012 WC_ALLOC_VAR_EX(pub, RsaKey, 1, NULL, DYNAMIC_TYPE_RSA,
4013 ret=MEMORY_E);
4014
4015 if ((ret == 0) && (ret = wc_InitRsaKey(pub, NULL)) == 0) {
4016 if (ret == 0) {
4017 ret = wc_RsaPublicKeyDecode(publicKey, &keyIdx, pub, pubKeySize);
4018 }
4019 if (ret == 0) {
4020 /* both keys extracted successfully now check n and e
4021 * values are the same. This is dereferencing RsaKey */
4022 if (mp_cmp(&(priv->n), &(pub->n)) != MP_EQ ||
4023 mp_cmp(&(priv->e), &(pub->e)) != MP_EQ) {
4024 ret = MP_CMP_E;
4025 }
4026 else
4027 ret = 0;
4028 }
4029 wc_FreeRsaKey(pub);
4030 }
4031 WC_FREE_VAR_EX(pub, NULL, DYNAMIC_TYPE_RSA);
4032
4033 return ret;
4034}
4035
4036/**
4037 * Checks the RSA private key matches the RSA public key.
4038 *
4039 * @param [in] session Session object.
4040 * @param [in] info Cryptographic operation data.
4041 * @return WC_HW_E when a PKCS#11 library call fails.
4042 * @return MEMORY_E when a memory allocation fails.
4043 * @return MP_CMP_E when the public parts are different.
4044 * @return 0 on success.
4045 */
4046static int Pkcs11RsaCheckPrivKey(Pkcs11Session* session, wc_CryptoInfo* info)
4047{
4048 int ret = 0;
4049 CK_OBJECT_HANDLE privateKey;
4050 RsaKey* priv = info->pk.rsa_check.key;
4051
4052 if (mp_iszero(&priv->n) || mp_iszero(&priv->e)) {
4053 /* Get the RSA private key object. */
4054 if (priv->labelLen > 0) {
4055 ret = Pkcs11FindKeyByLabel(&privateKey, CKO_PRIVATE_KEY,
4056 CKK_RSA, session, priv->label,
4057 priv->labelLen);
4058 }
4059 else if (priv->idLen > 0) {
4060 ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_RSA,
4061 session, priv->id, priv->idLen);
4062 }
4063 else {
4064 ret = Pkcs11FindRsaKey(&privateKey, CKO_PRIVATE_KEY, session, priv);
4065 }
4066
4067 if (ret == 0) {
4068 /* Extract the public key components. */
4069 ret = Pkcs11GetRsaPublicKey(priv, session, privateKey);
4070 }
4071 }
4072 if (ret == 0) {
4073 /* Compare the extracted public parts with the public key. */
4074 ret = wc_Pkcs11CheckPrivKey_Rsa(priv, info->pk.rsa_check.pubKey,
4075 info->pk.rsa_check.pubKeySz);
4076 }
4077
4078 return ret;
4079}
4080
4081/**
4082 * Get the size of the RSA key in bytes.
4083 *
4084 * @param [in] session Session object.
4085 * @param [in] info Cryptographic operation data.
4086 * @return WC_HW_E when a PKCS#11 library call fails.
4087 * @return NOT_COMPILED_IN when no modulus, label or id.
4088 * @return 0 on success.
4089 */
4090static int Pkcs11RsaGetSize(Pkcs11Session* session, wc_CryptoInfo* info)
4091{
4092 int ret = 0;
4093 CK_OBJECT_HANDLE privateKey;
4094 const RsaKey* priv = info->pk.rsa_get_size.key;
4095
4096 if (!mp_iszero(&priv->n)) {
4097 /* Use the key's modulus MP integer to determine size. */
4098 *info->pk.rsa_get_size.keySize = mp_unsigned_bin_size(&priv->n);
4099 }
4100 else {
4101 /* Get the RSA private key object. */
4102 if (priv->labelLen > 0) {
4103 ret = Pkcs11FindKeyByLabel(&privateKey, CKO_PRIVATE_KEY,
4104 CKK_RSA, session, (char*)priv->label,
4105 priv->labelLen);
4106 }
4107 else if (priv->idLen > 0) {
4108 ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_RSA,
4109 session, (unsigned char*)priv->id,
4110 priv->idLen);
4111 }
4112 else {
4113 /* Lookup is by modulus which is not present. */
4114 ret = NOT_COMPILED_IN;
4115 }
4116
4117 if (ret == 0) {
4118 /* Lookup the modulus size in bytes. */
4119 ret = Pkcs11GetRsaModulusSize(session, privateKey,
4120 info->pk.rsa_get_size.keySize);
4121 }
4122 }
4123
4124 return ret;
4125}
4126#endif
4127
4128#ifdef HAVE_ECC
4129/**
4130 * Check the private ECC key matches the public key.
4131 * Do this by looking up the public key data from the associated public key.
4132 * The public key object handle is passed in for the private key.
4133 *
4134 * @param [in] privateKey Handle to private key object.
4135 * @param [in] publicKey Encoded EC public key.
4136 * @param [in] pubKeySize Length of encoded EC public key.
4137 * @return MEMORY_E when a memory allocation fails.
4138 * @return MP_CMP_E when the public parts are different.
4139 * @return 0 on success.
4140 */
4141static int wc_Pkcs11CheckPrivKey_Ecc(ecc_key* priv,
4142 const unsigned char* publicKey, word32 pubKeySize)
4143{
4144 int ret = 0;
4145 WC_DECLARE_VAR(pub, ecc_key, 1, 0);
4146 word32 keyIdx = 0;
4147
4148 WC_ALLOC_VAR_EX(pub, ecc_key, 1, NULL, DYNAMIC_TYPE_ECC,
4149 ret=MEMORY_E);
4150
4151 if ((ret == 0) && (ret = wc_ecc_init(pub)) == 0) {
4152 ret = wc_EccPublicKeyDecode(publicKey, &keyIdx, pub, pubKeySize);
4153 if (ret == 0) {
4154 /* both keys extracted successfully now check curve and
4155 * pubkey. */
4156 if ((pub->idx != priv->idx) || (wc_ecc_cmp_point(&priv->pubkey,
4157 &pub->pubkey) != MP_EQ)) {
4158 ret = MP_CMP_E;
4159 }
4160 else {
4161 ret = 0;
4162 }
4163 }
4164 wc_ecc_free(pub);
4165 }
4166 WC_FREE_VAR_EX(pub, NULL, DYNAMIC_TYPE_ECC);
4167
4168 return ret;
4169}
4170
4171/**
4172 * Checks the ECC private key matches the ECC public key.
4173 *
4174 * @param [in] session Session object.
4175 * @param [in] info Cryptographic operation data.
4176 * @return WC_HW_E when a PKCS#11 library call fails.
4177 * @return MEMORY_E when a memory allocation fails.
4178 * @return MEMORY_E when a memory allocation fails.
4179 * @return MP_CMP_E when the public parts are different.
4180 * @return 0 on success.
4181 */
4182static int Pkcs11EccCheckPrivKey(Pkcs11Session* session, wc_CryptoInfo* info)
4183{
4184 int ret = 0;
4185 ecc_key* priv = info->pk.ecc_check.key;
4186 CK_OBJECT_HANDLE privateKey;
4187
4188 if (mp_iszero(priv->pubkey.x) || mp_iszero(priv->pubkey.y)) {
4189 /* Get the public key object as the private key object doesn't have
4190 * the public point stored in it.
4191 */
4192 if (priv->labelLen > 0) {
4193 ret = Pkcs11FindKeyByLabel(&privateKey, CKO_PUBLIC_KEY, CKK_EC,
4194 session, priv->label, priv->labelLen);
4195 }
4196 else if (priv->idLen > 0) {
4197 ret = Pkcs11FindKeyById(&privateKey, CKO_PUBLIC_KEY, CKK_EC,
4198 session, priv->id, priv->idLen);
4199 }
4200 else {
4201 ret = Pkcs11FindEccKey(&privateKey, CKO_PUBLIC_KEY, session, priv,
4202 CKA_SIGN);
4203 }
4204 if (ret == 0 && priv->dp == NULL) {
4205 /* Extract the group id. */
4206 ret = Pkcs11GetEccParams(session, privateKey, priv);
4207 }
4208 if (ret == 0) {
4209 /* Extract the public point. */
4210 ret = Pkcs11GetEccPublicKey(priv, session, privateKey);
4211 }
4212 }
4213 if (ret == 0) {
4214 /* Compare the extracted public parts with the public key. */
4215 ret = wc_Pkcs11CheckPrivKey_Ecc(priv, info->pk.ecc_check.pubKey,
4216 info->pk.ecc_check.pubKeySz);
4217 }
4218
4219 return ret;
4220}
4221
4222/**
4223 * Deletes the ECC private key.
4224 *
4225 * @param [in] session Session object.
4226 * @param [in] key ECC key.
4227 * @return 0 on success.
4228 */
4229static int Pkcs11EccDeletePrivKey(Pkcs11Session* session, ecc_key* key)
4230{
4231 CK_OBJECT_HANDLE privateKey;
4232
4233 if (key != NULL && key->devCtx != NULL) {
4234 privateKey = (CK_OBJECT_HANDLE)(wc_ptr_t)key->devCtx;
4235
4236 session->func->C_DestroyObject(session->handle, privateKey);
4237
4238 key->devCtx = NULL;
4239 }
4240
4241 return 0;
4242}
4243#endif
4244
4245#ifdef WOLFSSL_HAVE_MLKEM
4246/* Finds the first ML-KEM key matching the key type. */
4247static int Pkcs11FindMlKemKey(CK_OBJECT_HANDLE* handle,
4248 CK_OBJECT_CLASS keyClass,
4249 Pkcs11Session* session,
4250 MlKemKey* key)
4251{
4252 int ret = 0;
4253 CK_ULONG count = 0;
4254 CK_ML_KEM_PARAMETER_SET_TYPE param_set = 0;
4255 CK_ATTRIBUTE keyTemplate[] = {
4256 { CKA_CLASS, &keyClass, sizeof(keyClass) },
4257 { CKA_KEY_TYPE, &mlkemKeyType, sizeof(mlkemKeyType) },
4258 { CKA_PARAMETER_SET, ¶m_set, sizeof(param_set) },
4259 };
4260 CK_ULONG attrCnt =
4261 sizeof(keyTemplate) / sizeof(*keyTemplate);
4262
4263 switch (key->type) {
4264 #ifndef WOLFSSL_NO_ML_KEM
4265 case WC_ML_KEM_512:
4266 param_set = CKP_ML_KEM_512;
4267 break;
4268 case WC_ML_KEM_768:
4269 param_set = CKP_ML_KEM_768;
4270 break;
4271 case WC_ML_KEM_1024:
4272 param_set = CKP_ML_KEM_1024;
4273 break;
4274 default:
4275 ret = NOT_COMPILED_IN;
4276 break;
4277 #else
4278 default:
4279 ret = NOT_COMPILED_IN;
4280 break;
4281 #endif
4282 }
4283 if (ret == 0) {
4284 ret = Pkcs11FindKeyByTemplate(handle, session, keyTemplate, attrCnt,
4285 &count);
4286 }
4287 if (ret == 0 && count == 0) {
4288 ret = WC_HW_E;
4289 }
4290
4291 return ret;
4292}
4293
4294static int Pkcs11GetMlKemPublicKey(MlKemKey* key, Pkcs11Session* session,
4295 CK_OBJECT_HANDLE keyHandle)
4296{
4297 int ret = 0;
4298 CK_ULONG pubKeySize;
4299 CK_ML_KEM_PARAMETER_SET_TYPE paramSet = 0;
4300 unsigned char* pubKey = NULL;
4301 CK_ATTRIBUTE tmpl[] = {
4302 { CKA_VALUE, NULL, 0 },
4303 { CKA_PARAMETER_SET, ¶mSet, sizeof(paramSet) }
4304 };
4305 CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
4306 CK_RV rv;
4307
4308 PKCS11_DUMP_TEMPLATE("Get ML-KEM Public Key Length", tmpl, tmplCnt);
4309 rv = session->func->C_GetAttributeValue(session->handle, keyHandle,
4310 tmpl, tmplCnt);
4311 PKCS11_RV("C_GetAttributeValue", rv);
4312 if (rv != CKR_OK) {
4313 ret = WC_HW_E;
4314 }
4315 PKCS11_DUMP_TEMPLATE("ML-KEM Public Key Length", tmpl, tmplCnt);
4316
4317 if (ret == 0) {
4318 #ifndef WOLFSSL_NO_ML_KEM
4319 switch (paramSet) {
4320 case CKP_ML_KEM_512:
4321 key->type = WC_ML_KEM_512;
4322 break;
4323 case CKP_ML_KEM_768:
4324 key->type = WC_ML_KEM_768;
4325 break;
4326 case CKP_ML_KEM_1024:
4327 key->type = WC_ML_KEM_1024;
4328 break;
4329 default:
4330 ret = WC_KEY_SIZE_E;
4331 break;
4332 }
4333 #else
4334 ret = NOT_COMPILED_IN;
4335 #endif
4336 }
4337 if (ret == 0) {
4338 pubKeySize = tmpl[0].ulValueLen;
4339 pubKey = (unsigned char*)XMALLOC(pubKeySize, key->heap,
4340 DYNAMIC_TYPE_TMP_BUFFER);
4341 if (pubKey == NULL) {
4342 ret = MEMORY_E;
4343 }
4344 }
4345 if (ret == 0) {
4346 tmpl[0].pValue = pubKey;
4347
4348 PKCS11_DUMP_TEMPLATE("Get ML-KEM Public Key", tmpl, tmplCnt);
4349 rv = session->func->C_GetAttributeValue(session->handle, keyHandle,
4350 tmpl, tmplCnt);
4351 PKCS11_RV("C_GetAttributeValue", rv);
4352 if (rv != CKR_OK) {
4353 ret = WC_HW_E;
4354 }
4355 PKCS11_DUMP_TEMPLATE("ML-KEM Public Key", tmpl, tmplCnt);
4356 }
4357 if (ret == 0) {
4358 ret = wc_MlKemKey_DecodePublicKey(key, pubKey, (word32)pubKeySize);
4359 }
4360
4361 XFREE(pubKey, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
4362
4363 return ret;
4364}
4365
4366static int Pkcs11MlKemKeyGen(Pkcs11Session* session, MlKemKey* key)
4367{
4368 int ret = 0;
4369 CK_RV rv;
4370 CK_OBJECT_HANDLE pubKey = NULL_PTR, privKey = NULL_PTR;
4371 CK_MECHANISM mech;
4372 CK_MECHANISM_INFO mechInfo;
4373 CK_ML_KEM_PARAMETER_SET_TYPE param_set = 0;
4374 CK_ULONG pubKeyLen = 0;
4375 CK_ATTRIBUTE pubKeyTmpl[] = {
4376 { CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) },
4377 { CKA_ENCAPSULATE, &ckTrue, sizeof(ckTrue) },
4378 { CKA_KEY_TYPE, &mlkemKeyType, sizeof(mlkemKeyType) },
4379 { CKA_PARAMETER_SET, ¶m_set, sizeof(param_set) },
4380 { 0, NULL, 0 },
4381 { 0, NULL, 0 }
4382 };
4383 CK_ULONG pubTmplCnt =
4384 sizeof(pubKeyTmpl) / sizeof(*pubKeyTmpl) - 2;
4385 CK_ATTRIBUTE privKeyTmpl[] = {
4386 { CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
4387 { CKA_DECAPSULATE, &ckTrue, sizeof(ckTrue) },
4388 { CKA_KEY_TYPE, &mlkemKeyType, sizeof(mlkemKeyType) },
4389 { 0, NULL, 0 },
4390 { 0, NULL, 0 }
4391 };
4392 CK_ULONG privTmplCnt =
4393 sizeof(privKeyTmpl) / sizeof(*privKeyTmpl) - 2;
4394
4395 ret = Pkcs11MechAvail(session, CKM_ML_KEM_KEY_PAIR_GEN, &mechInfo);
4396 if (ret == 0) {
4397 switch (key->type) {
4398 #ifndef WOLFSSL_NO_ML_KEM
4399 case WC_ML_KEM_512:
4400 param_set = CKP_ML_KEM_512;
4401 pubKeyLen = WC_ML_KEM_512_PUBLIC_KEY_SIZE;
4402 break;
4403 case WC_ML_KEM_768:
4404 param_set = CKP_ML_KEM_768;
4405 pubKeyLen = WC_ML_KEM_768_PUBLIC_KEY_SIZE;
4406 break;
4407 case WC_ML_KEM_1024:
4408 param_set = CKP_ML_KEM_1024;
4409 pubKeyLen = WC_ML_KEM_1024_PUBLIC_KEY_SIZE;
4410 break;
4411 default:
4412 ret = NOT_COMPILED_IN;
4413 break;
4414 #else
4415 default:
4416 ret = NOT_COMPILED_IN;
4417 break;
4418 #endif
4419 }
4420 }
4421 if ((ret == 0) &&
4422 ((mechInfo.ulMinKeySize > pubKeyLen) ||
4423 (mechInfo.ulMaxKeySize < pubKeyLen))) {
4424 ret = WC_KEY_SIZE_E;
4425 }
4426 if (ret == 0) {
4427 WOLFSSL_MSG("PKCS#11: ML-KEM Key Generation Operation");
4428
4429 if (key->labelLen != 0) {
4430 privKeyTmpl[privTmplCnt].type = CKA_LABEL;
4431 privKeyTmpl[privTmplCnt].pValue = key->label;
4432 privKeyTmpl[privTmplCnt].ulValueLen = key->labelLen;
4433 privTmplCnt++;
4434
4435 pubKeyTmpl[pubTmplCnt].type = CKA_LABEL;
4436 pubKeyTmpl[pubTmplCnt].pValue = key->label;
4437 pubKeyTmpl[pubTmplCnt].ulValueLen = key->labelLen;
4438 pubTmplCnt++;
4439 }
4440 if (key->idLen != 0) {
4441 privKeyTmpl[privTmplCnt].type = CKA_ID;
4442 privKeyTmpl[privTmplCnt].pValue = key->id;
4443 privKeyTmpl[privTmplCnt].ulValueLen = key->idLen;
4444 privTmplCnt++;
4445
4446 pubKeyTmpl[pubTmplCnt].type = CKA_ID;
4447 pubKeyTmpl[pubTmplCnt].pValue = key->id;
4448 pubKeyTmpl[pubTmplCnt].ulValueLen = key->idLen;
4449 pubTmplCnt++;
4450 }
4451
4452 mech.mechanism = CKM_ML_KEM_KEY_PAIR_GEN;
4453 mech.ulParameterLen = 0;
4454 mech.pParameter = NULL;
4455
4456 PKCS11_DUMP_TEMPLATE("Private Key", privKeyTmpl, privTmplCnt);
4457 PKCS11_DUMP_TEMPLATE("Public Key", pubKeyTmpl, pubTmplCnt);
4458 rv = session->func->C_GenerateKeyPair(session->handle, &mech,
4459 pubKeyTmpl, pubTmplCnt,
4460 privKeyTmpl, privTmplCnt,
4461 &pubKey, &privKey);
4462 PKCS11_RV("C_GenerateKeyPair", rv);
4463 if (rv != CKR_OK) {
4464 ret = WC_HW_E;
4465 }
4466 }
4467 if (ret == 0) {
4468 ret = Pkcs11GetMlKemPublicKey(key, session, pubKey);
4469 }
4470
4471 /* Destroy the public key object, as encapsulation using the public key will
4472 * probably be performed outside of the PKCS#11 token. If not, user can call
4473 * wc_Pkcs11StoreKey() to import the public key to the token. */
4474 if (pubKey != NULL_PTR) {
4475 session->func->C_DestroyObject(session->handle, pubKey);
4476 }
4477 if (ret == 0 && privKey != NULL_PTR) {
4478 key->devCtx = (void*)(wc_ptr_t)privKey;
4479 key->flags |= MLKEM_FLAG_PRIV_SET;
4480 }
4481 else if (ret != 0 && privKey != NULL_PTR) {
4482 session->func->C_DestroyObject(session->handle, privKey);
4483 }
4484
4485 return ret;
4486}
4487
4488static int Pkcs11MlKemEncapsulate(Pkcs11Session* session, wc_CryptoInfo* info)
4489{
4490 int ret = 0;
4491 int sessionKey = 0;
4492 CK_RV rv;
4493 CK_MECHANISM mech;
4494 CK_MECHANISM_INFO mechInfo;
4495 CK_ULONG ctLen;
4496 CK_OBJECT_HANDLE publicKey = NULL_PTR;
4497 CK_OBJECT_HANDLE sharedKey = NULL_PTR;
4498 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
4499 CK_FUNCTION_LIST_3_2_PTR functionList = NULL;
4500 MlKemKey* key = (MlKemKey*)info->pk.pqc_encaps.key;
4501 word32 outLen = WC_ML_KEM_SS_SZ;
4502 CK_ATTRIBUTE sharedKeyTempl[] = {
4503 { CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass) },
4504 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
4505 { CKA_PRIVATE, &ckFalse, sizeof(ckFalse) },
4506 { CKA_SENSITIVE, &ckFalse, sizeof(ckFalse) },
4507 { CKA_EXTRACTABLE, &ckTrue, sizeof(ckTrue) },
4508 };
4509 CK_ULONG sharedKeyTmplCnt =
4510 sizeof(sharedKeyTempl) / sizeof(*sharedKeyTempl);
4511
4512 if (session->version >= WC_PCKS11VERSION_3_2) {
4513 functionList = (CK_FUNCTION_LIST_3_2_PTR)session->func;
4514 }
4515 else {
4516 return NOT_COMPILED_IN;
4517 }
4518
4519 ret = Pkcs11MechAvail(session, CKM_ML_KEM, &mechInfo);
4520 if (ret == 0 && (mechInfo.flags & CKF_ENCAPSULATE) == 0) {
4521 ret = NOT_COMPILED_IN;
4522 }
4523 if (ret == 0 && info->pk.pqc_encaps.sharedSecret == NULL) {
4524 ret = BAD_FUNC_ARG;
4525 }
4526 if (ret == 0 && info->pk.pqc_encaps.ciphertext == NULL) {
4527 ret = BAD_FUNC_ARG;
4528 }
4529 if (ret == 0) {
4530 WOLFSSL_MSG("PKCS#11: ML-KEM Encapsulation Operation");
4531
4532 if (key->labelLen > 0) {
4533 ret = Pkcs11FindKeyByLabel(&publicKey, CKO_PUBLIC_KEY, CKK_ML_KEM,
4534 session, key->label, key->labelLen);
4535 }
4536 else if (key->idLen > 0) {
4537 ret = Pkcs11FindKeyById(&publicKey, CKO_PUBLIC_KEY, CKK_ML_KEM,
4538 session, key->id, key->idLen);
4539 }
4540 else if ((key->flags & MLKEM_FLAG_PUB_SET) != 0) {
4541 ret = Pkcs11CreateMlKemPublicKey(&publicKey, session, key,
4542 &mechInfo);
4543 sessionKey = 1;
4544 }
4545 else {
4546 /* Fallback: find the first ML-KEM key matching the key type. */
4547 ret = Pkcs11FindMlKemKey(&publicKey, CKO_PUBLIC_KEY, session, key);
4548 }
4549 }
4550 if (ret == 0) {
4551 mech.mechanism = CKM_ML_KEM;
4552 mech.ulParameterLen = 0;
4553 mech.pParameter = NULL;
4554 ctLen = info->pk.pqc_encaps.ciphertextLen;
4555
4556 rv = functionList->C_EncapsulateKey(session->handle, &mech, publicKey,
4557 sharedKeyTempl, sharedKeyTmplCnt,
4558 (CK_BYTE_PTR)
4559 info->pk.pqc_encaps.ciphertext,
4560 &ctLen,
4561 &sharedKey);
4562 PKCS11_RV("C_EncapsulateKey", rv);
4563 if (rv != CKR_OK ||
4564 (word32)ctLen != info->pk.pqc_encaps.ciphertextLen) {
4565 ret = WC_HW_E;
4566 }
4567 }
4568 if (ret == 0) {
4569 outLen = info->pk.pqc_encaps.sharedSecretLen;
4570 ret = Pkcs11ExtractSecret(session, sharedKey,
4571 info->pk.pqc_encaps.sharedSecret, &outLen);
4572 if (ret == 0 && outLen != info->pk.pqc_encaps.sharedSecretLen) {
4573 ret = WC_HW_E;
4574 }
4575 }
4576
4577 if (sessionKey && publicKey != NULL_PTR) {
4578 session->func->C_DestroyObject(session->handle, publicKey);
4579 }
4580 if (sharedKey != NULL_PTR) {
4581 session->func->C_DestroyObject(session->handle, sharedKey);
4582 }
4583
4584 return ret;
4585}
4586
4587static int Pkcs11MlKemDecapsulate(Pkcs11Session* session, wc_CryptoInfo* info)
4588{
4589 int ret = 0;
4590 int sessionKey = 0;
4591 CK_RV rv;
4592 CK_MECHANISM mech;
4593 CK_MECHANISM_INFO mechInfo;
4594 CK_OBJECT_HANDLE privateKey = NULL_PTR;
4595 CK_OBJECT_HANDLE sharedKey = NULL_PTR;
4596 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
4597 CK_FUNCTION_LIST_3_2_PTR functionList = NULL;
4598 MlKemKey* key = (MlKemKey*)info->pk.pqc_decaps.key;
4599 word32 outLen = WC_ML_KEM_SS_SZ;
4600 CK_ATTRIBUTE sharedKeyTempl[] = {
4601 { CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass) },
4602 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
4603 { CKA_PRIVATE, &ckFalse, sizeof(ckFalse) },
4604 { CKA_SENSITIVE, &ckFalse, sizeof(ckFalse) },
4605 { CKA_EXTRACTABLE, &ckTrue, sizeof(ckTrue) },
4606 };
4607 CK_ULONG sharedKeyTmplCnt =
4608 sizeof(sharedKeyTempl) / sizeof(*sharedKeyTempl);
4609
4610 if (session->version >= WC_PCKS11VERSION_3_2) {
4611 functionList = (CK_FUNCTION_LIST_3_2_PTR)session->func;
4612 }
4613 else {
4614 return NOT_COMPILED_IN;
4615 }
4616
4617 ret = Pkcs11MechAvail(session, CKM_ML_KEM, &mechInfo);
4618 if (ret == 0 && (mechInfo.flags & CKF_DECAPSULATE) == 0) {
4619 ret = NOT_COMPILED_IN;
4620 }
4621 if (ret == 0 && info->pk.pqc_decaps.sharedSecret == NULL) {
4622 ret = BAD_FUNC_ARG;
4623 }
4624 if (ret == 0 && info->pk.pqc_decaps.ciphertext == NULL) {
4625 ret = BAD_FUNC_ARG;
4626 }
4627 if (ret == 0) {
4628 WOLFSSL_MSG("PKCS#11: ML-KEM Decapsulation Operation");
4629
4630 if (key->devCtx != NULL) {
4631 privateKey = (CK_OBJECT_HANDLE)(wc_ptr_t)key->devCtx;
4632 }
4633 else if (key->labelLen > 0) {
4634 ret = Pkcs11FindKeyByLabel(&privateKey, CKO_PRIVATE_KEY,
4635 CKK_ML_KEM, session,
4636 key->label, key->labelLen);
4637 }
4638 else if (key->idLen > 0) {
4639 ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_ML_KEM,
4640 session, key->id, key->idLen);
4641 }
4642 else if ((key->flags & MLKEM_FLAG_PRIV_SET) != 0) {
4643 ret = Pkcs11CreateMlKemPrivateKey(&privateKey, session, key,
4644 &mechInfo);
4645 sessionKey = 1;
4646 }
4647 else {
4648 /* Fallback: find the first ML-KEM key matching the key type. */
4649 ret = Pkcs11FindMlKemKey(&privateKey, CKO_PRIVATE_KEY, session,
4650 key);
4651 }
4652 }
4653 if (ret == 0) {
4654 mech.mechanism = CKM_ML_KEM;
4655 mech.ulParameterLen = 0;
4656 mech.pParameter = NULL;
4657
4658 rv = functionList->C_DecapsulateKey(session->handle, &mech, privateKey,
4659 sharedKeyTempl, sharedKeyTmplCnt,
4660 (CK_BYTE_PTR)
4661 info->pk.pqc_decaps.ciphertext,
4662 info->pk.pqc_decaps.ciphertextLen,
4663 &sharedKey);
4664 PKCS11_RV("C_DecapsulateKey", rv);
4665 if (rv != CKR_OK) {
4666 ret = WC_HW_E;
4667 }
4668 }
4669 if (ret == 0) {
4670 outLen = info->pk.pqc_decaps.sharedSecretLen;
4671 ret = Pkcs11ExtractSecret(session, sharedKey,
4672 info->pk.pqc_decaps.sharedSecret, &outLen);
4673 if (ret == 0 && outLen != info->pk.pqc_decaps.sharedSecretLen) {
4674 ret = WC_HW_E;
4675 }
4676 }
4677
4678 if (sessionKey && privateKey != NULL_PTR) {
4679 session->func->C_DestroyObject(session->handle, privateKey);
4680 }
4681 if (sharedKey != NULL_PTR) {
4682 session->func->C_DestroyObject(session->handle, sharedKey);
4683 }
4684
4685 return ret;
4686}
4687
4688static int Pkcs11MlKemDeletePrivKey(Pkcs11Session* session, MlKemKey* key)
4689{
4690 CK_OBJECT_HANDLE privateKey;
4691
4692 if (key != NULL && key->devCtx != NULL) {
4693 privateKey = (CK_OBJECT_HANDLE)(wc_ptr_t)key->devCtx;
4694 session->func->C_DestroyObject(session->handle, privateKey);
4695 key->devCtx = NULL;
4696 }
4697
4698 return 0;
4699}
4700
4701static int Pkcs11PqcKemKeyGen(Pkcs11Session* session, wc_CryptoInfo* info)
4702{
4703 int ret = 0;
4704
4705 switch (info->pk.pqc_kem_kg.type) {
4706 case WC_PQC_KEM_TYPE_KYBER:
4707 ret = Pkcs11MlKemKeyGen(session,
4708 (MlKemKey*)info->pk.pqc_kem_kg.key);
4709 break;
4710 default:
4711 ret = NOT_COMPILED_IN;
4712 break;
4713 }
4714
4715 return ret;
4716}
4717
4718static int Pkcs11PqcKemEncapsulate(Pkcs11Session* session, wc_CryptoInfo* info)
4719{
4720 int ret = 0;
4721
4722 switch (info->pk.pqc_encaps.type) {
4723 case WC_PQC_KEM_TYPE_KYBER:
4724 ret = Pkcs11MlKemEncapsulate(session, info);
4725 break;
4726 default:
4727 ret = NOT_COMPILED_IN;
4728 break;
4729 }
4730
4731 return ret;
4732}
4733
4734static int Pkcs11PqcKemDecapsulate(Pkcs11Session* session, wc_CryptoInfo* info)
4735{
4736 int ret = 0;
4737
4738 switch (info->pk.pqc_decaps.type) {
4739 case WC_PQC_KEM_TYPE_KYBER:
4740 ret = Pkcs11MlKemDecapsulate(session, info);
4741 break;
4742 default:
4743 ret = NOT_COMPILED_IN;
4744 break;
4745 }
4746
4747 return ret;
4748}
4749#endif /* WOLFSSL_HAVE_MLKEM */
4750
4751#if defined(HAVE_DILITHIUM)
4752/**
4753 * Find the PKCS#11 object containing the ML-DSA public or private key data.
4754 *
4755 * @param handle [out] Handle to key object.
4756 * @param keyClass [in] Public or private key class.
4757 * @param session [in] Session object.
4758 * @param key [in] ML-DSA key.
4759 * @return WC_HW_E when a PKCS#11 library call fails.
4760 * @return MEMORY_E when a memory allocation fails.
4761 * @return 0 on success.
4762 */
4763static int Pkcs11FindMldsaKey(CK_OBJECT_HANDLE* handle,
4764 CK_OBJECT_CLASS keyClass,
4765 Pkcs11Session* session,
4766 MlDsaKey* key)
4767{
4768 int ret = 0;
4769 CK_ULONG count = 0;
4770 CK_ML_DSA_PARAMETER_SET_TYPE param_set = 0;
4771 CK_ATTRIBUTE keyTemplate[] = {
4772 { CKA_CLASS, &keyClass, sizeof(keyClass) },
4773 { CKA_KEY_TYPE, &mldsaKeyType, sizeof(mldsaKeyType) },
4774 { CKA_PARAMETER_SET, ¶m_set, sizeof(param_set) },
4775 };
4776 CK_ULONG attrCnt = sizeof(keyTemplate) / sizeof(*keyTemplate);
4777
4778 if (key->level == WC_ML_DSA_44) {
4779 param_set = CKP_ML_DSA_44;
4780 }
4781 else if (key->level == WC_ML_DSA_65) {
4782 param_set = CKP_ML_DSA_65;
4783 }
4784 else if (key->level == WC_ML_DSA_87) {
4785 param_set = CKP_ML_DSA_87;
4786 }
4787 else {
4788 ret = NOT_COMPILED_IN;
4789 }
4790
4791 if (ret == 0) {
4792 ret = Pkcs11FindKeyByTemplate(handle, session, keyTemplate,
4793 attrCnt, &count);
4794 }
4795 if (ret == 0 && count == 0) {
4796 ret = WC_HW_E;
4797 }
4798
4799 return ret;
4800}
4801
4802/**
4803 * Gets the public key data from the PKCS#11 object and puts into the ML-DSA
4804 * key.
4805 *
4806 * @param key [in] ML-DSA key.
4807 * @param session [in] Session object.
4808 * @param keyHandle [in] ML-DSA public key PKCS#11 object handle.
4809 * @return WC_HW_E when a PKCS#11 library call fails.
4810 * @return MEMORY_E when a memory allocation fails.
4811 * @return 0 on success.
4812 */
4813static int Pkcs11GetMldsaPublicKey(MlDsaKey* key,
4814 Pkcs11Session* session,
4815 CK_OBJECT_HANDLE keyHandle)
4816{
4817 int ret = 0;
4818 CK_ULONG pubKeySize;
4819 unsigned char* pubKey = NULL;
4820 CK_ATTRIBUTE tmpl[] = {
4821 { CKA_VALUE, NULL, 0 }
4822 };
4823 CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
4824 CK_RV rv;
4825
4826 PKCS11_DUMP_TEMPLATE("Get ML-DSA Public Key Length", tmpl, tmplCnt);
4827 rv = session->func->C_GetAttributeValue(session->handle, keyHandle,
4828 tmpl, tmplCnt);
4829 PKCS11_RV("C_GetAttributeValue", rv);
4830 if (rv != CKR_OK) {
4831 ret = WC_HW_E;
4832 }
4833 PKCS11_DUMP_TEMPLATE("ML-DSA Public Key Length", tmpl, tmplCnt);
4834
4835 if (ret == 0) {
4836 pubKeySize = tmpl[0].ulValueLen;
4837 pubKey = (unsigned char*)XMALLOC(pubKeySize, key->heap,
4838 DYNAMIC_TYPE_TMP_BUFFER);
4839 if (pubKey == NULL)
4840 ret = MEMORY_E;
4841 }
4842 if (ret == 0) {
4843 tmpl[0].pValue = pubKey;
4844
4845 PKCS11_DUMP_TEMPLATE("Get ML-DSA Public Key", tmpl, tmplCnt);
4846 rv = session->func->C_GetAttributeValue(session->handle, keyHandle,
4847 tmpl, tmplCnt);
4848 PKCS11_RV("C_GetAttributeValue", rv);
4849 if (rv != CKR_OK) {
4850 ret = WC_HW_E;
4851 }
4852 PKCS11_DUMP_TEMPLATE("ML-DSA Public Key", tmpl, tmplCnt);
4853 }
4854 if (ret == 0) {
4855 if (pubKeySize == ML_DSA_LEVEL2_PUB_KEY_SIZE)
4856 wc_MlDsaKey_SetParams(key, WC_ML_DSA_44);
4857 else if (pubKeySize == ML_DSA_LEVEL3_PUB_KEY_SIZE)
4858 wc_MlDsaKey_SetParams(key, WC_ML_DSA_65);
4859 else if (pubKeySize == ML_DSA_LEVEL5_PUB_KEY_SIZE)
4860 wc_MlDsaKey_SetParams(key, WC_ML_DSA_87);
4861 else
4862 ret = WC_KEY_SIZE_E;
4863 }
4864 if (ret == 0)
4865 ret = wc_MlDsaKey_ImportPubRaw(key, pubKey, pubKeySize);
4866
4867 if (pubKey != NULL)
4868 XFREE(pubKey, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
4869
4870 return ret;
4871}
4872
4873/**
4874 * Convert the wolfCrypt hash type to a digest mechanism.
4875 *
4876 * @param hashType [in] Hash type.
4877 * @param hashMech [out] Pointer to digest mechanism.
4878
4879 * @return BAD_FUNC_ARG when the hash type is not recognized.
4880 * 0 on success.
4881 */
4882static int Pkcs11GetMldsaPreHash(int hashType,
4883 CK_MECHANISM_TYPE_PTR hashMech)
4884{
4885 int ret = 0;
4886
4887 if (hashMech == NULL) {
4888 return BAD_FUNC_ARG;
4889 }
4890
4891 switch (hashType) {
4892 case WC_HASH_TYPE_SHA256:
4893 *hashMech = CKM_SHA256;
4894 break;
4895 case WC_HASH_TYPE_SHA384:
4896 *hashMech = CKM_SHA384;
4897 break;
4898 case WC_HASH_TYPE_SHA512:
4899 *hashMech = CKM_SHA512;
4900 break;
4901 #ifndef WOLFSSL_NOSHA512_256
4902 case WC_HASH_TYPE_SHA512_256:
4903 *hashMech = CKM_SHA512_256;
4904 break;
4905 #endif
4906 case WC_HASH_TYPE_SHA3_256:
4907 *hashMech = CKM_SHA3_256;
4908 break;
4909 case WC_HASH_TYPE_SHA3_384:
4910 *hashMech = CKM_SHA3_384;
4911 break;
4912 case WC_HASH_TYPE_SHA3_512:
4913 *hashMech = CKM_SHA3_512;
4914 break;
4915 default:
4916 ret = BAD_FUNC_ARG;
4917 break;
4918 }
4919
4920 return ret;
4921}
4922
4923/**
4924 * Perform an ML-DSA key generation operation.
4925 * The private key data stays on the device.
4926 *
4927 * @param [in] session Session object.
4928 * @param [in] key ML-DSA key. Already configured with the desired
4929 * level and parameters.
4930 * @return WC_HW_E when a PKCS#11 library call fails.
4931 * @return 0 on success.
4932 */
4933static int Pkcs11MldsaKeyGen(Pkcs11Session* session, MlDsaKey* key)
4934{
4935 int ret = 0;
4936 CK_RV rv;
4937 CK_OBJECT_HANDLE pubKey = NULL_PTR, privKey = NULL_PTR;
4938 CK_MECHANISM mech;
4939 CK_MECHANISM_INFO mechInfo;
4940 CK_ML_DSA_PARAMETER_SET_TYPE param_set = 0;
4941
4942 /* Empty entries for optional label/ID. */
4943 CK_ATTRIBUTE pubKeyTmpl[] = {
4944 { CKA_CLASS, &pubKeyClass, sizeof(pubKeyClass) },
4945 { CKA_VERIFY, &ckTrue, sizeof(ckTrue) },
4946 { CKA_KEY_TYPE, &mldsaKeyType, sizeof(mldsaKeyType) },
4947 { CKA_PARAMETER_SET, ¶m_set, sizeof(param_set) },
4948 { 0, NULL, 0 },
4949 { 0, NULL, 0 }
4950 };
4951 /* Mandatory entries + 2 optional. */
4952 CK_ULONG pubTmplCnt = sizeof(pubKeyTmpl)/sizeof(*pubKeyTmpl) - 2;
4953
4954 /* Empty entries for optional label/ID. */
4955 CK_ATTRIBUTE privKeyTmpl[] = {
4956 { CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
4957 { CKA_SIGN, &ckTrue, sizeof(ckTrue) },
4958 { CKA_KEY_TYPE, &mldsaKeyType, sizeof(mldsaKeyType) },
4959 { 0, NULL, 0 },
4960 { 0, NULL, 0 }
4961 };
4962 /* Mandatory entries + 2 optional. */
4963 CK_ULONG privTmplCnt = sizeof(privKeyTmpl)/sizeof(*privKeyTmpl) - 2;
4964
4965 ret = Pkcs11MechAvail(session, CKM_ML_DSA_KEY_PAIR_GEN, &mechInfo);
4966 if (ret == 0) {
4967 if ((key->level == WC_ML_DSA_44) &&
4968 (mechInfo.ulMinKeySize <= ML_DSA_LEVEL2_PUB_KEY_SIZE) &&
4969 (mechInfo.ulMaxKeySize >= ML_DSA_LEVEL2_PUB_KEY_SIZE)) {
4970 param_set = CKP_ML_DSA_44;
4971 }
4972 else if ((key->level == WC_ML_DSA_65) &&
4973 (mechInfo.ulMinKeySize <= ML_DSA_LEVEL3_PUB_KEY_SIZE) &&
4974 (mechInfo.ulMaxKeySize >= ML_DSA_LEVEL3_PUB_KEY_SIZE)) {
4975 param_set = CKP_ML_DSA_65;
4976 }
4977 else if ((key->level == WC_ML_DSA_87) &&
4978 (mechInfo.ulMinKeySize <= ML_DSA_LEVEL5_PUB_KEY_SIZE) &&
4979 (mechInfo.ulMaxKeySize >= ML_DSA_LEVEL5_PUB_KEY_SIZE)) {
4980 param_set = CKP_ML_DSA_87;
4981 }
4982 else {
4983 ret = WC_KEY_SIZE_E;
4984 }
4985 }
4986 if (ret == 0) {
4987 WOLFSSL_MSG("PKCS#11: ML-DSA Key Generation Operation");
4988
4989 if (key->labelLen != 0) {
4990 privKeyTmpl[privTmplCnt].type = CKA_LABEL;
4991 privKeyTmpl[privTmplCnt].pValue = key->label;
4992 privKeyTmpl[privTmplCnt].ulValueLen = key->labelLen;
4993 privTmplCnt++;
4994
4995 pubKeyTmpl[pubTmplCnt].type = CKA_LABEL;
4996 pubKeyTmpl[pubTmplCnt].pValue = key->label;
4997 pubKeyTmpl[pubTmplCnt].ulValueLen = key->labelLen;
4998 pubTmplCnt++;
4999 }
5000 if (key->idLen != 0) {
5001 privKeyTmpl[privTmplCnt].type = CKA_ID;
5002 privKeyTmpl[privTmplCnt].pValue = key->id;
5003 privKeyTmpl[privTmplCnt].ulValueLen = key->idLen;
5004 privTmplCnt++;
5005
5006 pubKeyTmpl[pubTmplCnt].type = CKA_ID;
5007 pubKeyTmpl[pubTmplCnt].pValue = key->id;
5008 pubKeyTmpl[pubTmplCnt].ulValueLen = key->idLen;
5009 pubTmplCnt++;
5010 }
5011
5012 mech.mechanism = CKM_ML_DSA_KEY_PAIR_GEN;
5013 mech.ulParameterLen = 0;
5014 mech.pParameter = NULL;
5015
5016 PKCS11_DUMP_TEMPLATE("Private Key", privKeyTmpl, privTmplCnt);
5017 PKCS11_DUMP_TEMPLATE("Public Key", pubKeyTmpl, pubTmplCnt);
5018
5019 rv = session->func->C_GenerateKeyPair(session->handle, &mech,
5020 pubKeyTmpl, pubTmplCnt,
5021 privKeyTmpl, privTmplCnt,
5022 &pubKey, &privKey);
5023 PKCS11_RV("C_GenerateKeyPair", rv);
5024 if (rv != CKR_OK) {
5025 ret = WC_HW_E;
5026 }
5027 }
5028
5029 if (ret == 0)
5030 ret = Pkcs11GetMldsaPublicKey(key, session, pubKey);
5031
5032 if (pubKey != NULL_PTR)
5033 session->func->C_DestroyObject(session->handle, pubKey);
5034 if (ret == 0 && privKey != NULL_PTR) {
5035 key->devCtx = (void*)(wc_ptr_t)privKey;
5036 }
5037 else if (ret != 0 && privKey != NULL_PTR)
5038 session->func->C_DestroyObject(session->handle, privKey);
5039
5040 return ret;
5041}
5042
5043/**
5044 * Performs the ML-DSA signing operation.
5045 *
5046 * @param session [in] Session object.
5047 * @param info [in] Cryptographic operation data.
5048 * @return WC_HW_E when a PKCS#11 library call fails.
5049 * @return 0 on success.
5050 */
5051static int Pkcs11MldsaSign(Pkcs11Session* session, wc_CryptoInfo* info)
5052{
5053 int ret = 0;
5054 int sessionKey = 0;
5055 CK_RV rv;
5056 CK_ULONG outLen;
5057 CK_MECHANISM mech;
5058 CK_MECHANISM_INFO mechInfo;
5059 CK_OBJECT_HANDLE privateKey = NULL_PTR;
5060 MlDsaKey* key = (MlDsaKey*) info->pk.pqc_sign.key;
5061
5062 union {
5063 CK_SIGN_ADDITIONAL_CONTEXT pure;
5064 CK_HASH_SIGN_ADDITIONAL_CONTEXT preHash;
5065 } paramSet;
5066 XMEMSET(¶mSet, 0, sizeof(paramSet));
5067
5068 /* Check operation is supported. */
5069 if (info->pk.pqc_sign.preHashType != WC_HASH_TYPE_NONE) {
5070 ret = Pkcs11MechAvail(session, CKM_HASH_ML_DSA, &mechInfo);
5071 }
5072 else {
5073 ret = Pkcs11MechAvail(session, CKM_ML_DSA, &mechInfo);
5074 }
5075 if (ret == 0 && (mechInfo.flags & CKF_SIGN) == 0) {
5076 ret = NOT_COMPILED_IN;
5077 }
5078 if (ret == 0 && info->pk.pqc_sign.outlen == NULL) {
5079 ret = BAD_FUNC_ARG;
5080 }
5081 if (ret == 0 && info->pk.pqc_sign.out == NULL) {
5082 ret = BAD_FUNC_ARG;
5083 }
5084 if (ret == 0) {
5085 WOLFSSL_MSG("PKCS#11: ML-DSA Signing Operation");
5086
5087 if (key->devCtx != NULL) {
5088 privateKey = (CK_OBJECT_HANDLE)(wc_ptr_t)key->devCtx;
5089 }
5090 else if ((sessionKey = key->prvKeySet))
5091 ret = Pkcs11CreateMldsaPrivateKey(&privateKey, session,
5092 key, &mechInfo);
5093 else if (key->labelLen > 0) {
5094 ret = Pkcs11FindKeyByLabel(&privateKey, CKO_PRIVATE_KEY, CKK_ML_DSA,
5095 session, key->label, key->labelLen);
5096 }
5097 else if (key->idLen > 0) {
5098 ret = Pkcs11FindKeyById(&privateKey, CKO_PRIVATE_KEY, CKK_ML_DSA,
5099 session, key->id, key->idLen);
5100 }
5101 else {
5102 ret = Pkcs11FindMldsaKey(&privateKey, CKO_PRIVATE_KEY, session,
5103 key);
5104 }
5105 }
5106 if (ret == 0) {
5107 /* Prepare mechanism structure */
5108 mech.mechanism = CKM_ML_DSA;
5109 mech.ulParameterLen = 0;
5110 mech.pParameter = NULL;
5111
5112 if (info->pk.pqc_sign.preHashType != WC_HASH_TYPE_NONE) {
5113 /* Set the preHash algorithm */
5114 ret = Pkcs11GetMldsaPreHash(info->pk.pqc_sign.preHashType,
5115 ¶mSet.preHash.hash);
5116 if (ret == 0) {
5117 mech.mechanism = CKM_HASH_ML_DSA;
5118 mech.pParameter = ¶mSet.preHash;
5119 mech.ulParameterLen = sizeof(paramSet.preHash);
5120 }
5121
5122 /* Set the context data */
5123 if (info->pk.pqc_sign.context != NULL &&
5124 info->pk.pqc_sign.contextLen > 0) {
5125 paramSet.preHash.pContext = (byte*)info->pk.pqc_sign.context;
5126 paramSet.preHash.ulContextLen = info->pk.pqc_sign.contextLen;
5127 }
5128 else {
5129 paramSet.preHash.pContext = NULL;
5130 paramSet.preHash.ulContextLen = 0;
5131 }
5132
5133 /* Hard-code the hedge variant to CKH_HEDGE_REQUIRED as we currently
5134 * do not support deterministic signing for ML-DSA via the CryptoCb
5135 * interface. */
5136 paramSet.preHash.hedgeVariant = CKH_HEDGE_REQUIRED;
5137 }
5138 else {
5139 /* Set the context data */
5140 if (info->pk.pqc_sign.context != NULL &&
5141 info->pk.pqc_sign.contextLen > 0) {
5142 paramSet.pure.pContext = (byte*) info->pk.pqc_sign.context;
5143 paramSet.pure.ulContextLen = info->pk.pqc_sign.contextLen;
5144
5145 /* Hard-code the hedge variant to CKH_HEDGE_REQUIRED as we
5146 * currently do not support deterministic signing for ML-DSA
5147 * via the CryptoCb interface. */
5148 paramSet.pure.hedgeVariant = CKH_HEDGE_REQUIRED;
5149
5150 mech.pParameter = ¶mSet.pure;
5151 mech.ulParameterLen = sizeof(paramSet.pure);
5152 }
5153 }
5154 }
5155 if (ret == 0) {
5156 rv = session->func->C_SignInit(session->handle, &mech, privateKey);
5157 PKCS11_RV("C_SignInit", rv);
5158 if (rv != CKR_OK) {
5159 ret = WC_HW_E;
5160 }
5161 }
5162
5163 if (ret == 0) {
5164 outLen = *info->pk.pqc_sign.outlen;
5165 rv = session->func->C_Sign(session->handle,
5166 (CK_BYTE_PTR)info->pk.pqc_sign.in,
5167 info->pk.pqc_sign.inlen,
5168 info->pk.pqc_sign.out,
5169 &outLen);
5170 PKCS11_RV("C_Sign", rv);
5171 if (rv != CKR_OK) {
5172 ret = WC_HW_E;
5173 }
5174 }
5175
5176 if (ret == 0) {
5177 *info->pk.pqc_sign.outlen = outLen;
5178 }
5179
5180 if (sessionKey)
5181 session->func->C_DestroyObject(session->handle, privateKey);
5182
5183 return ret;
5184}
5185
5186/**
5187 * Performs the ML-DSA verification operation.
5188 *
5189 * @param session [in] Session object.
5190 * @param info [in] Cryptographic operation data.
5191 * @return WC_HW_E when a PKCS#11 library call fails.
5192 * @return MEMORY_E when a memory allocation fails.
5193 * @return 0 on success.
5194 */
5195static int Pkcs11MldsaVerify(Pkcs11Session* session, wc_CryptoInfo* info)
5196{
5197 int ret = 0;
5198 int sessionKey = 0;
5199 CK_RV rv;
5200 CK_MECHANISM mech;
5201 CK_MECHANISM_INFO mechInfo;
5202 CK_OBJECT_HANDLE publicKey = NULL_PTR;
5203 MlDsaKey* key = (MlDsaKey*) info->pk.pqc_verify.key;
5204
5205 union {
5206 CK_SIGN_ADDITIONAL_CONTEXT pure;
5207 CK_HASH_SIGN_ADDITIONAL_CONTEXT preHash;
5208 } paramSet;
5209 XMEMSET(¶mSet, 0, sizeof(paramSet));
5210
5211 /* Check operation is supported. */
5212 if (info->pk.pqc_verify.preHashType != WC_HASH_TYPE_NONE) {
5213 ret = Pkcs11MechAvail(session, CKM_HASH_ML_DSA, &mechInfo);
5214 }
5215 else {
5216 ret = Pkcs11MechAvail(session, CKM_ML_DSA, &mechInfo);
5217 }
5218 if (ret == 0 && (mechInfo.flags & CKF_VERIFY) == 0) {
5219 ret = NOT_COMPILED_IN;
5220 }
5221 if (ret == 0 && info->pk.pqc_verify.res == NULL) {
5222 ret = BAD_FUNC_ARG;
5223 }
5224
5225 if (ret == 0) {
5226 WOLFSSL_MSG("PKCS#11: ML-DSA Verification Operation");
5227
5228 if (key->labelLen > 0) {
5229 ret = Pkcs11FindKeyByLabel(&publicKey, CKO_PUBLIC_KEY, CKK_ML_DSA,
5230 session, key->label, key->labelLen);
5231 }
5232 else if (key->idLen > 0) {
5233 ret = Pkcs11FindKeyById(&publicKey, CKO_PUBLIC_KEY, CKK_ML_DSA,
5234 session, key->id, key->idLen);
5235 }
5236 else if (key->pubKeySet) {
5237 ret = Pkcs11CreateMldsaPublicKey(&publicKey, session,
5238 key, &mechInfo);
5239 sessionKey = 1;
5240 }
5241 else {
5242 ret = Pkcs11FindMldsaKey(&publicKey, CKO_PUBLIC_KEY, session,
5243 key);
5244 }
5245 }
5246 if (ret == 0) {
5247 /* Prepare mechanism structure */
5248 mech.mechanism = CKM_ML_DSA;
5249 mech.ulParameterLen = 0;
5250 mech.pParameter = NULL;
5251
5252 if (info->pk.pqc_verify.preHashType != WC_HASH_TYPE_NONE) {
5253 /* Set the preHash algorithm */
5254 ret = Pkcs11GetMldsaPreHash(info->pk.pqc_verify.preHashType,
5255 ¶mSet.preHash.hash);
5256 if (ret == 0) {
5257 mech.mechanism = CKM_HASH_ML_DSA;
5258 mech.pParameter = ¶mSet.preHash;
5259 mech.ulParameterLen = sizeof(paramSet.preHash);
5260 }
5261
5262 /* Set the context data */
5263 if (info->pk.pqc_verify.context != NULL &&
5264 info->pk.pqc_verify.contextLen > 0) {
5265 paramSet.preHash.pContext = (byte*) info->pk.pqc_verify.context;
5266 paramSet.preHash.ulContextLen = info->pk.pqc_verify.contextLen;
5267 }
5268 else {
5269 paramSet.preHash.pContext = NULL;
5270 paramSet.preHash.ulContextLen = 0;
5271 }
5272 }
5273 else {
5274 /* Set the context data */
5275 if (info->pk.pqc_verify.context != NULL &&
5276 info->pk.pqc_verify.contextLen > 0) {
5277 paramSet.pure.pContext = (byte*) info->pk.pqc_verify.context;
5278 paramSet.pure.ulContextLen = info->pk.pqc_verify.contextLen;
5279
5280 mech.pParameter = ¶mSet.pure;
5281 mech.ulParameterLen = sizeof(paramSet.pure);
5282 }
5283 }
5284 }
5285 if (ret == 0) {
5286 rv = session->func->C_VerifyInit(session->handle, &mech, publicKey);
5287 PKCS11_RV("C_VerifyInit", rv);
5288 if (rv != CKR_OK) {
5289 ret = WC_HW_E;
5290 }
5291 }
5292
5293 if (ret == 0) {
5294 *info->pk.pqc_verify.res = 0;
5295 rv = session->func->C_Verify(session->handle,
5296 (CK_BYTE_PTR)info->pk.pqc_verify.msg,
5297 info->pk.pqc_verify.msglen,
5298 (CK_BYTE_PTR)info->pk.pqc_verify.sig,
5299 info->pk.pqc_verify.siglen);
5300 PKCS11_RV("C_Verify", rv);
5301 if (rv == CKR_SIGNATURE_INVALID)
5302 ret = SIG_VERIFY_E;
5303 else if (rv != CKR_OK)
5304 ret = WC_HW_E;
5305 else
5306 *info->pk.pqc_verify.res = 1;
5307 }
5308
5309 if (sessionKey && publicKey != NULL_PTR)
5310 session->func->C_DestroyObject(session->handle, publicKey);
5311
5312 return ret;
5313}
5314
5315/**
5316 * Checks whether the stored ML-DSA private key matches the given public key.
5317 * Do this by looking up the public key data from the associated private key.
5318 *
5319 * @param session [in] Session object.
5320 * @param info [in] Cryptographic operation data.
5321 * @return WC_HW_E when a PKCS#11 library call fails.
5322 * @return MEMORY_E when a memory allocation fails.
5323 * @return MP_CMP_E when the public parts are different.
5324 * @return 0 on success.
5325 */
5326static int Pkcs11MldsaCheckPrivKey(Pkcs11Session* session, wc_CryptoInfo* info)
5327{
5328 int ret = 0;
5329 byte key_level = 0;
5330 word32 storedKeySize = 0;
5331 word32 idx = 0;
5332 CK_OBJECT_HANDLE privKeyHandle;
5333 MlDsaKey* privKey = (MlDsaKey*) info->pk.pqc_sig_check.key;
5334 WC_DECLARE_VAR(pubKey, MlDsaKey, 1, privKey->heap);
5335
5336 WC_ALLOC_VAR_EX(pubKey, MlDsaKey, 1, privKey->heap, DYNAMIC_TYPE_DILITHIUM,
5337 ret = MEMORY_E);
5338
5339 /* Get the ML-DSA public key object. */
5340 if (ret == 0 && privKey->labelLen > 0)
5341 ret = Pkcs11FindKeyByLabel(&privKeyHandle, CKO_PUBLIC_KEY, CKK_ML_DSA,
5342 session, privKey->label, privKey->labelLen);
5343 else if (ret == 0 && privKey->idLen > 0)
5344 ret = Pkcs11FindKeyById(&privKeyHandle, CKO_PUBLIC_KEY, CKK_ML_DSA,
5345 session, privKey->id, privKey->idLen);
5346 else if (ret == 0)
5347 ret = Pkcs11FindMldsaKey(&privKeyHandle, CKO_PUBLIC_KEY,
5348 session, privKey);
5349 if (ret == 0) {
5350 /* Extract the public key components. */
5351 ret = Pkcs11GetMldsaPublicKey(privKey, session, privKeyHandle);
5352 }
5353
5354 /* Get the security level of the private key */
5355 if (ret == 0)
5356 ret = wc_MlDsaKey_GetParams(privKey, &key_level);
5357
5358 if (ret == 0) {
5359 if (key_level == WC_ML_DSA_44)
5360 storedKeySize = ML_DSA_LEVEL2_PUB_KEY_SIZE;
5361 else if (key_level == WC_ML_DSA_65)
5362 storedKeySize = ML_DSA_LEVEL3_PUB_KEY_SIZE;
5363 else if (key_level == WC_ML_DSA_87)
5364 storedKeySize = ML_DSA_LEVEL5_PUB_KEY_SIZE;
5365 else
5366 ret = WC_KEY_SIZE_E;
5367 }
5368
5369 if ((ret == 0) &&
5370 ((ret = wc_MlDsaKey_Init(pubKey, privKey->heap, INVALID_DEVID)) == 0)) {
5371 ret = wc_MlDsaKey_SetParams(pubKey, key_level);
5372 if (ret == 0) {
5373 ret = wc_MlDsaKey_PublicKeyDecode(pubKey,
5374 info->pk.pqc_sig_check.pubKey,
5375 info->pk.pqc_sig_check.pubKeySz,
5376 &idx);
5377 }
5378 if (ret == 0) {
5379 /* Compare the data of the provided public key with the data
5380 * stored in the private key object */
5381 ret = XMEMCMP(privKey->p, pubKey->p, storedKeySize);
5382 if (ret != 0)
5383 ret = MP_CMP_E;
5384 }
5385 wc_MlDsaKey_Free(pubKey);
5386 }
5387
5388 WC_FREE_VAR_EX(pubKey, privKey->heap, DYNAMIC_TYPE_DILITHIUM);
5389
5390 return ret;
5391}
5392
5393/**
5394 * Deletes the ML-DSA private key.
5395 *
5396 * @param [in] session Session object.
5397 * @param [in] key ML-DSA key.
5398 * @return 0 on success.
5399 */
5400static int Pkcs11MldsaDeletePrivKey(Pkcs11Session* session, MlDsaKey* key)
5401{
5402 CK_OBJECT_HANDLE privateKey;
5403
5404 if (key != NULL && key->devCtx != NULL) {
5405 privateKey = (CK_OBJECT_HANDLE)(wc_ptr_t)key->devCtx;
5406
5407 session->func->C_DestroyObject(session->handle, privateKey);
5408
5409 key->devCtx = NULL;
5410 }
5411
5412 return 0;
5413}
5414
5415/**
5416 * Perform a PQC key generation operation.
5417 * The private key data stays on the device.
5418 *
5419 * @param [in] session Session object.
5420 * @param [in] info Cryptographic operation data.
5421 * @return WC_HW_E when a PKCS#11 library call fails.
5422 * @return 0 on success.
5423 */
5424static int Pkcs11PqcSigKeyGen(Pkcs11Session* session, wc_CryptoInfo* info)
5425{
5426 int ret = 0;
5427
5428 switch (info->pk.pqc_sig_kg.type) {
5429 case WC_PQC_SIG_TYPE_DILITHIUM:
5430 ret = Pkcs11MldsaKeyGen(session,
5431 (MlDsaKey*)info->pk.pqc_sig_kg.key);
5432 break;
5433 default:
5434 ret = NOT_COMPILED_IN;
5435 break;
5436 }
5437
5438 return ret;
5439}
5440
5441/**
5442 * Performs the signing operation with the PQC algorithm.
5443 *
5444 * @param session [in] Session object.
5445 * @param info [in] Cryptographic operation data.
5446 * @return WC_HW_E when a PKCS#11 library call fails.
5447 * @return 0 on success.
5448 */
5449static int Pkcs11PqcSigSign(Pkcs11Session* session, wc_CryptoInfo* info)
5450{
5451 int ret = 0;
5452
5453 switch (info->pk.pqc_sign.type) {
5454 case WC_PQC_SIG_TYPE_DILITHIUM:
5455 ret = Pkcs11MldsaSign(session, info);
5456 break;
5457 default:
5458 ret = NOT_COMPILED_IN;
5459 break;
5460 }
5461
5462 return ret;
5463}
5464
5465/**
5466 * Performs the verification operation with the PQC algorithm.
5467 *
5468 * @param session [in] Session object.
5469 * @param info [in] Cryptographic operation data.
5470 * @return WC_HW_E when a PKCS#11 library call fails.
5471 * @return MEMORY_E when a memory allocation fails.
5472 * @return 0 on success.
5473 */
5474static int Pkcs11PqcSigVerify(Pkcs11Session* session, wc_CryptoInfo* info)
5475{
5476 int ret = 0;
5477
5478 switch (info->pk.pqc_verify.type) {
5479 case WC_PQC_SIG_TYPE_DILITHIUM:
5480 ret = Pkcs11MldsaVerify(session, info);
5481 break;
5482 default:
5483 ret = NOT_COMPILED_IN;
5484 break;
5485 }
5486
5487 return ret;
5488}
5489
5490/**
5491 * Checks whether the stored PQC private key matches the given PQC public key.
5492 *
5493 * @param session [in] Session object.
5494 * @param info [in] Cryptographic operation data.
5495 * @return WC_HW_E when a PKCS#11 library call fails.
5496 * @return MEMORY_E when a memory allocation fails.
5497 * @return MP_CMP_E when the public parts are different.
5498 * @return 0 on success.
5499 */
5500static int Pkcs11PqcSigCheckPrivKey(Pkcs11Session* session, wc_CryptoInfo* info)
5501{
5502 int ret = 0;
5503
5504 switch (info->pk.pqc_sig_check.type) {
5505 case WC_PQC_SIG_TYPE_DILITHIUM:
5506 ret = Pkcs11MldsaCheckPrivKey(session, info);
5507 break;
5508 default:
5509 ret = NOT_COMPILED_IN;
5510 break;
5511 }
5512
5513 return ret;
5514}
5515#endif /* HAVE_DILITHIUM */
5516
5517#if !defined(NO_AES) && defined(HAVE_AESGCM)
5518/**
5519 * Performs the AES-GCM encryption operation.
5520 *
5521 * @param [in] session Session object.
5522 * @param [in] info Cryptographic operation data.
5523 * @return WC_HW_E when a PKCS#11 library call fails.
5524 * @return MEMORY_E when a memory allocation fails.
5525 * @return 0 on success.
5526 */
5527static int Pkcs11AesGcmEncrypt(Pkcs11Session* session, wc_CryptoInfo* info)
5528{
5529 int ret = 0;
5530 CK_RV rv;
5531 Aes* aes = info->cipher.aesgcm_enc.aes;
5532 CK_GCM_PARAMS params;
5533 CK_MECHANISM_INFO mechInfo;
5534 CK_OBJECT_HANDLE key = NULL_PTR;
5535 CK_MECHANISM mech;
5536 CK_ULONG outLen;
5537
5538 /* Check operation is supported. */
5539 ret = Pkcs11MechAvail(session, CKM_AES_GCM, &mechInfo);
5540 if (ret == 0 && (mechInfo.flags & CKF_ENCRYPT) == 0) {
5541 ret = NOT_COMPILED_IN;
5542 }
5543 if (ret == 0) {
5544 WOLFSSL_MSG("PKCS#11: AES-GCM Encryption Operation");
5545
5546 /* Create a private key object or find by label or id. */
5547 if (aes->idLen == 0 && aes->labelLen == 0) {
5548 ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,
5549 (unsigned char*)aes->devKey,
5550 aes->keylen, NULL, 0, NULL, 0,
5551 CKA_ENCRYPT);
5552 }
5553 else if (aes->labelLen != 0) {
5554 ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY, CKK_AES, session,
5555 aes->label, aes->labelLen);
5556 }
5557 else {
5558 ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session,
5559 aes->id, aes->idLen);
5560 }
5561 }
5562
5563 if (ret == 0) {
5564 params.pIv = (CK_BYTE_PTR)info->cipher.aesgcm_enc.iv;
5565 params.ulIvLen = info->cipher.aesgcm_enc.ivSz;
5566 params.pAAD = (CK_BYTE_PTR)info->cipher.aesgcm_enc.authIn;
5567 params.ulAADLen = info->cipher.aesgcm_enc.authInSz;
5568 params.ulTagBits = info->cipher.aesgcm_enc.authTagSz * 8;
5569
5570 mech.mechanism = CKM_AES_GCM;
5571 mech.ulParameterLen = sizeof(params);
5572 mech.pParameter = ¶ms;
5573
5574 rv = session->func->C_EncryptInit(session->handle, &mech, key);
5575 PKCS11_RV("C_EncryptInit", rv);
5576 if (rv != CKR_OK) {
5577 ret = WC_HW_E;
5578 }
5579 }
5580 if (ret == 0) {
5581 outLen = info->cipher.aesgcm_enc.sz;
5582 rv = session->func->C_EncryptUpdate(session->handle,
5583 (CK_BYTE_PTR)info->cipher.aesgcm_enc.in,
5584 info->cipher.aesgcm_enc.sz,
5585 info->cipher.aesgcm_enc.out,
5586 &outLen);
5587 PKCS11_RV("C_EncryptUpdate", rv);
5588 if (rv != CKR_OK) {
5589 ret = WC_HW_E;
5590 }
5591 }
5592 if (ret == 0) {
5593 /* Authentication tag comes out in final block. */
5594 outLen = info->cipher.aesgcm_enc.authTagSz;
5595 rv = session->func->C_EncryptFinal(session->handle,
5596 info->cipher.aesgcm_enc.authTag,
5597 &outLen);
5598 PKCS11_RV("C_EncryptFinal", rv);
5599 if (rv != CKR_OK) {
5600 ret = WC_HW_E;
5601 }
5602 }
5603
5604 if (aes->idLen == 0 && aes->labelLen == 0 && key != NULL_PTR)
5605 session->func->C_DestroyObject(session->handle, key);
5606
5607 return ret;
5608}
5609
5610/**
5611 * Performs the AES-GCM decryption operation.
5612 *
5613 * @param [in] session Session object.
5614 * @param [in] info Cryptographic operation data.
5615 * @return WC_HW_E when a PKCS#11 library call fails.
5616 * @return MEMORY_E when a memory allocation fails.
5617 * @return 0 on success.
5618 */
5619static int Pkcs11AesGcmDecrypt(Pkcs11Session* session, wc_CryptoInfo* info)
5620{
5621 int ret = 0;
5622 CK_RV rv;
5623 Aes* aes = info->cipher.aesgcm_enc.aes;
5624 CK_GCM_PARAMS params;
5625 CK_MECHANISM_INFO mechInfo;
5626 CK_OBJECT_HANDLE key = NULL_PTR;
5627 CK_MECHANISM mech;
5628 CK_ULONG outLen;
5629 word32 len;
5630
5631 /* Check operation is supported. */
5632 ret = Pkcs11MechAvail(session, CKM_AES_GCM, &mechInfo);
5633 if (ret == 0 && (mechInfo.flags & CKF_DECRYPT) == 0) {
5634 ret = NOT_COMPILED_IN;
5635 }
5636 if (ret == 0) {
5637 WOLFSSL_MSG("PKCS#11: AES-GCM Decryption Operation");
5638
5639 /* Create a private key object or find by id. */
5640 if (aes->idLen == 0 && aes->labelLen == 0) {
5641 ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,
5642 (unsigned char*)aes->devKey,
5643 aes->keylen, NULL, 0, NULL, 0,
5644 CKA_DECRYPT);
5645 }
5646 else if (aes->labelLen != 0) {
5647 ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY, CKK_AES, session,
5648 aes->label, aes->labelLen);
5649 }
5650 else {
5651 ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session,
5652 aes->id, aes->idLen);
5653 }
5654 }
5655
5656 if (ret == 0) {
5657 params.pIv = (CK_BYTE_PTR)info->cipher.aesgcm_dec.iv;
5658 params.ulIvLen = info->cipher.aesgcm_dec.ivSz;
5659 params.pAAD = (CK_BYTE_PTR)info->cipher.aesgcm_dec.authIn;
5660 params.ulAADLen = info->cipher.aesgcm_dec.authInSz;
5661 params.ulTagBits = info->cipher.aesgcm_dec.authTagSz * 8;
5662
5663 mech.mechanism = CKM_AES_GCM;
5664 mech.ulParameterLen = sizeof(params);
5665 mech.pParameter = ¶ms;
5666
5667 rv = session->func->C_DecryptInit(session->handle, &mech, key);
5668 PKCS11_RV("C_DecryptInit", rv);
5669 if (rv != CKR_OK) {
5670 ret = WC_HW_E;
5671 }
5672 }
5673 if (ret == 0) {
5674 outLen = len = info->cipher.aesgcm_dec.sz;
5675 rv = session->func->C_DecryptUpdate(session->handle,
5676 (CK_BYTE_PTR)info->cipher.aesgcm_dec.in,
5677 info->cipher.aesgcm_dec.sz,
5678 info->cipher.aesgcm_dec.out,
5679 &outLen);
5680 PKCS11_RV("C_DecryptUpdate", rv);
5681 if (rv != CKR_OK) {
5682 ret = WC_HW_E;
5683 }
5684 }
5685 if (ret == 0) {
5686 /* Put authentication tag in as encrypted data. */
5687 outLen = len = (len + info->cipher.aesgcm_dec.authTagSz -
5688 (word32)outLen);
5689 rv = session->func->C_DecryptUpdate(session->handle,
5690 (CK_BYTE_PTR)info->cipher.aesgcm_dec.authTag,
5691 info->cipher.aesgcm_dec.authTagSz,
5692 info->cipher.aesgcm_dec.out,
5693 &outLen);
5694 PKCS11_RV("C_DecryptUpdate", rv);
5695 if (rv != CKR_OK) {
5696 ret = WC_HW_E;
5697 }
5698 }
5699 if (ret == 0) {
5700 outLen = len = (len - (word32)outLen);
5701 /* Decrypted data comes out now. */
5702 rv = session->func->C_DecryptFinal(session->handle,
5703 info->cipher.aesgcm_dec.out,
5704 &outLen);
5705 PKCS11_RV("C_DecryptFinal", rv);
5706 if (rv != CKR_OK) {
5707 ret = WC_HW_E;
5708 }
5709 }
5710
5711 if (aes->idLen == 0 && aes->labelLen == 0 && key != NULL_PTR)
5712 session->func->C_DestroyObject(session->handle, key);
5713
5714 return ret;
5715}
5716#endif
5717
5718#if !defined(NO_AES) && defined(HAVE_AES_CBC)
5719/**
5720 * Performs the AES-CBC encryption operation.
5721 *
5722 * @param [in] session Session object.
5723 * @param [in] info Cryptographic operation data.
5724 * @return WC_HW_E when a PKCS#11 library call fails.
5725 * @return MEMORY_E when a memory allocation fails.
5726 * @return 0 on success.
5727 */
5728static int Pkcs11AesCbcEncrypt(Pkcs11Session* session, wc_CryptoInfo* info)
5729{
5730 int ret = 0;
5731 CK_RV rv;
5732 Aes* aes = info->cipher.aescbc.aes;
5733 CK_MECHANISM_INFO mechInfo;
5734 CK_OBJECT_HANDLE key = NULL_PTR;
5735 CK_MECHANISM mech;
5736 CK_ULONG outLen;
5737
5738 /* Check operation is supported. */
5739 ret = Pkcs11MechAvail(session, CKM_AES_CBC, &mechInfo);
5740 if (ret == 0 && (mechInfo.flags & CKF_ENCRYPT) == 0) {
5741 ret = NOT_COMPILED_IN;
5742 }
5743 if (ret == 0) {
5744 WOLFSSL_MSG("PKCS#11: AES-CBC Encryption Operation");
5745
5746 /* Create a private key object or find by id. */
5747 if (aes->idLen == 0 && aes->labelLen == 0) {
5748 ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,
5749 (unsigned char*)aes->devKey,
5750 aes->keylen, NULL, 0, NULL, 0,
5751 CKA_ENCRYPT);
5752 }
5753 else if (aes->labelLen != 0) {
5754 ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY, CKK_AES, session,
5755 aes->label, aes->labelLen);
5756 }
5757 else {
5758 ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session,
5759 aes->id, aes->idLen);
5760 }
5761 }
5762
5763 if (ret == 0) {
5764 mech.mechanism = CKM_AES_CBC;
5765 mech.ulParameterLen = WC_AES_BLOCK_SIZE;
5766 mech.pParameter = (CK_BYTE_PTR)info->cipher.aescbc.aes->reg;
5767
5768 rv = session->func->C_EncryptInit(session->handle, &mech, key);
5769 PKCS11_RV("C_EncryptInit", rv);
5770 if (rv != CKR_OK) {
5771 ret = WC_HW_E;
5772 }
5773 }
5774 if (ret == 0) {
5775 outLen = info->cipher.aescbc.sz;
5776 rv = session->func->C_Encrypt(session->handle,
5777 (CK_BYTE_PTR)info->cipher.aescbc.in,
5778 info->cipher.aescbc.sz,
5779 info->cipher.aescbc.out,
5780 &outLen);
5781 PKCS11_RV("C_Encrypt", rv);
5782 if (rv != CKR_OK) {
5783 ret = WC_HW_E;
5784 }
5785 }
5786
5787 if (aes->idLen == 0 && aes->labelLen == 0 && key != NULL_PTR)
5788 session->func->C_DestroyObject(session->handle, key);
5789
5790 return ret;
5791}
5792
5793/**
5794 * Performs the AES-CBC decryption operation.
5795 *
5796 * @param [in] session Session object.
5797 * @param [in] info Cryptographic operation data.
5798 * @return WC_HW_E when a PKCS#11 library call fails.
5799 * @return MEMORY_E when a memory allocation fails.
5800 * @return 0 on success.
5801 */
5802static int Pkcs11AesCbcDecrypt(Pkcs11Session* session, wc_CryptoInfo* info)
5803{
5804 int ret = 0;
5805 CK_RV rv;
5806 Aes* aes = info->cipher.aescbc.aes;
5807 CK_MECHANISM_INFO mechInfo;
5808 CK_OBJECT_HANDLE key = NULL_PTR;
5809 CK_MECHANISM mech;
5810 CK_ULONG outLen;
5811
5812 /* Check operation is supported. */
5813 ret = Pkcs11MechAvail(session, CKM_AES_CBC, &mechInfo);
5814 if (ret == 0 && (mechInfo.flags & CKF_DECRYPT) == 0) {
5815 ret = NOT_COMPILED_IN;
5816 }
5817 if (ret == 0) {
5818 WOLFSSL_MSG("PKCS#11: AES-CBC Decryption Operation");
5819
5820 /* Create a private key object or find by id. */
5821 if (aes->idLen == 0 && aes->labelLen == 0) {
5822 ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,
5823 (unsigned char*)aes->devKey,
5824 aes->keylen, NULL, 0, NULL, 0,
5825 CKA_DECRYPT);
5826 }
5827 else if (aes->labelLen != 0) {
5828 ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY, CKK_AES, session,
5829 aes->label, aes->labelLen);
5830 }
5831 else {
5832 ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session,
5833 aes->id, aes->idLen);
5834 }
5835 }
5836
5837 if (ret == 0) {
5838 mech.mechanism = CKM_AES_CBC;
5839 mech.ulParameterLen = WC_AES_BLOCK_SIZE;
5840 mech.pParameter = (CK_BYTE_PTR)info->cipher.aescbc.aes->reg;
5841
5842 rv = session->func->C_DecryptInit(session->handle, &mech, key);
5843 PKCS11_RV("C_DecryptInit", rv);
5844 if (rv != CKR_OK) {
5845 ret = WC_HW_E;
5846 }
5847 }
5848 if (ret == 0) {
5849 outLen = info->cipher.aescbc.sz;
5850 rv = session->func->C_Decrypt(session->handle,
5851 (CK_BYTE_PTR)info->cipher.aescbc.in,
5852 info->cipher.aescbc.sz,
5853 info->cipher.aescbc.out,
5854 &outLen);
5855 PKCS11_RV("C_Decrypt", rv);
5856 if (rv != CKR_OK) {
5857 ret = WC_HW_E;
5858 }
5859 }
5860
5861 if (aes->idLen == 0 && aes->labelLen == 0 && key != NULL_PTR)
5862 session->func->C_DestroyObject(session->handle, key);
5863
5864 return ret;
5865}
5866
5867#endif
5868
5869#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER)
5870/**
5871 * Performs the AES-CTR encryption operation.
5872 *
5873 * @param [in] session Session object.
5874 * @param [in] info Cryptographic operation data.
5875 * @return WC_HW_E when a PKCS#11 library call fails.
5876 * @return MEMORY_E when a memory allocation fails.
5877 * @return 0 on success.
5878 */
5879static int Pkcs11AesCtrEncrypt(Pkcs11Session* session, wc_CryptoInfo* info)
5880{
5881 int ret = 0;
5882 CK_RV rv;
5883 Aes* aes = info->cipher.aesctr.aes;
5884 CK_MECHANISM_INFO mechInfo;
5885 CK_AES_CTR_PARAMS params;
5886 CK_OBJECT_HANDLE key = NULL_PTR;
5887 CK_MECHANISM mech;
5888 CK_ULONG outLen;
5889
5890 /* Check operation is supported. */
5891 ret = Pkcs11MechAvail(session, CKM_AES_CTR, &mechInfo);
5892 if (ret == 0 && (mechInfo.flags & CKF_ENCRYPT) == 0) {
5893 ret = NOT_COMPILED_IN;
5894 }
5895 if (ret == 0) {
5896 WOLFSSL_MSG("PKCS#11: AES-CTR Encryption Operation");
5897
5898 /* Create a private key object or find by id. */
5899 if (aes->idLen == 0 && aes->labelLen == 0) {
5900 ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,
5901 (unsigned char*)aes->devKey,
5902 aes->keylen, NULL, 0, NULL, 0,
5903 CKA_ENCRYPT);
5904 }
5905 else if (aes->labelLen != 0) {
5906 ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY, CKK_AES, session,
5907 aes->label, aes->labelLen);
5908 }
5909 else {
5910 ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session,
5911 aes->id, aes->idLen);
5912 }
5913 }
5914
5915 if (ret == 0) {
5916 XMEMSET(¶ms, 0, sizeof(params));
5917 params.ulCounterBits = WC_AES_BLOCK_SIZE * 8;
5918 XMEMCPY(params.cb, info->cipher.aesctr.aes->reg, WC_AES_BLOCK_SIZE);
5919
5920 mech.mechanism = CKM_AES_CTR;
5921 mech.ulParameterLen = sizeof(params);
5922 mech.pParameter = ¶ms;
5923
5924 rv = session->func->C_EncryptInit(session->handle, &mech, key);
5925 PKCS11_RV("C_EncryptInit", rv);
5926 if (rv != CKR_OK) {
5927 ret = WC_HW_E;
5928 }
5929 }
5930 if (ret == 0) {
5931 outLen = info->cipher.aesctr.sz;
5932 rv = session->func->C_Encrypt(session->handle,
5933 (CK_BYTE_PTR)info->cipher.aesctr.in,
5934 info->cipher.aesctr.sz,
5935 info->cipher.aesctr.out,
5936 &outLen);
5937 PKCS11_RV("C_Encrypt", rv);
5938 if (rv != CKR_OK) {
5939 ret = WC_HW_E;
5940 }
5941 }
5942
5943 if (aes->idLen == 0 && aes->labelLen == 0 && key != NULL_PTR)
5944 session->func->C_DestroyObject(session->handle, key);
5945
5946 return ret;
5947}
5948
5949/**
5950 * Performs the AES-CTR decryption operation.
5951 *
5952 * @param [in] session Session object.
5953 * @param [in] info Cryptographic operation data.
5954 * @return WC_HW_E when a PKCS#11 library call fails.
5955 * @return MEMORY_E when a memory allocation fails.
5956 * @return 0 on success.
5957 */
5958static int Pkcs11AesCtrDecrypt(Pkcs11Session* session, wc_CryptoInfo* info)
5959{
5960 int ret = 0;
5961 CK_RV rv;
5962 Aes* aes = info->cipher.aesctr.aes;
5963 CK_MECHANISM_INFO mechInfo;
5964 CK_AES_CTR_PARAMS params;
5965 CK_OBJECT_HANDLE key = NULL_PTR;
5966 CK_MECHANISM mech;
5967 CK_ULONG outLen;
5968
5969 /* Check operation is supported. */
5970 ret = Pkcs11MechAvail(session, CKM_AES_CTR, &mechInfo);
5971 if (ret == 0 && (mechInfo.flags & CKF_DECRYPT) == 0) {
5972 ret = NOT_COMPILED_IN;
5973 }
5974 if (ret == 0) {
5975 WOLFSSL_MSG("PKCS#11: AES-CTR Decryption Operation");
5976
5977 /* Create a private key object or find by id. */
5978 if (aes->idLen == 0 && aes->labelLen == 0) {
5979 ret = Pkcs11CreateSecretKey(&key, session, CKK_AES,
5980 (unsigned char*)aes->devKey,
5981 aes->keylen, NULL, 0, NULL, 0,
5982 CKA_DECRYPT);
5983 }
5984 else if (aes->labelLen != 0) {
5985 ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY, CKK_AES, session,
5986 aes->label, aes->labelLen);
5987 }
5988 else {
5989 ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, CKK_AES, session,
5990 aes->id, aes->idLen);
5991 }
5992 }
5993
5994 if (ret == 0) {
5995 XMEMSET(¶ms, 0, sizeof(params));
5996 params.ulCounterBits = WC_AES_BLOCK_SIZE * 8;
5997 XMEMCPY(params.cb, info->cipher.aesctr.aes->reg, WC_AES_BLOCK_SIZE);
5998
5999 mech.mechanism = CKM_AES_CTR;
6000 mech.ulParameterLen = sizeof(params);
6001 mech.pParameter = ¶ms;
6002
6003 rv = session->func->C_DecryptInit(session->handle, &mech, key);
6004 PKCS11_RV("C_DecryptInit", rv);
6005 if (rv != CKR_OK) {
6006 ret = WC_HW_E;
6007 }
6008 }
6009 if (ret == 0) {
6010 outLen = info->cipher.aesctr.sz;
6011 rv = session->func->C_Decrypt(session->handle,
6012 (CK_BYTE_PTR)info->cipher.aesctr.in,
6013 info->cipher.aesctr.sz,
6014 info->cipher.aesctr.out,
6015 &outLen);
6016 PKCS11_RV("C_Decrypt", rv);
6017 if (rv != CKR_OK) {
6018 ret = WC_HW_E;
6019 }
6020 }
6021
6022 if (aes->idLen == 0 && aes->labelLen == 0 && key != NULL_PTR)
6023 session->func->C_DestroyObject(session->handle, key);
6024
6025 return ret;
6026}
6027
6028#endif
6029
6030#ifndef NO_HMAC
6031/**
6032 * Updates or calculates the HMAC of the data.
6033 *
6034 * @param [in] session Session object.
6035 * @param [in] info Cryptographic operation data.
6036 * @return WC_HW_E when a PKCS#11 library call fails.
6037 * @return 0 on success.
6038 */
6039static int Pkcs11Hmac(Pkcs11Session* session, wc_CryptoInfo* info)
6040{
6041 int ret = 0;
6042 CK_RV rv;
6043 Hmac* hmac = info->hmac.hmac;
6044 CK_MECHANISM_INFO mechInfo;
6045 CK_OBJECT_HANDLE key = NULL_PTR;
6046 CK_MECHANISM mech;
6047 CK_ULONG outLen;
6048 int mechType;
6049 int keyType;
6050
6051 if (hmac->innerHashKeyed == WC_HMAC_INNER_HASH_KEYED_SW)
6052 ret = NOT_COMPILED_IN;
6053
6054 if (ret == 0)
6055 ret = Pkcs11HmacTypes(info->hmac.macType, &mechType, &keyType);
6056 if (ret == 0) {
6057 /* Check operation is supported. */
6058 ret = Pkcs11MechAvail(session, mechType, &mechInfo);
6059 if (ret == 0 && (mechInfo.flags & CKF_SIGN) == 0) {
6060 ret = NOT_COMPILED_IN;
6061 }
6062 }
6063
6064 /* Check whether key been used to initialized. */
6065 if (ret == 0 && !hmac->innerHashKeyed) {
6066 WOLFSSL_MSG("PKCS#11: HMAC Init");
6067
6068 /* Check device supports key length. */
6069 if (mechInfo.ulMaxKeySize > 0 &&
6070 (hmac->keyLen < mechInfo.ulMinKeySize ||
6071 hmac->keyLen > mechInfo.ulMaxKeySize)) {
6072 WOLFSSL_MSG("PKCS#11: Key Length not supported");
6073 ret = NOT_COMPILED_IN;
6074 }
6075
6076 /* Create a private key object or find by id. */
6077 if (ret == 0 && hmac->idLen == 0 && hmac->labelLen == 0) {
6078 ret = Pkcs11CreateSecretKey(&key, session, keyType,
6079 (unsigned char*)hmac->keyRaw, hmac->keyLen,
6080 NULL, 0, NULL, 0, CKA_SIGN);
6081 if (ret == WC_NO_ERR_TRACE(WC_HW_E)) {
6082 ret = Pkcs11CreateSecretKey(&key, session, CKK_GENERIC_SECRET,
6083 (unsigned char*)hmac->keyRaw, hmac->keyLen,
6084 NULL, 0, NULL, 0, CKA_SIGN);
6085 }
6086
6087 }
6088 else if (ret == 0 && hmac->labelLen != 0) {
6089 ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY, keyType, session,
6090 hmac->label, hmac->labelLen);
6091 if (ret == WC_NO_ERR_TRACE(WC_HW_E)) {
6092 ret = Pkcs11FindKeyByLabel(&key, CKO_SECRET_KEY,
6093 CKK_GENERIC_SECRET, session,
6094 hmac->label, hmac->labelLen);
6095 }
6096 }
6097 else if (ret == 0) {
6098 ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY, keyType, session,
6099 hmac->id, hmac->idLen);
6100 if (ret == WC_NO_ERR_TRACE(WC_HW_E)) {
6101 ret = Pkcs11FindKeyById(&key, CKO_SECRET_KEY,
6102 CKK_GENERIC_SECRET, session, hmac->id,
6103 hmac->idLen);
6104 }
6105 }
6106
6107 /* Initialize HMAC operation */
6108 if (ret == 0) {
6109 mech.mechanism = mechType;
6110 mech.ulParameterLen = 0;
6111 mech.pParameter = NULL;
6112
6113 rv = session->func->C_SignInit(session->handle, &mech, key);
6114 PKCS11_RV("C_SignInit", rv);
6115 if (rv != CKR_OK) {
6116 ret = WC_HW_E;
6117 }
6118 }
6119
6120 /* Don't initialize HMAC again if this succeeded */
6121 if (ret == 0)
6122 hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_DEV;
6123 }
6124 /* Update the HMAC if input data passed in. */
6125 if (ret == 0 && info->hmac.inSz > 0) {
6126 WOLFSSL_MSG("PKCS#11: HMAC Update");
6127
6128 rv = session->func->C_SignUpdate(session->handle,
6129 (CK_BYTE_PTR)info->hmac.in,
6130 info->hmac.inSz);
6131 PKCS11_RV("C_SignUpdate", rv);
6132 /* Some algorithm implementations only support C_Sign. */
6133 if (rv == CKR_MECHANISM_INVALID) {
6134 WOLFSSL_MSG("PKCS#11: HMAC Update/Final not supported");
6135 ret = NOT_COMPILED_IN;
6136 /* Allow software implementation to set key. */
6137 hmac->innerHashKeyed = 0;
6138 }
6139 else if (rv != CKR_OK)
6140 ret = WC_HW_E;
6141 }
6142 /* Calculate the HMAC result if output buffer specified. */
6143 if (ret == 0 && info->hmac.digest != NULL) {
6144 WOLFSSL_MSG("PKCS#11: HMAC Final");
6145
6146 outLen = WC_MAX_DIGEST_SIZE;
6147 rv = session->func->C_SignFinal(session->handle,
6148 (CK_BYTE_PTR)info->hmac.digest,
6149 &outLen);
6150 PKCS11_RV("C_SignFinal", rv);
6151 /* Some algorithm implementations only support C_Sign. */
6152 if (rv != CKR_OK) {
6153 ret = WC_HW_E;
6154 }
6155 else
6156 hmac->innerHashKeyed = 0;
6157 }
6158
6159 if (hmac->idLen == 0 && hmac->labelLen == 0 && key != NULL_PTR)
6160 session->func->C_DestroyObject(session->handle, key);
6161
6162 return ret;
6163}
6164#endif
6165
6166#ifndef WC_NO_RNG
6167#ifndef HAVE_HASHDRBG
6168/**
6169 * Performs random number generation.
6170 *
6171 * @param [in] session Session object.
6172 * @param [in] info Cryptographic operation data.
6173 * @return WC_HW_E when a PKCS#11 library call fails.
6174 * @return 0 on success.
6175 */
6176static int Pkcs11RandomBlock(Pkcs11Session* session, wc_CryptoInfo* info)
6177{
6178 int ret = 0;
6179 CK_RV rv;
6180
6181 WOLFSSL_MSG("PKCS#11: Generate Random for Block");
6182
6183 rv = session->func->C_GenerateRandom(session->handle, info->rng.out,
6184 info->rng.sz);
6185 PKCS11_RV("C_GenerateRandom", rv);
6186 if (rv != CKR_OK) {
6187 ret = WC_HW_E;
6188 }
6189 return ret;
6190}
6191#endif
6192
6193/**
6194 * Generates entropy (seed) data.
6195 *
6196 * @param [in] session Session object.
6197 * @param [in] info Cryptographic operation data.
6198 * @return WC_HW_E when a PKCS#11 library call fails.
6199 * @return 0 on success.
6200 */
6201static int Pkcs11RandomSeed(Pkcs11Session* session, wc_CryptoInfo* info)
6202{
6203 int ret = 0;
6204 CK_RV rv;
6205
6206 WOLFSSL_MSG("PKCS#11: Generate Random for Seed");
6207
6208 rv = session->func->C_GenerateRandom(session->handle, info->seed.seed,
6209 info->seed.sz);
6210 PKCS11_RV("C_GenerateRandom", rv);
6211 if (rv != CKR_OK) {
6212 ret = WC_HW_E;
6213 }
6214 return ret;
6215}
6216#endif
6217
6218#ifndef NO_CERTS
6219
6220static int Pkcs11GetCert(Pkcs11Session* session, wc_CryptoInfo* info) {
6221 int ret = 0;
6222 CK_RV rv = 0;
6223 CK_ULONG count = 0;
6224 CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
6225 byte *certData = NULL;
6226 CK_ATTRIBUTE certTemplate[2] = {
6227 { CKA_CLASS, &certClass, sizeof(certClass) }
6228 };
6229 CK_ATTRIBUTE tmpl[] = {
6230 { CKA_VALUE, NULL_PTR, 0 }
6231 };
6232 CK_ULONG certTmplCnt = sizeof(certTemplate) / sizeof(*certTemplate);
6233 CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
6234
6235 WOLFSSL_MSG("PKCS#11: Retrieve certificate");
6236 if (info->cert.labelLen > 0) {
6237 certTemplate[1].type = CKA_LABEL;
6238 certTemplate[1].pValue = (CK_VOID_PTR)info->cert.label;
6239 certTemplate[1].ulValueLen = info->cert.labelLen;
6240 }
6241 else if (info->cert.idLen > 0) {
6242 certTemplate[1].type = CKA_ID;
6243 certTemplate[1].pValue = (CK_VOID_PTR)info->cert.id;
6244 certTemplate[1].ulValueLen = info->cert.idLen;
6245 }
6246 else {
6247 ret = BAD_FUNC_ARG;
6248 goto exit;
6249 }
6250
6251 ret = Pkcs11FindKeyByTemplate(
6252 &certHandle, session, certTemplate, certTmplCnt, &count);
6253 if (ret == 0 && count == 0) {
6254 ret = WC_HW_E;
6255 goto exit;
6256 }
6257
6258 PKCS11_DUMP_TEMPLATE("Get Certificate Length", tmpl, tmplCnt);
6259 rv = session->func->C_GetAttributeValue(
6260 session->handle, certHandle, tmpl, tmplCnt);
6261 PKCS11_RV("C_GetAttributeValue", rv);
6262 if (rv != CKR_OK) {
6263 ret = WC_HW_E;
6264 goto exit;
6265 }
6266
6267 if (tmpl[0].ulValueLen <= 0) {
6268 ret = WC_HW_E;
6269 goto exit;
6270 }
6271
6272 certData = (byte *)XMALLOC(
6273 (int)tmpl[0].ulValueLen, info->cert.heap, DYNAMIC_TYPE_CERT);
6274 if (certData == NULL) {
6275 ret = MEMORY_E;
6276 goto exit;
6277 }
6278
6279 tmpl[0].pValue = certData;
6280 rv = session->func->C_GetAttributeValue(
6281 session->handle, certHandle, tmpl, tmplCnt);
6282 PKCS11_RV("C_GetAttributeValue", rv);
6283 if (rv != CKR_OK) {
6284 ret = WC_HW_E;
6285 goto exit;
6286 }
6287
6288 *info->cert.certDataOut = certData;
6289 *info->cert.certSz = (word32)tmpl[0].ulValueLen;
6290 if (info->cert.certFormatOut != NULL) {
6291 *info->cert.certFormatOut = CTC_FILETYPE_ASN1;
6292 }
6293 certData = NULL;
6294
6295exit:
6296 XFREE(certData, info->cert.heap, DYNAMIC_TYPE_CERT);
6297 return ret;
6298}
6299
6300#endif /* !NO_CERTS */
6301
6302/**
6303 * Perform a cryptographic operation using PKCS#11 device.
6304 *
6305 * @param [in] devId Device identifier.
6306 * @param [in] info Cryptographic operation data.
6307 * @param [in] ctx Context data for device - the token object.
6308 * @return WC_HW_E when a PKCS#11 library call fails.
6309 * @return NOT_COMPILED_IN when an unsupported operation is requested.
6310 * @return 0 on success.
6311 */
6312int wc_Pkcs11_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
6313{
6314 int ret = 0;
6315 Pkcs11Token* token = (Pkcs11Token*)ctx;
6316 Pkcs11Session session;
6317
6318#ifdef WOLFSSL_PKCS11_RW_TOKENS
6319 int readWrite = 1;
6320#else
6321 int readWrite = 0;
6322#endif
6323
6324 if (devId <= INVALID_DEVID || info == NULL || ctx == NULL)
6325 ret = BAD_FUNC_ARG;
6326
6327 /* Open and close a session around each operation as the operation may not
6328 * be compiled in.
6329 */
6330 if (ret == 0) {
6331 if (info->algo_type == WC_ALGO_TYPE_PK) {
6332#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_DILITHIUM) || \
6333 defined(WOLFSSL_HAVE_MLKEM)
6334 switch (info->pk.type) {
6335 #ifndef NO_RSA
6336 case WC_PK_TYPE_RSA:
6337 #ifdef WOLF_CRYPTO_CB_RSA_PAD
6338 case WC_PK_TYPE_RSA_PKCS:
6339 case WC_PK_TYPE_RSA_PSS:
6340 case WC_PK_TYPE_RSA_OAEP:
6341 #endif
6342 ret = Pkcs11OpenSession(token, &session, readWrite);
6343 if (ret == 0) {
6344 ret = Pkcs11Rsa(&session, info);
6345 Pkcs11CloseSession(token, &session);
6346 }
6347 break;
6348 #ifdef WOLFSSL_KEY_GEN
6349 case WC_PK_TYPE_RSA_KEYGEN:
6350 ret = Pkcs11OpenSession(token, &session, readWrite);
6351 if (ret == 0) {
6352 ret = Pkcs11RsaKeyGen(&session, info);
6353 Pkcs11CloseSession(token, &session);
6354 }
6355 break;
6356 #endif
6357 case WC_PK_TYPE_RSA_CHECK_PRIV_KEY:
6358 ret = Pkcs11OpenSession(token, &session, readWrite);
6359 if (ret == 0) {
6360 ret = Pkcs11RsaCheckPrivKey(&session, info);
6361 Pkcs11CloseSession(token, &session);
6362 }
6363 break;
6364 case WC_PK_TYPE_RSA_GET_SIZE:
6365 ret = Pkcs11OpenSession(token, &session, readWrite);
6366 if (ret == 0) {
6367 ret = Pkcs11RsaGetSize(&session, info);
6368 Pkcs11CloseSession(token, &session);
6369 }
6370 break;
6371 #endif
6372 #ifdef HAVE_ECC
6373 #ifndef NO_PKCS11_EC_KEYGEN
6374 case WC_PK_TYPE_EC_KEYGEN:
6375 ret = Pkcs11OpenSession(token, &session, readWrite);
6376 if (ret == 0) {
6377 ret = Pkcs11EcKeyGen(&session, info);
6378 Pkcs11CloseSession(token, &session);
6379 }
6380 break;
6381 #endif
6382 #ifndef NO_PKCS11_ECDH
6383 case WC_PK_TYPE_ECDH:
6384 ret = Pkcs11OpenSession(token, &session, readWrite);
6385 if (ret == 0) {
6386 ret = Pkcs11ECDH(&session, info);
6387 Pkcs11CloseSession(token, &session);
6388 }
6389 break;
6390 #endif
6391 case WC_PK_TYPE_ECDSA_SIGN:
6392 ret = Pkcs11OpenSession(token, &session, readWrite);
6393 if (ret == 0) {
6394 ret = Pkcs11ECDSA_Sign(&session, info);
6395 Pkcs11CloseSession(token, &session);
6396 }
6397 break;
6398 case WC_PK_TYPE_ECDSA_VERIFY:
6399 ret = Pkcs11OpenSession(token, &session, readWrite);
6400 if (ret == 0) {
6401 ret = Pkcs11ECDSA_Verify(&session, info);
6402 Pkcs11CloseSession(token, &session);
6403 }
6404 break;
6405 case WC_PK_TYPE_EC_CHECK_PRIV_KEY:
6406 ret = Pkcs11OpenSession(token, &session, readWrite);
6407 if (ret == 0) {
6408 ret = Pkcs11EccCheckPrivKey(&session, info);
6409 Pkcs11CloseSession(token, &session);
6410 }
6411 break;
6412 #endif
6413 #ifdef WOLFSSL_HAVE_MLKEM
6414 case WC_PK_TYPE_PQC_KEM_KEYGEN:
6415 ret = Pkcs11OpenSession(token, &session, readWrite);
6416 if (ret == 0) {
6417 ret = Pkcs11PqcKemKeyGen(&session, info);
6418 Pkcs11CloseSession(token, &session);
6419 }
6420 break;
6421 case WC_PK_TYPE_PQC_KEM_ENCAPS:
6422 ret = Pkcs11OpenSession(token, &session, readWrite);
6423 if (ret == 0) {
6424 ret = Pkcs11PqcKemEncapsulate(&session, info);
6425 Pkcs11CloseSession(token, &session);
6426 }
6427 break;
6428 case WC_PK_TYPE_PQC_KEM_DECAPS:
6429 ret = Pkcs11OpenSession(token, &session, readWrite);
6430 if (ret == 0) {
6431 ret = Pkcs11PqcKemDecapsulate(&session, info);
6432 Pkcs11CloseSession(token, &session);
6433 }
6434 break;
6435 #endif
6436 #if defined(HAVE_DILITHIUM)
6437 case WC_PK_TYPE_PQC_SIG_KEYGEN:
6438 ret = Pkcs11OpenSession(token, &session, readWrite);
6439 if (ret == 0) {
6440 ret = Pkcs11PqcSigKeyGen(&session, info);
6441 Pkcs11CloseSession(token, &session);
6442 }
6443 break;
6444 case WC_PK_TYPE_PQC_SIG_SIGN:
6445 ret = Pkcs11OpenSession(token, &session, readWrite);
6446 if (ret == 0) {
6447 ret = Pkcs11PqcSigSign(&session, info);
6448 Pkcs11CloseSession(token, &session);
6449 }
6450 break;
6451 case WC_PK_TYPE_PQC_SIG_VERIFY:
6452 ret = Pkcs11OpenSession(token, &session, readWrite);
6453 if (ret == 0) {
6454 ret = Pkcs11PqcSigVerify(&session, info);
6455 Pkcs11CloseSession(token, &session);
6456 }
6457 break;
6458 case WC_PK_TYPE_PQC_SIG_CHECK_PRIV_KEY:
6459 ret = Pkcs11OpenSession(token, &session, readWrite);
6460 if (ret == 0) {
6461 ret = Pkcs11PqcSigCheckPrivKey(&session, info);
6462 Pkcs11CloseSession(token, &session);
6463 }
6464 break;
6465 #endif
6466 default:
6467 ret = NOT_COMPILED_IN;
6468 break;
6469 }
6470#else
6471 ret = NOT_COMPILED_IN;
6472#endif /* !NO_RSA || HAVE_ECC || HAVE_DILITHIUM || WOLFSSL_HAVE_MLKEM */
6473 }
6474 else if (info->algo_type == WC_ALGO_TYPE_CIPHER) {
6475 #ifndef NO_AES
6476 switch (info->cipher.type) {
6477 #ifdef HAVE_AESGCM
6478 case WC_CIPHER_AES_GCM:
6479 if (info->cipher.enc) {
6480 ret = Pkcs11OpenSession(token, &session, readWrite);
6481 if (ret == 0) {
6482 ret = Pkcs11AesGcmEncrypt(&session, info);
6483 Pkcs11CloseSession(token, &session);
6484 }
6485 }
6486 else {
6487 ret = Pkcs11OpenSession(token, &session, readWrite);
6488 if (ret == 0) {
6489 ret = Pkcs11AesGcmDecrypt(&session, info);
6490 Pkcs11CloseSession(token, &session);
6491 }
6492 }
6493 break;
6494 #endif
6495 #ifdef HAVE_AES_CBC
6496 case WC_CIPHER_AES_CBC:
6497 if (info->cipher.enc) {
6498 ret = Pkcs11OpenSession(token, &session, readWrite);
6499 if (ret == 0) {
6500 ret = Pkcs11AesCbcEncrypt(&session, info);
6501 Pkcs11CloseSession(token, &session);
6502 }
6503 }
6504 else {
6505 ret = Pkcs11OpenSession(token, &session, readWrite);
6506 if (ret == 0) {
6507 ret = Pkcs11AesCbcDecrypt(&session, info);
6508 Pkcs11CloseSession(token, &session);
6509 }
6510 }
6511 break;
6512 #endif
6513 #ifdef WOLFSSL_AES_COUNTER
6514 case WC_CIPHER_AES_CTR:
6515 if (info->cipher.enc) {
6516 ret = Pkcs11OpenSession(token, &session, readWrite);
6517 if (ret == 0) {
6518 ret = Pkcs11AesCtrEncrypt(&session, info);
6519 Pkcs11CloseSession(token, &session);
6520 }
6521 }
6522 else {
6523 ret = Pkcs11OpenSession(token, &session, readWrite);
6524 if (ret == 0) {
6525 ret = Pkcs11AesCtrDecrypt(&session, info);
6526 Pkcs11CloseSession(token, &session);
6527 }
6528 }
6529 break;
6530 #endif
6531 default:
6532 ret = NOT_COMPILED_IN;
6533 break;
6534 }
6535 #else
6536 ret = NOT_COMPILED_IN;
6537 #endif
6538 }
6539 else if (info->algo_type == WC_ALGO_TYPE_HMAC) {
6540 #ifndef NO_HMAC
6541 Hmac* hmac = info->hmac.hmac;
6542
6543 /* Sign ops are session-scoped; cache the session across
6544 * multi-call HMAC dispatches. */
6545 if (hmac != NULL && hmac->devCtx != NULL) {
6546 session.func = token->func;
6547 session.slotId = token->slotId;
6548 session.version = token->version;
6549 session.handle =
6550 (CK_SESSION_HANDLE)(wc_ptr_t)hmac->devCtx;
6551 ret = Pkcs11Hmac(&session, info);
6552 if (ret != 0 ||
6553 hmac->innerHashKeyed
6554 != WC_HMAC_INNER_HASH_KEYED_DEV) {
6555 Pkcs11CloseSession(token, &session);
6556 hmac->devCtx = NULL;
6557 /* Don't leave stale DEV state past session close;
6558 * leave SW state (owned by software fallback). */
6559 if (hmac->innerHashKeyed
6560 == WC_HMAC_INNER_HASH_KEYED_DEV)
6561 hmac->innerHashKeyed = 0;
6562 }
6563 }
6564 else {
6565 ret = Pkcs11OpenSession(token, &session, readWrite);
6566 if (ret == 0) {
6567 ret = Pkcs11Hmac(&session, info);
6568 if (ret == 0 && hmac != NULL &&
6569 hmac->innerHashKeyed
6570 == WC_HMAC_INNER_HASH_KEYED_DEV) {
6571 hmac->devCtx =
6572 (void*)(wc_ptr_t)session.handle;
6573 }
6574 else {
6575 Pkcs11CloseSession(token, &session);
6576 if (hmac != NULL && hmac->innerHashKeyed
6577 == WC_HMAC_INNER_HASH_KEYED_DEV)
6578 hmac->innerHashKeyed = 0;
6579 }
6580 }
6581 }
6582 #else
6583 ret = NOT_COMPILED_IN;
6584 #endif
6585 }
6586 else if (info->algo_type == WC_ALGO_TYPE_RNG) {
6587 #if !defined(WC_NO_RNG) && !defined(HAVE_HASHDRBG)
6588 ret = Pkcs11OpenSession(token, &session, readWrite);
6589 if (ret == 0) {
6590 ret = Pkcs11RandomBlock(&session, info);
6591 Pkcs11CloseSession(token, &session);
6592 }
6593 #else
6594 ret = NOT_COMPILED_IN;
6595 #endif
6596 }
6597 else if (info->algo_type == WC_ALGO_TYPE_SEED) {
6598 #ifndef WC_NO_RNG
6599 ret = Pkcs11OpenSession(token, &session, readWrite);
6600 if (ret == 0) {
6601 ret = Pkcs11RandomSeed(&session, info);
6602 Pkcs11CloseSession(token, &session);
6603 }
6604 #else
6605 ret = NOT_COMPILED_IN;
6606 #endif
6607 }
6608 else if (info->algo_type == WC_ALGO_TYPE_CERT) {
6609 #ifndef NO_CERTS
6610 ret = Pkcs11OpenSession(token, &session, readWrite);
6611 if (ret == 0) {
6612 ret = Pkcs11GetCert(&session, info);
6613 Pkcs11CloseSession(token, &session);
6614 }
6615 #else
6616 ret = NOT_COMPILED_IN;
6617 #endif
6618 }
6619 else if (info->algo_type == WC_ALGO_TYPE_FREE) {
6620 #ifdef HAVE_ECC
6621 if (info->free.algo == WC_ALGO_TYPE_PK &&
6622 info->free.type == WC_PK_TYPE_EC_KEYGEN) {
6623 ret = Pkcs11OpenSession(token, &session, readWrite);
6624 if (ret == 0) {
6625 ret = Pkcs11EccDeletePrivKey(&session,
6626 (ecc_key*)info->free.obj);
6627 Pkcs11CloseSession(token, &session);
6628 }
6629 }
6630 else
6631 #endif
6632 #ifdef HAVE_DILITHIUM
6633 if (info->free.algo == WC_ALGO_TYPE_PK &&
6634 info->free.type == WC_PK_TYPE_PQC_SIG_KEYGEN &&
6635 info->free.subType == WC_PQC_SIG_TYPE_DILITHIUM) {
6636 ret = Pkcs11OpenSession(token, &session, readWrite);
6637 if (ret == 0) {
6638 ret = Pkcs11MldsaDeletePrivKey(&session,
6639 (MlDsaKey*)info->free.obj);
6640 Pkcs11CloseSession(token, &session);
6641 }
6642 }
6643 else
6644 #endif
6645 #ifdef WOLFSSL_HAVE_MLKEM
6646 if (info->free.algo == WC_ALGO_TYPE_PK &&
6647 info->free.type == WC_PK_TYPE_PQC_KEM_KEYGEN &&
6648 info->free.subType == WC_PQC_KEM_TYPE_KYBER) {
6649 ret = Pkcs11OpenSession(token, &session, readWrite);
6650 if (ret == 0) {
6651 ret = Pkcs11MlKemDeletePrivKey(&session,
6652 (MlKemKey*)info->free.obj);
6653 Pkcs11CloseSession(token, &session);
6654 }
6655 }
6656 else
6657 #endif
6658 {
6659 ret = NOT_COMPILED_IN;
6660 }
6661 }
6662 else {
6663 ret = NOT_COMPILED_IN;
6664 }
6665 }
6666
6667 return ret;
6668}
6669
6670#endif /* HAVE_PKCS11 */